<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Lizard-Spock</title><link href="http://lizard-spock.co.uk/" rel="alternate"></link><link href="http://lizard-spock.co.uk/feeds/all.atom.xml" rel="self"></link><id>http://lizard-spock.co.uk/</id><updated>2026-04-09T00:00:00+01:00</updated><entry><title>SoC Article 06: Interconnects and Bus Protocols - AXI, AHB, and APB</title><link href="http://lizard-spock.co.uk/soc-article-06-interconnects-and-bus-protocols.html" rel="alternate"></link><published>2026-04-09T00:00:00+01:00</published><updated>2026-04-09T00:00:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-04-09:/soc-article-06-interconnects-and-bus-protocols.html</id><summary type="html">&lt;p&gt;How SoC blocks communicate: the AMBA bus family from simple APB peripherals through pipelined AHB to the high-performance AXI4 with its five independent channels, valid/ready handshake, and crossbar interconnects.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Series: Introduction to SoC Design | Article 6 of 11&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Every block on a SoC -- CPUs, DMA engines, memory controllers, peripherals -- must communicate with every other block. The internal communication fabric that makes this possible is called the &lt;strong&gt;interconnect&lt;/strong&gt; or &lt;strong&gt;bus&lt;/strong&gt;. Choosing and designing the interconnect is one of the most consequential architectural decisions in SoC design: it determines bandwidth, latency, arbitration, and overall system throughput.&lt;/p&gt;
&lt;p&gt;This article introduces the major bus standards used in modern SoCs, with emphasis on &lt;strong&gt;ARM's AMBA (Advanced Microcontroller Bus Architecture)&lt;/strong&gt; family, which is the dominant standard in the industry.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Why a Standard Bus Matters&lt;/h2&gt;
&lt;p&gt;Without a standard interface, every IP block would need a custom interface to every other block -- an impractical explosion of design effort. A standard bus protocol defines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Signal names and widths&lt;/strong&gt; -- both sides know how to connect&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Handshake mechanism&lt;/strong&gt; -- how a master requests and a slave responds&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transaction semantics&lt;/strong&gt; -- what "read", "write", and "burst" mean&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timing requirements&lt;/strong&gt; -- setup times, hold times, latency bounds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;IP vendors design their blocks to be &lt;strong&gt;plug-compatible&lt;/strong&gt; with the standard, so a UART controller from one vendor and a DMA engine from another can both connect to the same ARM CoreLink interconnect without any custom glue logic.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The AMBA Family&lt;/h2&gt;
&lt;p&gt;ARM's &lt;strong&gt;AMBA&lt;/strong&gt; specification, first published in 1996 and evolving through multiple generations, defines a family of bus protocols at different performance tiers:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/06-amba-family-HQ.png"&gt;&lt;img alt="AMBA protocol family spectrum showing ACE/CHI, AXI4, AHB, and APB from high-performance to simple" src="http://lizard-spock.co.uk/06-amba-family-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The family spans from simple, low-power APB peripherals on the right through pipelined AHB, high-performance AXI4, all the way to cache-coherent ACE/CHI protocols used in multi-core processor clusters on the left.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;APB -- Advanced Peripheral Bus&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;APB&lt;/strong&gt; is the simplest AMBA protocol, designed for low-bandwidth, low-power peripheral registers. It is a &lt;strong&gt;synchronous, non-pipelined&lt;/strong&gt; bus with no burst mode -- every transfer takes a minimum of two clock cycles.&lt;/p&gt;
&lt;h3&gt;APB Signals&lt;/h3&gt;
&lt;p&gt;Key APB signals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PCLK&lt;/code&gt; -- Clock&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PRESETn&lt;/code&gt; -- Active-low reset&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PADDR&lt;/code&gt; -- Address (12-32 bit)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PSEL&lt;/code&gt; -- Select: asserted to indicate target peripheral&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PENABLE&lt;/code&gt; -- Enable: on second cycle of every transfer&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PWRITE&lt;/code&gt; -- Direction: high = write, low = read&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PWDATA&lt;/code&gt; -- Write data&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PRDATA&lt;/code&gt; -- Read data (from slave)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PREADY&lt;/code&gt; -- Slave extends transfer if not ready&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PSLVERR&lt;/code&gt; -- Slave error response&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;APB Write Timing&lt;/h3&gt;
&lt;p&gt;An APB write transaction takes place over two phases: &lt;strong&gt;Setup&lt;/strong&gt; and &lt;strong&gt;Access&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_09ef87f95dc8f74f62f977bf68033a1e.svg"&gt;&lt;/p&gt;
&lt;p&gt;In the &lt;strong&gt;Setup&lt;/strong&gt; phase, PSEL is asserted and the address and write data are presented. In the &lt;strong&gt;Access&lt;/strong&gt; phase, PENABLE goes high confirming the transfer. PREADY allows a slow peripheral to extend the access phase by holding it low.&lt;/p&gt;
&lt;p&gt;APB is ideal for: UART, SPI, I2C, GPIO, timer, and watchdog registers -- anything that does not require high data throughput.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;AHB -- Advanced High-performance Bus&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AHB&lt;/strong&gt; sits in the middle tier. It is a &lt;strong&gt;pipelined&lt;/strong&gt;, higher-bandwidth protocol supporting burst transfers. AHB separates the &lt;strong&gt;address phase&lt;/strong&gt; and &lt;strong&gt;data phase&lt;/strong&gt;, allowing the next address to be issued while the current data transfer is in progress.&lt;/p&gt;
&lt;h3&gt;Key AHB Signals&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HCLK&lt;/code&gt;, &lt;code&gt;HRESETn&lt;/code&gt; -- Clock and reset&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HADDR&lt;/code&gt; -- Address (32-bit)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HTRANS&lt;/code&gt; -- Transfer type: IDLE / BUSY / NONSEQ / SEQ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HWRITE&lt;/code&gt; -- Direction&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HSIZE&lt;/code&gt; -- Transfer size (8, 16, 32, 64... bit)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HBURST&lt;/code&gt; -- Burst type (SINGLE, INCR, WRAP4, INCR4...)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HWDATA&lt;/code&gt; / &lt;code&gt;HRDATA&lt;/code&gt; -- Write and read data&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HREADY&lt;/code&gt; -- Transfer complete / extend&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HRESP&lt;/code&gt; -- Response (OKAY / ERROR)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;AHB Pipelined Burst Read&lt;/h3&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_b51c9049a22ed7556c47b205afac8c07.svg"&gt;&lt;/p&gt;
&lt;p&gt;The key insight: while the data for A0 is being returned, the address A1 is already being presented. This pipeline overlap hides address-to-data latency and improves throughput.&lt;/p&gt;
&lt;h3&gt;AHB Arbitration&lt;/h3&gt;
&lt;p&gt;When multiple masters (CPU, DMA) contend for the AHB, an &lt;strong&gt;arbiter&lt;/strong&gt; decides who gets access using a bus grant / bus request protocol. Masters assert &lt;code&gt;HBUSREQx&lt;/code&gt; when they want the bus; the arbiter asserts &lt;code&gt;HGRANTx&lt;/code&gt; to indicate the winner. This round-robin or priority-based arbitration introduces a form of time-division multiplexing onto the shared bus.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;AXI -- Advanced eXtensible Interface&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;AXI4&lt;/strong&gt; is the highest-performance AMBA protocol, used to connect CPUs, memory controllers, DMA engines, GPUs, and other high-bandwidth masters and slaves. It is the backbone of most modern SoCs.&lt;/p&gt;
&lt;p&gt;AXI4's key innovation is &lt;strong&gt;independent channels&lt;/strong&gt;: read and write transactions are completely separate, and multiple transactions can be in flight simultaneously.&lt;/p&gt;
&lt;h3&gt;The Five AXI Channels&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/06-axi-channels-HQ.png"&gt;&lt;img alt="AXI4 five-channel architecture diagram showing master and slave blocks connected by AW, W, B, AR, and R channels with signal names" src="http://lizard-spock.co.uk/06-axi-channels-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The five channels are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AW (Write Address)&lt;/strong&gt; -- master sends the address and burst parameters for a write&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;W (Write Data)&lt;/strong&gt; -- master sends the data beats with byte strobes and WLAST flag&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;B (Write Response)&lt;/strong&gt; -- slave confirms the write completed (or reports an error)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AR (Read Address)&lt;/strong&gt; -- master sends the address and burst parameters for a read&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;R (Read Data)&lt;/strong&gt; -- slave returns data beats with RLAST flag&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Valid/Ready Handshake&lt;/h3&gt;
&lt;p&gt;Every AXI channel uses the same &lt;strong&gt;valid/ready handshake&lt;/strong&gt; protocol. The sender asserts &lt;code&gt;VALID&lt;/code&gt; when it has data to transfer. The receiver asserts &lt;code&gt;READY&lt;/code&gt; when it can accept data. The transfer completes on the rising clock edge when &lt;strong&gt;both&lt;/strong&gt; are high:&lt;/p&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_bdf5614eafeb6fb4c582b3cf98b83a3e.svg"&gt;&lt;/p&gt;
&lt;p&gt;This decoupled handshake is powerful: the master can issue addresses continuously; the slave can stall when its internal buffers are full, without requiring the master to back off.&lt;/p&gt;
&lt;h3&gt;AXI Burst Transfers&lt;/h3&gt;
&lt;p&gt;Rather than issuing many single transactions, AXI supports &lt;strong&gt;burst transfers&lt;/strong&gt; -- a single address phase followed by multiple data beats. This dramatically improves efficiency for sequential memory access.&lt;/p&gt;
&lt;p&gt;Key burst parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AWLEN / ARLEN&lt;/strong&gt; -- number of data beats (0=1 beat, 255=256 beats for AXI4)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWSIZE / ARSIZE&lt;/strong&gt; -- bytes per beat (1, 2, 4, 8, 16, 32, 64, 128)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWBURST / ARBURST&lt;/strong&gt; -- burst type:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FIXED&lt;/code&gt; -- same address repeated (useful for FIFOs)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;INCR&lt;/code&gt; -- address increments each beat (normal memory access)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WRAP&lt;/code&gt; -- like INCR but wraps at a boundary (useful for cache lines)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;AXI IDs and Out-of-Order Transactions&lt;/h3&gt;
&lt;p&gt;AXI assigns each transaction an &lt;strong&gt;ID&lt;/strong&gt; (&lt;code&gt;AWID&lt;/code&gt; / &lt;code&gt;ARID&lt;/code&gt;). A slave may respond to transactions &lt;strong&gt;out of order&lt;/strong&gt; as long as responses within the same ID are in order. This allows a memory controller to optimise DRAM access patterns rather than being forced to respond in the exact order of requests.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Interconnect: From Bus to Crossbar&lt;/h2&gt;
&lt;p&gt;A simple shared bus forces all masters to share a single data path -- only one master can use it at a time. This creates a bottleneck in systems with multiple high-bandwidth masters.&lt;/p&gt;
&lt;p&gt;The solution is an &lt;strong&gt;AXI crossbar&lt;/strong&gt; (also called a &lt;strong&gt;switch matrix&lt;/strong&gt;): it provides dedicated paths between every master-slave pair, allowing multiple simultaneous transfers as long as they target different slaves.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/06-bus-vs-crossbar-HQ.png"&gt;&lt;img alt="Shared bus versus AXI crossbar comparison showing bottleneck on left and simultaneous transfers on right" src="http://lizard-spock.co.uk/06-bus-vs-crossbar-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ARM's CoreLink NIC-400 and CoreLink CCI-550 are examples of AXI interconnect IP used in real SoCs. RISC-V SoCs commonly use TileLink or AXI crossbars built with open-source IP.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;QoS: Quality of Service in Interconnects&lt;/h2&gt;
&lt;p&gt;Not all traffic is equal. A display engine reading pixel data must deliver frames at a guaranteed rate, or the screen will tear. A background DMA transfer moving log data is not time-critical. AXI4 supports &lt;strong&gt;QoS signalling&lt;/strong&gt; (&lt;code&gt;ARQOS&lt;/code&gt; / &lt;code&gt;AWQOS&lt;/code&gt;) -- a 4-bit priority tag attached to every transaction.&lt;/p&gt;
&lt;p&gt;The interconnect uses these tags to arbitrate between competing masters, ensuring that time-sensitive traffic is served first without starvation of low-priority traffic.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;AXI4-Lite: The Simplified Register Interface&lt;/h2&gt;
&lt;p&gt;Full AXI4 has substantial complexity -- burst management, ID tracking, out-of-order responses. For accessing peripheral register banks (where individual 32-bit reads and writes are all that is needed), &lt;strong&gt;AXI4-Lite&lt;/strong&gt; offers a simplified subset:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No burst support (single transfers only)&lt;/li&gt;
&lt;li&gt;No transaction IDs&lt;/li&gt;
&lt;li&gt;No out-of-order support&lt;/li&gt;
&lt;li&gt;Simple 32-bit or 64-bit data width&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AXI4-Lite is extremely common for connecting peripheral IP blocks to the system bus, where its simplicity makes it easy to implement correctly.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;APB Bridge: Connecting the Bus Tiers&lt;/h2&gt;
&lt;p&gt;Because APB is simpler and lower power, slow peripherals are typically attached to an &lt;strong&gt;APB bus&lt;/strong&gt; rather than directly to the AXI/AHB backbone. An &lt;strong&gt;AXI-to-APB bridge&lt;/strong&gt; converts between the protocols:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/06-soc-bus-hierarchy-HQ.png"&gt;&lt;img alt="SoC bus hierarchy showing CPU core, L2 cache, AXI crossbar connecting to DRAM, GPU, DMA, and APB bridge leading to peripheral bus" src="http://lizard-spock.co.uk/06-soc-bus-hierarchy-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The bridge runs the APB at a lower, slower clock (e.g., 100 MHz) while the AXI backbone runs at 500 MHz or more, reducing dynamic power in the peripherals.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Network-on-Chip (NoC)&lt;/h2&gt;
&lt;p&gt;In the largest, most complex SoCs -- server processors, AI accelerators -- even an AXI crossbar becomes a bottleneck. The solution is a &lt;strong&gt;Network-on-Chip (NoC)&lt;/strong&gt;: a switched packet network embedded on the die, with routers at each node and links between them.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/06-noc-mesh-HQ.png"&gt;&lt;img alt="Network-on-Chip 4x4 mesh topology showing router nodes connected by bidirectional links with CPU, GPU, DRAM, and NPU blocks at the edges" src="http://lizard-spock.co.uk/06-noc-mesh-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;NoCs provide:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scalability&lt;/strong&gt; -- adding more processing tiles does not require redesigning the interconnect&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bandwidth&lt;/strong&gt; -- multiple simultaneous transfers across different links&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modularity&lt;/strong&gt; -- standard router IP can be assembled in different topologies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is an advanced topic covered in the advanced article series.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;SoC interconnects form the communication backbone that links every functional block. The AMBA protocol family provides a hierarchy of protocols: APB for simple peripherals, AHB for mid-range transfers, and AXI for high-performance connections. AXI's independent channel architecture and valid/ready handshake enable high-throughput, pipelined, out-of-order transfers. Crossbar interconnects replace shared buses to allow simultaneous transfers between different master-slave pairs. Understanding these protocols is essential for designing IP blocks that plug into an SoC and for debugging system-level performance issues.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Further Reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;AXI4 Protocol Deep Dive&lt;/em&gt; -- Burst types, transaction IDs, out-of-order response ordering&lt;/li&gt;
&lt;li&gt;&lt;em&gt;DMA Controller Architecture&lt;/em&gt; -- How a DMA engine uses AXI to move data autonomously&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Network-on-Chip Design (Advanced)&lt;/em&gt; -- Topology, routing algorithms, virtual channels&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Previous: &lt;a href="http://lizard-spock.co.uk/soc-article-05-memory-architecture.html"&gt;Article 05 -- Memory Architecture&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content><category term="Engineering"></category><category term="SoC"></category><category term="Hardware"></category><category term="Computer Architecture"></category><category term="Electronics"></category><category term="Embedded Systems"></category><category term="ARM"></category><category term="AMBA"></category><category term="AXI"></category><category term="AHB"></category><category term="APB"></category><category term="Bus Protocols"></category></entry><entry><title>SoC Article 05: Memory Architecture - Caches, DRAM, and On-chip Storage</title><link href="http://lizard-spock.co.uk/soc-article-05-memory-architecture.html" rel="alternate"></link><published>2026-04-04T00:00:00+01:00</published><updated>2026-04-04T00:00:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-04-04:/soc-article-05-memory-architecture.html</id><summary type="html">&lt;p&gt;How modern SoCs bridge the speed gap between fast CPU cores and slow external DRAM through cache hierarchies, SRAM, and DRAM controllers. Covers cache organisation, MESI coherency, the MMU, and on-chip storage.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Series: Introduction to SoC Design | Article 5 of 11&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Of all the factors that determine a SoC's real-world performance, &lt;strong&gt;memory&lt;/strong&gt; is often the most important and the most overlooked by beginners. A modern CPU core can theoretically execute billions of operations per second, but most of that potential is wasted if data cannot be delivered fast enough.&lt;/p&gt;
&lt;p&gt;The art of SoC memory architecture is bridging the massive speed gap between the processor (which wants data in nanoseconds) and the external DRAM (which takes tens of nanoseconds to respond) in the most energy-efficient way possible.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Memory Speed Gap&lt;/h2&gt;
&lt;p&gt;The problem starts with a fundamental mismatch in technology:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-memory-technology-comparison-HQ.png"&gt;&lt;img alt="Memory technology comparison table showing capacity, latency, bandwidth and power from CPU registers through DRAM to flash storage" src="http://lizard-spock.co.uk/05-memory-technology-comparison-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice the gap: a CPU register delivers data in under a nanosecond, while external DRAM takes 50-70 ns - roughly 100x slower. Without a caching strategy, the CPU would spend most of its time waiting for memory.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Memory Hierarchy&lt;/h2&gt;
&lt;p&gt;The solution is a &lt;strong&gt;hierarchy&lt;/strong&gt; of storage technologies, organised by speed, cost, and distance from the processor:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-memory-hierarchy-HQ.png"&gt;&lt;img alt="Memory hierarchy pyramid showing registers, L1 cache, L2 cache, L3 cache, DRAM and flash storage with latency and capacity annotations" src="http://lizard-spock.co.uk/05-memory-hierarchy-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The hierarchy works because of &lt;strong&gt;locality&lt;/strong&gt; - the observation that most programs access the same data repeatedly over a short period (&lt;em&gt;temporal locality&lt;/em&gt;) and access data at adjacent addresses in sequence (&lt;em&gt;spatial locality&lt;/em&gt;). Caches exploit both properties.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;How Caches Work&lt;/h2&gt;
&lt;p&gt;A cache is a small, fast SRAM that stores copies of recently-used data from slower memory. When the CPU reads an address, it first checks the cache:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cache hit&lt;/strong&gt; - the data is in the cache; it is returned immediately (low latency)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache miss&lt;/strong&gt; - the data is not in the cache; it must be fetched from a slower level&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_b8d5e322e8edb747d88c0ef3d9f3d343.svg"&gt;&lt;/p&gt;
&lt;h3&gt;Cache Organisation&lt;/h3&gt;
&lt;p&gt;A cache is organised into &lt;strong&gt;lines&lt;/strong&gt; (also called blocks) - the minimum unit of transfer between memory levels. A typical cache line is &lt;strong&gt;64 bytes&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Three important cache parameters:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Capacity&lt;/strong&gt; - total amount of data the cache can hold.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Associativity&lt;/strong&gt; - how many possible cache locations a given memory address can map to. A &lt;em&gt;direct-mapped&lt;/em&gt; cache is simplest: each address maps to exactly one line. A &lt;em&gt;fully-associative&lt;/em&gt; cache can hold any address in any line. A &lt;em&gt;4-way set-associative&lt;/em&gt; cache is a compromise: each address maps to a set of 4 lines.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-cache-organisation-HQ.png"&gt;&lt;img alt="Cache associativity comparison showing direct-mapped cache versus 4-way set-associative cache organisation" src="http://lizard-spock.co.uk/05-cache-organisation-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Write policy&lt;/strong&gt; - what happens when the CPU writes to a cached address:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Write-through&lt;/em&gt;: simultaneously update both cache and memory (simple, but uses memory bandwidth)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Write-back&lt;/em&gt;: update only the cache, mark the line "dirty", and write to memory only when the line is evicted (more efficient)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Static RAM (SRAM): The Cache Technology&lt;/h2&gt;
&lt;p&gt;Caches are built from &lt;strong&gt;SRAM&lt;/strong&gt; (Static RAM). Each bit is stored in a &lt;strong&gt;six-transistor cell&lt;/strong&gt; (6T SRAM) - two cross-coupled inverters and two access transistors.&lt;/p&gt;
&lt;p&gt;SRAM retains data as long as power is applied (it is &lt;em&gt;volatile&lt;/em&gt;). It is fast (sub-nanosecond access) but uses significant area - roughly 100-150 F per bit (where F is the minimum feature size). This is why caches are small relative to DRAM.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;DRAM: The Main Memory Technology&lt;/h2&gt;
&lt;p&gt;External DRAM uses a &lt;strong&gt;one-transistor, one-capacitor&lt;/strong&gt; (1T1C) cell. The charge on a capacitor represents the bit value.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-sram-dram-cells-HQ.png"&gt;&lt;img alt="SRAM 6T cell versus DRAM 1T1C cell comparison showing transistor and capacitor layout with wordline and bitline connections" src="http://lizard-spock.co.uk/05-sram-dram-cells-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The 1T1C cell is much smaller than a 6T SRAM cell, enabling much higher density - today's DRAM stores tens of gigabits per die. However, the capacitor leaks charge over time, so each cell must be &lt;strong&gt;refreshed&lt;/strong&gt; (read and rewritten) thousands of times per second. This refresh activity consumes power and introduces brief periods where the memory cannot be accessed.&lt;/p&gt;
&lt;h3&gt;DRAM Organisation&lt;/h3&gt;
&lt;p&gt;DRAM is organised into &lt;strong&gt;banks&lt;/strong&gt;, &lt;strong&gt;rows&lt;/strong&gt;, and &lt;strong&gt;columns&lt;/strong&gt;. Accessing data requires:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Activate&lt;/strong&gt; (open) a row - copies the row into a row buffer (sense amplifiers)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Read/Write&lt;/strong&gt; column - access the desired column from the row buffer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Precharge&lt;/strong&gt; - close the row (prepare for the next row activation)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_0301a316868482bdbb1947198a5e921c.svg"&gt;&lt;/p&gt;
&lt;p&gt;Key timing parameters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;tRCD&lt;/strong&gt; - Row-to-Column Delay (time after ACT before a column can be accessed)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CL&lt;/strong&gt; - CAS Latency (time after READ command before data appears)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tRP&lt;/strong&gt; - Row Precharge time (time to precharge before next ACT)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tRAS&lt;/strong&gt; - Row Active time (minimum time row must be open)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;On-chip SRAM (Tightly Coupled Memory)&lt;/h2&gt;
&lt;p&gt;In addition to caches, many SoCs include blocks of &lt;strong&gt;Tightly Coupled Memory (TCM)&lt;/strong&gt; - SRAM directly connected to the processor core, accessed through a dedicated bus rather than through the cache hierarchy. TCM provides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Guaranteed latency&lt;/strong&gt; - always one cycle, no possibility of a cache miss&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deterministic behaviour&lt;/strong&gt; - essential for real-time systems&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DMA-accessible storage&lt;/strong&gt; - used for buffers shared with peripherals&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is particularly common in ARM Cortex-M microcontrollers, where code critical for interrupt service routines may be placed in ITCM (Instruction TCM) to ensure it always executes at maximum speed.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The DRAM Controller&lt;/h2&gt;
&lt;p&gt;Between the SoC's system bus and the DRAM package sits the &lt;strong&gt;DRAM controller&lt;/strong&gt; - a complex piece of hardware that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Translates read/write requests from the bus into DRAM-specific command sequences (ACT, RD, WR, PRE, REF)&lt;/li&gt;
&lt;li&gt;Schedules requests to maximise row-buffer hit rate and memory bandwidth&lt;/li&gt;
&lt;li&gt;Issues periodic &lt;strong&gt;refresh&lt;/strong&gt; commands to prevent data loss&lt;/li&gt;
&lt;li&gt;Manages multiple banks and ranks for parallel access&lt;/li&gt;
&lt;li&gt;Implements &lt;strong&gt;QoS (Quality of Service)&lt;/strong&gt; to ensure latency-sensitive initiators (e.g., display engines) get priority&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-dram-controller-HQ.png"&gt;&lt;img alt="DRAM controller architecture block diagram showing AXI slave interface, command scheduler, refresh engine, and PHY interface connecting to LPDDR5 DRAM" src="http://lizard-spock.co.uk/05-dram-controller-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Non-Volatile Storage&lt;/h2&gt;
&lt;p&gt;Beyond volatile DRAM, SoCs interface with non-volatile storage where data must persist after power-off:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;eMMC (embedded MultiMediaCard)&lt;/strong&gt; - flash memory in a BGA package, soldered to the board. Used in mid-range phones and single-board computers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UFS (Universal Flash Storage)&lt;/strong&gt; - faster, lower-latency serial protocol with command queuing. Used in high-end smartphones.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOR Flash&lt;/strong&gt; - byte-addressable, execute-in-place (XIP) capable. Often used for bootloaders on embedded systems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NAND Flash&lt;/strong&gt; - high density, page/block-based access. Requires a flash translation layer (FTL) to manage wear levelling.&lt;/p&gt;
&lt;p&gt;The SoC connects to these through dedicated controller IP blocks: eMMC controller on AHB/APB, UFS controller on AXI, QSPI controller on APB for NOR flash, and NAND controller on AHB.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Memory Mapping: The Software View&lt;/h2&gt;
&lt;p&gt;From software's perspective, all memory - SRAM, DRAM, memory-mapped registers, flash - appears as a flat &lt;strong&gt;address space&lt;/strong&gt;. The processor simply reads and writes to 32-bit or 64-bit addresses; the hardware decides which memory or peripheral handles each range.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-address-map-HQ.png"&gt;&lt;img alt="32-bit SoC address space layout showing peripheral registers, private CPU peripherals, external DRAM, on-chip SRAM, and flash ROM regions" src="http://lizard-spock.co.uk/05-address-map-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;memory map&lt;/strong&gt; is one of the first things a firmware developer consults when writing code for a new SoC. It is typically documented in the SoC's &lt;strong&gt;Technical Reference Manual (TRM)&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Cache Coherency: The Multi-Core Problem&lt;/h2&gt;
&lt;p&gt;When multiple CPU cores share a memory system, a challenge arises: &lt;strong&gt;what happens if two cores have different cached copies of the same address?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is the &lt;strong&gt;cache coherency problem&lt;/strong&gt;. If Core 0 writes to address A and Core 1 has a stale cached copy of A, Core 1 will read incorrect data.&lt;/p&gt;
&lt;p&gt;Hardware cache coherency protocols solve this. The most common is &lt;strong&gt;MESI&lt;/strong&gt; (Modified, Exclusive, Shared, Invalid):&lt;/p&gt;
&lt;p&gt;&lt;img alt="FSM diagram" src="http://lizard-spock.co.uk/images/fsm/fsm_a25d2b06f62d26e489ba5d1cdc5ad725.svg"&gt;&lt;/p&gt;
&lt;p&gt;Each cache line has a state tag (M, E, S, or I) that determines how it may be used. A bus snooping mechanism or directory protocol ensures all cores agree on the current state.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Memory Management Unit (MMU)&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;MMU&lt;/strong&gt; translates &lt;strong&gt;virtual addresses&lt;/strong&gt; (used by software) into &lt;strong&gt;physical addresses&lt;/strong&gt; (used by hardware). This translation enables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Process isolation&lt;/strong&gt; - each process has its own virtual address space&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory protection&lt;/strong&gt; - preventing processes from accessing each other's memory&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Virtual memory&lt;/strong&gt; - presenting more memory than is physically available&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Translation is performed via a &lt;strong&gt;page table&lt;/strong&gt; hierarchy stored in DRAM. To avoid the latency of a full table walk for every access, the CPU caches recent translations in the &lt;strong&gt;TLB (Translation Lookaside Buffer)&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-mmu-translation-HQ.png"&gt;&lt;img alt="MMU virtual to physical address translation diagram showing VPN fields, TLB lookup path, page table walk on miss, and physical frame number output" src="http://lizard-spock.co.uk/05-mmu-translation-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The ARM SMMU (System Memory Management Unit) extends this concept to non-CPU masters (DMA engines, GPU), ensuring that peripheral DMA transfers are also constrained to authorised memory regions.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;The SoC memory architecture is a carefully designed hierarchy that bridges the speed gap between fast-but-small on-chip SRAM and slow-but-large external DRAM. Caches exploit locality to keep frequently-used data close to the processor. DRAM controllers manage the complex command sequencing needed to drive modern LPDDR memory. The MMU virtualises the address space to enable protection and isolation. Together, these components are often the primary determinant of real-world SoC performance.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Intermediate Articles This Topic Connects To&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Cache Coherency Protocols&lt;/em&gt; - MESI, MOESI, directory-based coherency in detail&lt;/li&gt;
&lt;li&gt;&lt;em&gt;DRAM Subsystem Timing (Advanced)&lt;/em&gt; - tRCD, tCL, CWL, refresh, power states, LPDDR5&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Memory-Mapped I/O and Linux Device Drivers&lt;/em&gt; - How software talks to hardware registers&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Previous: &lt;a href="http://lizard-spock.co.uk/soc-article-04-processor-cores.html"&gt;SoC Article 04 - Processor Cores&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content><category term="Engineering"></category><category term="SoC"></category><category term="Hardware"></category><category term="Computer Architecture"></category><category term="Electronics"></category><category term="Embedded Systems"></category><category term="Memory"></category><category term="DRAM"></category><category term="SRAM"></category><category term="Cache"></category><category term="ARM"></category></entry><entry><title>SoC Article 04: Processor Cores - CPU, DSP, GPU and Hardware Accelerators</title><link href="http://lizard-spock.co.uk/soc-article-04-processor-cores.html" rel="alternate"></link><published>2026-03-27T00:00:00+00:00</published><updated>2026-03-27T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-27:/soc-article-04-processor-cores.html</id><summary type="html">&lt;p&gt;A survey of the main processor types in modern SoCs: CPUs for general-purpose code, DSPs for signal processing, GPUs for parallel workloads, and hardware accelerators for AI, video, and cryptography.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Series: Introduction to SoC Design | Article 4 of 11&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;The processor is the heart of any SoC. But "processor" is a broad term that covers a remarkably diverse family of designs, each optimised for a different class of computation. A modern smartphone SoC may contain a dozen or more distinct processing engines - general-purpose CPUs, a graphics processor, a signal processing cluster, a neural network accelerator, and several smaller microcontrollers managing power and connectivity.&lt;/p&gt;
&lt;p&gt;This article surveys the main classes of processor used in SoCs, explains what makes each suited to its domain, and introduces the key architectural concepts every SoC designer needs to understand.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Processing Landscape&lt;/h2&gt;
&lt;p&gt;Different computational tasks have different shapes. Some are sequential and unpredictable (parsing a web page). Others are massively parallel and regular (multiplying a matrix). Still others require precisely timed, low-latency responses (handling a radio frame). These different "shapes" of computation call for different processor architectures.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-task-taxonomy-HQ.png"&gt;&lt;img alt="Computational Task Taxonomy showing the spectrum from sequential irregular control-heavy tasks handled by CPUs through DSPs and GPUs to parallel regular data-heavy tasks handled by neural engines" src="http://lizard-spock.co.uk/04-task-taxonomy-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;General-Purpose CPU Cores&lt;/h2&gt;
&lt;h3&gt;Architecture Fundamentals&lt;/h3&gt;
&lt;p&gt;A CPU core executes a sequential stream of instructions: fetch, decode, execute, access memory, write back. The efficiency of this loop determines performance.&lt;/p&gt;
&lt;p&gt;Modern CPU cores in SoCs are overwhelmingly &lt;strong&gt;RISC&lt;/strong&gt; (Reduced Instruction Set Computer) designs. The dominant ISA is &lt;strong&gt;ARM&lt;/strong&gt;, with &lt;strong&gt;RISC-V&lt;/strong&gt; growing rapidly in open-source and embedded applications.&lt;/p&gt;
&lt;p&gt;The key subsystems inside a CPU core are:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-cpu-core-internals-HQ.png"&gt;&lt;img alt="CPU core internal architecture showing the instruction fetch, decode and dispatch, execute units (ALU, FPU, multiplier), register file, load/store unit, and branch predictor" src="http://lizard-spock.co.uk/04-cpu-core-internals-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Pipeline Stages&lt;/h3&gt;
&lt;p&gt;A five-stage pipeline is the canonical teaching model:&lt;/p&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_9dbcb49039a3e254bc98df89b49e18d6.svg"&gt;&lt;/p&gt;
&lt;h3&gt;The Big-Little Concept&lt;/h3&gt;
&lt;p&gt;For power-sensitive SoCs (smartphones, wearables), ARM developed the &lt;strong&gt;big.LITTLE&lt;/strong&gt; architecture, which pairs high-performance "big" cores with energy-efficient "little" cores on the same die:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-big-little-cluster-HQ.png"&gt;&lt;img alt="ARM big.LITTLE DynamIQ cluster configuration showing the performance cluster with Cortex-A78 cores and the efficiency cluster with Cortex-A55 cores, sharing an L3 cache and system interconnect" src="http://lizard-spock.co.uk/04-big-little-cluster-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The OS scheduler assigns heavy tasks (video decoding, gaming) to the big cores, and lightweight tasks (receiving notifications, idle polling) to the little cores. This can reduce energy consumption by 10x or more compared to running everything on the big cores.&lt;/p&gt;
&lt;h3&gt;Key Performance Metrics&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IPC (Instructions Per Cycle)&lt;/strong&gt; - how much useful work a core does per clock cycle&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clock frequency&lt;/strong&gt; - cycles per second (GHz)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance = IPC x Frequency&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPI (Cycles Per Instruction)&lt;/strong&gt; = 1/IPC; lower is better&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Modern high-performance cores achieve IPC values of 4-8 by executing multiple instructions simultaneously (superscalar) and speculatively executing future instructions.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Soft vs Hard CPU Cores&lt;/h2&gt;
&lt;p&gt;An important distinction for SoC designers is between &lt;strong&gt;soft&lt;/strong&gt; and &lt;strong&gt;hard&lt;/strong&gt; processor cores:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hard cores&lt;/strong&gt; are transistor-level implementations physically embedded in the silicon - you cannot change them. They are highly optimised for performance and area. The ARM Cortex-A cores in a smartphone SoC are hard cores licensed from ARM.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Soft cores&lt;/strong&gt; are RTL descriptions that you synthesise yourself onto the target process or onto FPGA fabric. They are portable and configurable but less efficient. Examples include:
- &lt;strong&gt;ARM Cortex-M0&lt;/strong&gt; (available as soft core for ASIC/FPGA)
- &lt;strong&gt;RISC-V&lt;/strong&gt; cores (PicoRV32, VexRiscv, BOOM, Rocket)
- &lt;strong&gt;MicroBlaze&lt;/strong&gt; (Xilinx/AMD FPGA soft core)
- &lt;strong&gt;Nios II&lt;/strong&gt; (Altera/Intel FPGA soft core)&lt;/p&gt;
&lt;p&gt;SoC designers on FPGAs (see Article 09) almost always use soft cores since they are placing logic into reconfigurable fabric.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Digital Signal Processors (DSPs)&lt;/h2&gt;
&lt;p&gt;A &lt;strong&gt;DSP&lt;/strong&gt; is a processor specialised for signal processing algorithms. Its architecture is tuned for two operations that appear constantly in such algorithms: &lt;strong&gt;multiply-accumulate (MAC)&lt;/strong&gt; and &lt;strong&gt;data movement&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;The MAC Operation&lt;/h3&gt;
&lt;p&gt;The core of almost all digital signal processing is the &lt;strong&gt;dot product&lt;/strong&gt;: multiply pairs of numbers and sum the results. This appears in:
- &lt;strong&gt;FIR filters&lt;/strong&gt;: y[n] = h[0]x[n] + h[1]x[n-1] + ... + h[N]x[n-N]
- &lt;strong&gt;FFT&lt;/strong&gt; (Fast Fourier Transform)
- &lt;strong&gt;Convolution&lt;/strong&gt; in image processing and neural networks&lt;/p&gt;
&lt;p&gt;A MAC operation computes: &lt;strong&gt;Accumulator += A x B&lt;/strong&gt; in a single cycle.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-dsp-mac-unit-HQ.png"&gt;&lt;img alt="DSP MAC Unit showing the single-cycle multiply-accumulate pipeline: A and B input registers feeding a multiplier, then an adder, then a 40-bit accumulator with feedback" src="http://lizard-spock.co.uk/04-dsp-mac-unit-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;DSP Architecture Features&lt;/h3&gt;
&lt;p&gt;DSPs include hardware features that a general-purpose CPU lacks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hardware loopers&lt;/strong&gt; - zero-overhead loops without branch penalty&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dual-MAC units&lt;/strong&gt; - two multiply-accumulate operations per cycle&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Circular addressing&lt;/strong&gt; - automatic modulo addressing for filter delay lines&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bit-reverse addressing&lt;/strong&gt; - essential for FFT butterfly operations&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SIMD instructions&lt;/strong&gt; - Single Instruction Multiple Data, processing several samples simultaneously&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DSPs are commonly found in SoCs handling audio codecs, cellular modem baseband processing, image signal processing (ISPs), and radar systems.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Graphics Processing Units (GPUs)&lt;/h2&gt;
&lt;p&gt;A GPU is architected around &lt;strong&gt;massive parallelism&lt;/strong&gt;. Instead of a few powerful, complex cores, a GPU contains hundreds or thousands of simple &lt;strong&gt;shader cores&lt;/strong&gt; that execute in lockstep on large datasets.&lt;/p&gt;
&lt;p&gt;The programming model is based on the observation that rendering a 3D scene, applying a filter to an image, or training a neural network involves applying the &lt;strong&gt;same operation&lt;/strong&gt; to &lt;strong&gt;many different data points&lt;/strong&gt; independently.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-gpu-vs-cpu-HQ.png"&gt;&lt;img alt="GPU vs CPU core organisation: the CPU has 4 large complex cores with large caches, while the GPU has 2048 simple shader cores - showing how CPUs are optimised for serial branchy tasks while GPUs excel at regular parallel tasks" src="http://lizard-spock.co.uk/04-gpu-vs-cpu-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In mobile SoCs, GPUs are used for:
- 3D gaming and UI rendering
- Video encode/decode
- Computer vision and augmented reality
- Machine learning inference (alongside or instead of dedicated NPUs)&lt;/p&gt;
&lt;p&gt;Common mobile GPU families include &lt;strong&gt;ARM Mali&lt;/strong&gt;, &lt;strong&gt;Qualcomm Adreno&lt;/strong&gt;, and &lt;strong&gt;Apple's own GPU&lt;/strong&gt; (unnamed, integrated in A-series chips).&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Hardware Accelerators&lt;/h2&gt;
&lt;p&gt;As compute-intensive AI workloads have become dominant, SoC vendors have added &lt;strong&gt;dedicated hardware accelerators&lt;/strong&gt; - fixed-function silicon blocks that execute one type of computation extremely efficiently.&lt;/p&gt;
&lt;h3&gt;Neural Processing Unit (NPU / Neural Engine)&lt;/h3&gt;
&lt;p&gt;An NPU accelerates neural network inference - the process of running a trained model on new input data. The core operation is matrix-vector multiplication (essentially a large MAC array).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-systolic-array-HQ.png"&gt;&lt;img alt="Systolic array architecture used in NPU designs: a grid of Processing Elements (PEs) where weights flow downward and activations flow rightward, each PE computing one MAC per clock cycle, with partial sums accumulating downward" src="http://lizard-spock.co.uk/04-systolic-array-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In a systolic array, data flows through the processing elements rhythmically (like blood through a heart - hence "systolic"). Weights are pre-loaded; activations and partial sums flow through, with each PE performing one MAC per cycle. This achieves very high utilisation of the multiplication hardware.&lt;/p&gt;
&lt;h3&gt;Video Codec Engine&lt;/h3&gt;
&lt;p&gt;Encoding and decoding H.264/H.265/AV1 video in software is extremely CPU-intensive. A dedicated hardware codec can process 4K video at 30+ frames per second while drawing milliwatts, compared to watts for a software implementation. Modern SoCs include fixed-function codec blocks that implement the specific algorithms of each video standard.&lt;/p&gt;
&lt;h3&gt;Cryptographic Accelerator&lt;/h3&gt;
&lt;p&gt;AES encryption, SHA hashing, RSA/ECC public-key operations, and True Random Number Generation (TRNG) are all candidates for hardware acceleration. Performing AES-128 in hardware can be 50-100x more energy-efficient than software.&lt;/p&gt;
&lt;h3&gt;Image Signal Processor (ISP)&lt;/h3&gt;
&lt;p&gt;The camera pipeline - demosaicing, noise reduction, white balance, tone mapping, HDR merging - runs in a dedicated ISP. This is a DSP-like block hardwired to the specific algorithms of computational photography.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Processor Cluster: Putting It Together&lt;/h2&gt;
&lt;p&gt;A high-end mobile SoC might contain the following processing elements:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-soc-processor-subsystem-HQ.png"&gt;&lt;img alt="Modern mobile SoC processor subsystem showing the CPU cluster (prime, big and little cores), GPU, DSP, NPU, ISP and modem as distinct blocks on the die" src="http://lizard-spock.co.uk/04-soc-processor-subsystem-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Processor State Machine: A Simplified View&lt;/h2&gt;
&lt;p&gt;Every processor can be modelled as a state machine. Here is a simplified view of a CPU's states in a typical embedded SoC context:&lt;/p&gt;
&lt;p&gt;&lt;img alt="FSM diagram" src="http://lizard-spock.co.uk/images/fsm/fsm_d3b3a56743e4c3f1c5d4b7c3e7a5609b.svg"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Choosing the Right Processor for Your SoC&lt;/h2&gt;
&lt;p&gt;The processor choice depends critically on the application:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Application&lt;/th&gt;
&lt;th&gt;Primary Processor&lt;/th&gt;
&lt;th&gt;Rationale&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;IoT sensor node&lt;/td&gt;
&lt;td&gt;Cortex-M0+ (soft/hard)&lt;/td&gt;
&lt;td&gt;Ultra-low power, simple code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RTOS control system&lt;/td&gt;
&lt;td&gt;Cortex-M4 / M7&lt;/td&gt;
&lt;td&gt;Real-time response, DSP extensions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automotive ADAS&lt;/td&gt;
&lt;td&gt;Cortex-A + DSP cluster&lt;/td&gt;
&lt;td&gt;Linux needed + CV workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smartphone&lt;/td&gt;
&lt;td&gt;big.LITTLE Cortex-A&lt;/td&gt;
&lt;td&gt;Variable load, battery priority&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge AI inference&lt;/td&gt;
&lt;td&gt;ARM + NPU&lt;/td&gt;
&lt;td&gt;Dominates workload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5G baseband&lt;/td&gt;
&lt;td&gt;Multi-DSP cluster&lt;/td&gt;
&lt;td&gt;Fixed-point signal processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FPGA prototyping&lt;/td&gt;
&lt;td&gt;RISC-V soft core&lt;/td&gt;
&lt;td&gt;Open, configurable, no licence fee&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;SoC processing subsystems are not monolithic: they combine CPUs for general-purpose code, DSPs for signal processing, GPUs for parallel/graphics workloads, and hardware accelerators for specific high-demand functions like AI inference, video coding, and cryptography. Each architecture is optimised for its domain. The RISC philosophy underpins most modern SoC CPUs, while the systolic array and SIMD principles dominate accelerators. Understanding the trade-offs between these options is one of the core competencies of SoC architecture.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Intermediate Articles This Topic Connects To&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Pipeline Design and Hazards&lt;/em&gt; - Data, structural, and control hazards; forwarding networks&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Cache Coherency Protocols&lt;/em&gt; - How multiple CPU cores agree on the state of shared memory&lt;/li&gt;
&lt;li&gt;&lt;em&gt;AI Accelerator Architecture (Advanced)&lt;/em&gt; - Dataflow, weight stationarity, memory bandwidth&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Previous: &lt;a href="http://lizard-spock.co.uk/soc-article-03-design-stack.html"&gt;Article 03 - The SoC Design Stack&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content><category term="Engineering"></category><category term="SoC"></category><category term="Hardware"></category><category term="Computer Architecture"></category><category term="Electronics"></category><category term="Embedded Systems"></category><category term="CPU"></category><category term="DSP"></category><category term="GPU"></category><category term="NPU"></category><category term="RISC-V"></category><category term="ARM"></category></entry><entry><title>SoC Article 03: The SoC Design Stack - From Transistors to Software</title><link href="http://lizard-spock.co.uk/soc-article-03-design-stack.html" rel="alternate"></link><published>2026-03-21T00:00:00+00:00</published><updated>2026-03-21T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-21:/soc-article-03-design-stack.html</id><summary type="html">&lt;p&gt;How SoC design is organised as a stack of abstraction layers, from transistors at the bottom to application software at the top, and the languages and tools used at each level.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Series: Introduction to SoC Design | Article 3 of 11&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the previous article we looked at what a SoC &lt;em&gt;is&lt;/em&gt;. Now we need to understand how it is &lt;em&gt;described, designed, and built&lt;/em&gt;. The answer is not a single language or a single tool - it is a &lt;strong&gt;stack of abstraction layers&lt;/strong&gt;, each hiding complexity from the layer above it.&lt;/p&gt;
&lt;p&gt;This concept of layered abstraction is one of the most powerful ideas in all of engineering, and it is particularly rich in SoC design, where the stack spans from quantum mechanics at the silicon level all the way up to the C programs and operating systems that run on the finished chip.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Abstraction Hierarchy&lt;/h2&gt;
&lt;p&gt;Think of SoC design as a series of nested boxes. Each layer can be understood and reasoned about independently, so long as it respects the contracts defined by the layers around it.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/01-abstraction-stack-HQ.png"&gt;&lt;img alt="The SoC abstraction stack from physical layout at the bottom to application software at the top, with ISA highlighted as the hardware/software boundary" src="http://lizard-spock.co.uk/01-abstraction-stack-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Engineers who work in SoC design typically specialise in one or two adjacent layers. A physical design engineer thinks in terms of polygons and resistance; a firmware engineer thinks in terms of memory-mapped registers and interrupt vectors. The stack is the shared vocabulary that lets them collaborate.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Gajski-Kuhn Y-Chart&lt;/h2&gt;
&lt;p&gt;A classic way to visualise the design space is the &lt;strong&gt;Y-chart&lt;/strong&gt;, introduced by Daniel Gajski and Robert Kuhn in 1983. It organises design descriptions along three axes (or "domains"), each of which can be examined at multiple levels of abstraction:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/03-y-chart-HQ.png"&gt;&lt;img alt="The Gajski-Kuhn Y-Chart showing three design domains - behavioural, structural, and physical - with abstraction levels along each axis" src="http://lizard-spock.co.uk/03-y-chart-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The key insight of the Y-chart is that every design activity maps a description from one domain into another at the same level of abstraction. &lt;strong&gt;Synthesis&lt;/strong&gt; maps a behavioural RTL description into a structural gate-level netlist. &lt;strong&gt;Place-and-route&lt;/strong&gt; maps a structural netlist into a physical layout.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Layer 1: Devices and Transistors&lt;/h2&gt;
&lt;p&gt;At the very bottom of the stack sits the &lt;strong&gt;transistor&lt;/strong&gt; - the fundamental switch of digital electronics. Modern SoCs are built using &lt;strong&gt;CMOS&lt;/strong&gt; (Complementary Metal-Oxide-Semiconductor) technology, which uses two complementary transistor types: &lt;strong&gt;nMOS&lt;/strong&gt; (conducts when gate is high) and &lt;strong&gt;pMOS&lt;/strong&gt; (conducts when gate is low).&lt;/p&gt;
&lt;p&gt;A single CMOS inverter (NOT gate) uses one nMOS and one pMOS transistor. This pairing is elegant: it ensures that when the output is stable, no DC path exists from power to ground, so the circuit draws near-zero static power.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/02-cmos-inverter-HQ.png"&gt;&lt;img alt="CMOS inverter schematic showing pMOS and nMOS transistors in complementary configuration, with IN and OUT signals and Vdd/GND rails" src="http://lizard-spock.co.uk/02-cmos-inverter-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The process of manufacturing transistors is described by the &lt;strong&gt;technology node&lt;/strong&gt; - a number like 5 nm, 7 nm, or 28 nm. This roughly corresponds to the minimum feature size achievable. Smaller nodes pack more transistors into the same area but require more expensive processes.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Layer 2: Logic Gates&lt;/h2&gt;
&lt;p&gt;Transistors are combined to form &lt;strong&gt;logic gates&lt;/strong&gt; - circuits that implement boolean operations. Gates are the building blocks of all digital logic.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/06-logic-gates-HQ.png"&gt;&lt;img alt="Six common logic gates: AND, OR, NOT, NAND, NOR, and XOR, drawn as hand-sketched IEEE symbols with Boolean equations. NAND and NOR highlighted in teal as universal gates." src="http://lizard-spock.co.uk/06-logic-gates-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In practice, &lt;strong&gt;NAND and NOR&lt;/strong&gt; gates are the most fundamental - any other gate can be built from them (they are "universal"). Standard cell libraries contain dozens to hundreds of gate variants with different drive strengths, optimised for speed or area.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Layer 3: Register Transfer Level (RTL)&lt;/h2&gt;
&lt;p&gt;Above the gate level sits the &lt;strong&gt;Register Transfer Level (RTL)&lt;/strong&gt;, the primary working abstraction for SoC designers. RTL describes a circuit in terms of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Registers&lt;/strong&gt; - collections of flip-flops that hold state&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Combinational logic&lt;/strong&gt; - the boolean functions that compute new values from current state and inputs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data transfers&lt;/strong&gt; - moving values between registers, through functional units (ALUs, multiplexers)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RTL is described using a &lt;strong&gt;Hardware Description Language (HDL)&lt;/strong&gt; - either &lt;strong&gt;Verilog/SystemVerilog&lt;/strong&gt; or &lt;strong&gt;VHDL&lt;/strong&gt;. Here is a simple 4-bit counter in both:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// SystemVerilog -- 4-bit synchronous counter with enable&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;#(&lt;/span&gt;&lt;span class="k"&gt;parameter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;WIDTH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;input&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;logic&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;input&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;logic&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="n"&gt;rst_n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;// active-low reset&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;input&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;logic&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;logic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;WIDTH&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mh"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;always_ff&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@(&lt;/span&gt;&lt;span class="k"&gt;posedge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;negedge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rst_n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;rst_n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;&amp;#39;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;1&lt;/span&gt;&lt;span class="mb"&gt;&amp;#39;b1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;endmodule&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;-- VHDL -- equivalent 4-bit synchronous counter&lt;/span&gt;
&lt;span class="k"&gt;library&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;ieee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;ieee.std_logic_1164.&lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;ieee.numeric_std.&lt;/span&gt;&lt;span class="k"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;entity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;counter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;generic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WIDTH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;integer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;std_logic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;rst_n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;std_logic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kt"&gt;std_logic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;std_logic_vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WIDTH&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;downto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;architecture&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;rtl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;counter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;signal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WIDTH&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;downto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rst_n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rst_n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;others&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;elsif&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rising_edge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;process&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;std_logic_vector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cnt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;architecture&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The behaviour of this counter over time is shown in the timing diagram below:&lt;/p&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_eb26cdc141712ed315fcbdc995cf70b7.svg"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Layer 4: The Instruction Set Architecture (ISA)&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;ISA&lt;/strong&gt; is the contract between hardware and software. It defines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;programmer-visible registers&lt;/strong&gt; (e.g., x0-x31 in RISC-V)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;instruction set&lt;/strong&gt; - the opcodes and their semantics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory addressing modes&lt;/strong&gt; - how addresses are formed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Exception and interrupt behaviour&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privilege levels&lt;/strong&gt; - user, supervisor, machine mode&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The ISA is intentionally a stable interface. A program compiled for RISC-V will run correctly on any RISC-V implementation, regardless of how many pipeline stages it has, how large its caches are, or whether it executes instructions out of order. The microarchitecture can change entirely as long as it correctly implements the ISA.&lt;/p&gt;
&lt;p&gt;There are two broad architectural philosophies:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;CISC&lt;/th&gt;
&lt;th&gt;RISC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Philosophy&lt;/td&gt;
&lt;td&gt;Complex instructions doing more work&lt;/td&gt;
&lt;td&gt;Simple, fast instructions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Instruction size&lt;/td&gt;
&lt;td&gt;Variable (1-15 bytes on x86)&lt;/td&gt;
&lt;td&gt;Fixed (4 bytes in RISC-V, ARM)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Register count&lt;/td&gt;
&lt;td&gt;Historically few&lt;/td&gt;
&lt;td&gt;Many (16-32+)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Examples&lt;/td&gt;
&lt;td&gt;x86 / x86-64&lt;/td&gt;
&lt;td&gt;ARM, RISC-V, MIPS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common in SoCs&lt;/td&gt;
&lt;td&gt;Desktop/server&lt;/td&gt;
&lt;td&gt;Mobile, embedded, IoT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Most modern SoCs use RISC-based ISAs (particularly ARM) because their simpler, more regular instruction encodings are easier to implement efficiently in hardware.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Layer 5: Microarchitecture&lt;/h2&gt;
&lt;p&gt;The microarchitecture is the &lt;em&gt;implementation&lt;/em&gt; of the ISA - the actual pipeline, caches, branch predictors, and functional units that execute instructions. It is typically described at RTL level.&lt;/p&gt;
&lt;p&gt;A simple five-stage pipeline illustrates the key idea:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-pipeline-HQ.png"&gt;&lt;img alt="5-stage pipeline grid showing three instructions executing in parallel across clock cycles, with Execute stages in teal and Write Back in orange" src="http://lizard-spock.co.uk/04-pipeline-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Multiple instructions are in-flight simultaneously, improving throughput. The art of microarchitecture is managing the interactions between them - particularly &lt;strong&gt;hazards&lt;/strong&gt; where one instruction depends on the result of a previous one that hasn't finished yet.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;IP Cores: Pre-Built Design Blocks&lt;/h2&gt;
&lt;p&gt;One of the most important concepts in SoC design is the &lt;strong&gt;Intellectual Property (IP) core&lt;/strong&gt; - a pre-designed, pre-verified block that can be reused in a new design. IP reuse is what makes SoC development tractable: instead of designing every block from scratch, engineers assemble proven components.&lt;/p&gt;
&lt;p&gt;IP cores come in three forms:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-ip-core-types-HQ.png"&gt;&lt;img alt="IP core classification spectrum from Soft IP (RTL source, portable) through Firm IP (netlist) to Hard IP (GDSII layout, fully optimised), with opposing arrows showing the portability vs optimisation trade-off" src="http://lizard-spock.co.uk/05-ip-core-types-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ARM's Cortex-M series are delivered as &lt;strong&gt;soft IP&lt;/strong&gt; - you receive the RTL description and synthesise it yourself. ARM's Cortex-A series in advanced processes often comes as &lt;strong&gt;hard IP&lt;/strong&gt; - the physical layout is fixed for a particular foundry process.&lt;/p&gt;
&lt;p&gt;Common IP blocks found in SoCs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CPU cores&lt;/strong&gt; - ARM Cortex-A/M/R, RISC-V cores&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU IP&lt;/strong&gt; - ARM Mali, Imagination PowerVR&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;USB PHY and controller&lt;/strong&gt; - Synopsys DesignWare&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PCIe controller&lt;/strong&gt; - Synopsys, Cadence&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory controllers&lt;/strong&gt; - DDR PHY from specialised vendors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ethernet MAC/PHY&lt;/strong&gt; - various vendors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cryptography engines&lt;/strong&gt; - AES, SHA, PKA implementations&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;The Design Flow Overview&lt;/h2&gt;
&lt;p&gt;Taking an SoC from concept to fabricated silicon follows a structured sequence of steps, each with its own tools and verification checkpoints:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/07-design-flow-HQ.png"&gt;&lt;img alt="SoC design flow from Specification through Architecture, RTL Design, Synthesis, Place and Route, Sign-off to Tape-out, with RTL Simulation feeding into Synthesis and a feedback arrow showing iteration back to RTL Design." src="http://lizard-spock.co.uk/07-design-flow-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Article 09 in this series covers the design flow in detail. For now, the important point is that design is not a linear process - it is iterative. Problems discovered during synthesis or place-and-route often require revisiting the RTL, and sometimes the architecture.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Modelling Languages: Choosing the Right Abstraction&lt;/h2&gt;
&lt;p&gt;Different languages are suited to different levels of the design stack:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Primary Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SystemC&lt;/td&gt;
&lt;td&gt;Architecture / TLM&lt;/td&gt;
&lt;td&gt;System-level modelling, HW/SW co-design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SystemVerilog&lt;/td&gt;
&lt;td&gt;RTL / Gate&lt;/td&gt;
&lt;td&gt;Hardware design, simulation, formal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VHDL&lt;/td&gt;
&lt;td&gt;RTL / Gate&lt;/td&gt;
&lt;td&gt;Hardware design (historically in Europe/defence)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verilog&lt;/td&gt;
&lt;td&gt;RTL / Gate&lt;/td&gt;
&lt;td&gt;Older HDL, still widely used&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C/C++&lt;/td&gt;
&lt;td&gt;Algorithm / Firmware&lt;/td&gt;
&lt;td&gt;SW design, hardware test benches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;Verification / Tools&lt;/td&gt;
&lt;td&gt;Test automation, tooling, cocotb test benches&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;SoC design is organised as a stack of abstraction layers, from quantum-mechanical effects in transistors at the bottom to application software at the top. Each layer hides complexity from the layer above it, enabling teams of specialists to collaborate without needing to understand every detail. The key levels are: device/transistor, logic gate, RTL, ISA, microarchitecture, and software. IP reuse is the mechanism that makes modern SoC development tractable. The design flow moves from specification through RTL, synthesis, physical design, and sign-off before tape-out.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Intermediate Articles This Topic Connects To&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;RTL Synthesis and Timing Closure&lt;/em&gt; - How EDA tools map RTL to gates and meet timing&lt;/li&gt;
&lt;li&gt;&lt;em&gt;SoC Verification with UVM&lt;/em&gt; - Proving the RTL is correct before committing to silicon&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Formal Verification Methods&lt;/em&gt; - Using mathematics to prove hardware correctness&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Previous: &lt;a href="http://lizard-spock.co.uk/soc-article-02-anatomy-and-motivation.html"&gt;Article 02 - What is a System on Chip?&lt;/a&gt;&lt;/em&gt;
&lt;em&gt;Next: Article 04 - Processor Cores: CPU, DSP, GPU and Hardware Accelerators&lt;/em&gt;&lt;/p&gt;</content><category term="Engineering"></category><category term="SoC"></category><category term="Hardware"></category><category term="Computer Architecture"></category><category term="Electronics"></category><category term="Embedded Systems"></category><category term="RTL"></category><category term="Verilog"></category><category term="VHDL"></category></entry><entry><title>SoC Article 02: What is a System on Chip? - Anatomy and Motivation</title><link href="http://lizard-spock.co.uk/soc-article-02-anatomy-and-motivation.html" rel="alternate"></link><published>2026-03-15T00:00:00+00:00</published><updated>2026-03-15T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-15:/soc-article-02-anatomy-and-motivation.html</id><summary type="html">&lt;p&gt;What blocks make up a System on Chip, how do they relate, and why does integration deliver such dramatic benefits over traditional board-level designs?&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Series: Introduction to SoC Design | Article 2 of 11&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the previous article we traced the seventy-year journey from room-sized mainframes to silicon-level integration, arriving at the &lt;strong&gt;System on Chip&lt;/strong&gt; - a complete computer system fabricated on a single piece of silicon. Now it is time to look inside one: what blocks does it contain, how do they relate, and why does integration deliver such dramatic benefits?&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Board-to-Silicon Transition&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image" src="http://lizard-spock.co.uk/Gemini_Generated_Image_yhyy7hyhyy7hyhyy-901w.png"&gt;&lt;/p&gt;
&lt;p&gt;In traditional electronics, a "system" was a &lt;strong&gt;circuit board&lt;/strong&gt; populated with many separate chips, each performing one role: a CPU chip, a separate memory controller, a graphics processor, communication peripheral chips, and a power management IC, all connected by copper traces on the PCB.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;System on Chip&lt;/strong&gt; collapses most or all of those components onto a &lt;strong&gt;single piece of silicon&lt;/strong&gt;. The processor, memory interfaces, graphics engine, USB controller, cryptographic accelerator, radio interface, and many other functional blocks are fabricated together in one integrated circuit.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/01-board-vs-soc-HQ.png"&gt;&lt;img alt="Side-by-side comparison: a traditional board-level system with many discrete chips connected by slow PCB traces versus a System on Chip with the same blocks integrated onto a single die connected by fast on-chip wires" src="http://lizard-spock.co.uk/01-board-vs-soc-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The term "SoC" emerged formally in the mid-1990s when transistor densities crossed roughly 100 million per chip - the threshold at which integrating a complete system became both technically practical and economically compelling. Today, modern SoCs routinely contain &lt;strong&gt;tens of billions of transistors&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Why Does Integration Matter?&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image" src="http://lizard-spock.co.uk/Gemini_Generated_Image_yhyy7hyhyy7hyhyy-2-900w.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/02-integration-benefits-HQ.png"&gt;&lt;img alt="Four benefits of integration shown as a 2x2 grid: Speed (on-chip nanoseconds vs PCB 60-100ns), Power Efficiency (low-voltage on-chip signalling vs high-drive off-chip), Area and Cost (fewer chips, smaller PCB), and Reliability (fewer solder joints)" src="http://lizard-spock.co.uk/02-integration-benefits-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Putting everything on one die is not just about convenience. It delivers fundamental advantages across every dimension that matters.&lt;/p&gt;
&lt;h3&gt;Speed&lt;/h3&gt;
&lt;p&gt;On-chip wires are nanometres wide and micrometres long. Signals cross them in fractions of a nanosecond. Signals crossing a PCB encounter far greater inductance and capacitance, longer paths, and the need for high-drive output buffers - all of which introduce significant delay. An on-chip memory access takes 1-5 ns; an off-chip access might take 60-100 ns for the same data.&lt;/p&gt;
&lt;h3&gt;Power Efficiency&lt;/h3&gt;
&lt;p&gt;Driving a signal off-chip requires pumping it up to a voltage level and current that the PCB can handle reliably - this is fundamentally wasteful. On-chip signalling operates at much lower voltages (as little as 0.4 V for the fastest paths) and does not need the drive strength of an off-chip interface. Every chip-to-chip boundary eliminated saves power directly.&lt;/p&gt;
&lt;h3&gt;Area and Cost&lt;/h3&gt;
&lt;p&gt;Fewer chips means a smaller PCB, which means a smaller, lighter product. At the volumes of the smartphone market (billions of units per year), even a 5 mm² reduction in PCB area translates into substantial savings. One complex SoC may cost less to manufacture and assemble than the collection of chips it replaces.&lt;/p&gt;
&lt;h3&gt;Reliability&lt;/h3&gt;
&lt;p&gt;Solder joints and connectors are the most common failure points in electronic assemblies. Fewer chips mean fewer joints, longer mean time between failures, and better suitability for vibration-prone environments (automotive, industrial, aerospace).&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;The Anatomy of a Generic SoC&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image" src="http://lizard-spock.co.uk/Gemini_Generated_Image_yhyy7hyhyy7hyhyy-3-900w.png"&gt;&lt;/p&gt;
&lt;p&gt;While no two SoCs are identical, most share a recognisable set of functional blocks:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/03-soc-anatomy-HQ.png"&gt;&lt;img alt="SoC anatomy block diagram showing the processing subsystem (CPU cores, GPU/DSP, hardware accelerators) connected via the AXI high-speed interconnect to on-chip SRAM, DDR memory controller, DMA engine, and peripheral bridge, with clock/reset, power management, and security engine as spanning blocks" src="http://lizard-spock.co.uk/03-soc-anatomy-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each block has its own dedicated article later in the series. Here is a brief map of what each does:&lt;/p&gt;
&lt;h3&gt;Processing Subsystem&lt;/h3&gt;
&lt;p&gt;The "brains" of the SoC. One or more &lt;strong&gt;CPU cores&lt;/strong&gt; execute general-purpose software. Alongside them are specialised processors - &lt;strong&gt;DSPs&lt;/strong&gt; for signal processing, &lt;strong&gt;GPUs&lt;/strong&gt; for graphics and parallel computation, and dedicated &lt;strong&gt;hardware accelerators&lt;/strong&gt; for AI inference, video coding, and cryptography. (Article 04)&lt;/p&gt;
&lt;h3&gt;Memory Subsystem&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;On-chip SRAM&lt;/strong&gt; provides fast, low-latency storage close to the processors. &lt;strong&gt;DRAM controllers&lt;/strong&gt; connect to external memory for the large working set. A cache hierarchy sits between the two. (Article 05)&lt;/p&gt;
&lt;h3&gt;System Interconnect&lt;/h3&gt;
&lt;p&gt;The internal "highway" connecting all blocks. High-bandwidth connections use &lt;strong&gt;AXI&lt;/strong&gt;; lower-bandwidth peripheral connections use &lt;strong&gt;AHB&lt;/strong&gt; or &lt;strong&gt;APB&lt;/strong&gt;. (Article 06)&lt;/p&gt;
&lt;h3&gt;DMA Engine&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Direct Memory Access&lt;/strong&gt; allows peripherals to move blocks of data to/from memory without involving the CPU - essential for high-throughput peripherals like USB, Ethernet, and cameras. (Article 08)&lt;/p&gt;
&lt;h3&gt;Peripherals&lt;/h3&gt;
&lt;p&gt;The interfaces that connect the chip to the external world: UART, SPI, I2C, GPIO, USB, Ethernet, and many others. (Article 08)&lt;/p&gt;
&lt;h3&gt;Clock and Reset&lt;/h3&gt;
&lt;p&gt;A &lt;strong&gt;PLL&lt;/strong&gt; generates the precise, stable frequencies each subsystem requires. The reset subsystem places all flip-flops in a known initial state after power-up. (Article 07)&lt;/p&gt;
&lt;h3&gt;Power Management&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;PMU&lt;/strong&gt; selectively powers down idle blocks, runs the CPU at lower voltage when full speed is not needed, and manages battery charging in portable devices. (Article 07)&lt;/p&gt;
&lt;h3&gt;Security Engine&lt;/h3&gt;
&lt;p&gt;Dedicated hardware for encryption, secure boot, key storage, and access control. ARM &lt;strong&gt;TrustZone&lt;/strong&gt; partitions the chip into secure and non-secure domains. (Article 11)&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;SoC Examples in the Real World&lt;/h2&gt;
&lt;p&gt;&lt;img alt="image" src="http://lizard-spock.co.uk/Gemini_Generated_Image_yhyy7hyhyy7hyhyy-4-900w.png"&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SoC&lt;/th&gt;
&lt;th&gt;Application&lt;/th&gt;
&lt;th&gt;Notable Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Apple A18 (iPhone 16)&lt;/td&gt;
&lt;td&gt;Smartphone&lt;/td&gt;
&lt;td&gt;6-core CPU, 6-core GPU, Neural Engine, 16 B transistors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Qualcomm Snapdragon 8 Gen 3&lt;/td&gt;
&lt;td&gt;Android phone&lt;/td&gt;
&lt;td&gt;big.LITTLE cluster, Hexagon DSP, integrated 5G modem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVIDIA Orin&lt;/td&gt;
&lt;td&gt;Autonomous vehicles&lt;/td&gt;
&lt;td&gt;12-core ARM, Ampere GPU, deep learning accelerator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raspberry Pi RP2040&lt;/td&gt;
&lt;td&gt;Hobbyist MCU&lt;/td&gt;
&lt;td&gt;Dual Cortex-M0+, PIO state machines, 264 KB SRAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nordic nRF5340&lt;/td&gt;
&lt;td&gt;IoT / BLE&lt;/td&gt;
&lt;td&gt;Dual ARM cores, Bluetooth 5.3 radio integrated on-chip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Xilinx Zynq UltraScale+&lt;/td&gt;
&lt;td&gt;FPGA SoC&lt;/td&gt;
&lt;td&gt;ARM quad-core + FPGA fabric + GPU + DSP slices&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The range here is important. An SoC is not just a smartphone chip. The same integration principle applies from a $0.50 microcontroller running a light switch to a $200 chip managing an autonomous vehicle.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-soc-spectrum-HQ.png"&gt;&lt;img alt="SoC application spectrum arranged left to right by complexity and cost: tiny IoT/MCU chip at far left through embedded controller, smartphone SoC, automotive SoC, to HPC/data-centre SoC at far right, with transistor count and power budget indicated for each" src="http://lizard-spock.co.uk/04-soc-spectrum-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt="image" src="http://lizard-spock.co.uk/Gemini_Generated_Image_yhyy7hyhyy7hyhyy-5-900w.png"&gt;&lt;/p&gt;
&lt;h2&gt;The Complexity Challenge&lt;/h2&gt;
&lt;p&gt;Integration delivers benefits, but it raises design complexity to a different level entirely. A modern SoC is designed by teams of hundreds of engineers over one to three years. The design must:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Meet timing requirements across all operating conditions (voltage, temperature, process variation)&lt;/li&gt;
&lt;li&gt;Be verified correct before manufacture - a bug in silicon costs millions to fix&lt;/li&gt;
&lt;li&gt;Balance the competing bandwidth demands of many simultaneous data flows&lt;/li&gt;
&lt;li&gt;Boot reliably from cold power-off and recover gracefully from faults&lt;/li&gt;
&lt;li&gt;Meet strict power and thermal budgets across wildly different workloads&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Managing this complexity is the central discipline of SoC design, and it is the reason for the structured methodologies this series explores.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;HW/SW Duality&lt;/h2&gt;
&lt;p&gt;A crucial insight for SoC design is that &lt;strong&gt;hardware and software are both valid ways to implement any function&lt;/strong&gt;. The choice between them is a trade-off, and it shapes the entire architecture:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Hardware&lt;/th&gt;
&lt;th&gt;Software&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Very high (parallel, GHz)&lt;/td&gt;
&lt;td&gt;Lower (sequential execution)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexibility&lt;/td&gt;
&lt;td&gt;Fixed after tape-out&lt;/td&gt;
&lt;td&gt;Updateable/patchable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Energy efficiency&lt;/td&gt;
&lt;td&gt;Excellent for specific tasks&lt;/td&gt;
&lt;td&gt;Lower for the same task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Development time&lt;/td&gt;
&lt;td&gt;Long, expensive&lt;/td&gt;
&lt;td&gt;Shorter, cheaper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugging difficulty&lt;/td&gt;
&lt;td&gt;Very high post-silicon&lt;/td&gt;
&lt;td&gt;Much easier&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Most SoCs exploit this duality deliberately - placing performance-critical, stable functions in hardware, and flexible or complex control logic in software. Understanding where to draw that line is one of the core skills in SoC architecture and is the subject of Article 11.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-hw-sw-tradeoff-HQ.png"&gt;&lt;img alt="Two-column comparison of hardware vs software implementation: left column shows hardware block icons with labels - parallel execution, fixed function, high efficiency; right column shows software/CPU icons - sequential execution, flexible, patchable; a central dividing line labelled &amp;quot;The HW/SW Boundary&amp;quot; with a spectrum arrow beneath" src="http://lizard-spock.co.uk/05-hw-sw-tradeoff-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;A System on Chip integrates what was once a board full of discrete chips - processors, memory controllers, communication interfaces, and more - onto a single piece of silicon. Integration delivers speed (proximity), power efficiency (no off-chip driving), smaller area (fewer chips), and higher reliability (fewer solder joints). Every SoC shares a recognisable anatomy: processing subsystem, memory subsystem, system interconnect, DMA engine, peripherals, clock/reset, power management, and security. The following articles examine each of these in turn.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Intermediate Articles This Topic Connects To&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;AXI4 Protocol Deep Dive&lt;/em&gt; - The interconnect in detail&lt;/li&gt;
&lt;li&gt;&lt;em&gt;SoC Power Management Techniques&lt;/em&gt; - DVFS, power gating, retention&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Heterogeneous SoC Partitioning (Advanced)&lt;/em&gt; - Formal HW/SW co-exploration&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Previous: &lt;a href="http://lizard-spock.co.uk/soc-article-01-from-room-to-silicon.html"&gt;Article 01 - From Room to Silicon&lt;/a&gt;&lt;/em&gt;
&lt;em&gt;Next: &lt;a href="http://lizard-spock.co.uk/soc-article-03-design-stack.html"&gt;Article 03 - The SoC Design Stack: From Transistors to Software&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content><category term="Engineering"></category><category term="SoC"></category><category term="Hardware"></category><category term="Computer Architecture"></category><category term="Electronics"></category><category term="Embedded Systems"></category></entry><entry><title>Managing Dotfiles with Stow and Git</title><link href="http://lizard-spock.co.uk/dotfiles-setup-stow-git.html" rel="alternate"></link><published>2026-03-07T00:00:00+00:00</published><updated>2026-03-07T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-07:/dotfiles-setup-stow-git.html</id><summary type="html">&lt;p&gt;How to centralise and manage Unix dotfiles in a Git repository, using source directives and GNU Stow to link them into place.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Configuration files (dotfiles) for tools like Zsh, Vim, tmux, and Git tend to accumulate across machines over time. Without a strategy, they diverge: one machine has tuned aliases, another has an old vimrc, and a new machine starts from scratch. Keeping dotfiles in a single Git repository solves this. Clone once, link into place, and every machine stays consistent.&lt;/p&gt;
&lt;p&gt;My dotfiles are on GitHub at &lt;a href="https://github.com/morganp/dotfiles"&gt;morganp/dotfiles&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Why Centralise Dotfiles&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A single source of truth for all shell and tool configuration.&lt;/li&gt;
&lt;li&gt;Version history lets you see what changed and roll back if something breaks.&lt;/li&gt;
&lt;li&gt;Setting up a new machine reduces to cloning the repo and running a handful of commands.&lt;/li&gt;
&lt;li&gt;Sharing config across macOS and Linux with minimal platform-specific branching.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Cloning the Repo&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/morganp/dotfiles.git&lt;span class="w"&gt; &lt;/span&gt;~/dotfiles
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Linking Config Files&lt;/h2&gt;
&lt;p&gt;There are two approaches depending on the tool.&lt;/p&gt;
&lt;h3&gt;Sourcing (Zsh and Vim)&lt;/h3&gt;
&lt;p&gt;Some tools are simplest to handle by having the home directory config file source the dotfiles version directly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Zsh&lt;/strong&gt; -- add to &lt;code&gt;~/.zshrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/dotfiles/config/shell/dot-zshrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Vim&lt;/strong&gt; -- add to &lt;code&gt;~/.vimrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;so&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/dotfiles/&lt;/span&gt;config&lt;span class="sr"&gt;/vim/&lt;/span&gt;dot&lt;span class="p"&gt;-&lt;/span&gt;vimrc_clean
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;GNU Stow (Everything Else)&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.gnu.org/software/stow/"&gt;GNU Stow&lt;/a&gt; manages symlinks. It takes a package directory and creates symlinks in a target directory that mirror the structure. With the &lt;code&gt;--dotfiles&lt;/code&gt; flag, files named &lt;code&gt;dot-foo&lt;/code&gt; are linked as &lt;code&gt;.foo&lt;/code&gt; in the target, keeping the repo free of files that would be hidden by default.&lt;/p&gt;
&lt;p&gt;Install Stow and other packages via Homebrew:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;brew&lt;span class="w"&gt; &lt;/span&gt;bundle&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;--file&lt;span class="o"&gt;=&lt;/span&gt;~/dotfiles/config/brew
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then link the remaining configs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/dotfiles/config
stow&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;--dotfiles&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;~/
stow&lt;span class="w"&gt; &lt;/span&gt;input&lt;span class="w"&gt; &lt;/span&gt;--dotfiles&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;~/
stow&lt;span class="w"&gt; &lt;/span&gt;screen&lt;span class="w"&gt; &lt;/span&gt;--dotfiles&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;~/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A &lt;code&gt;run_stow&lt;/code&gt; script in the repo automates this.&lt;/p&gt;
&lt;h2&gt;Tmux&lt;/h2&gt;
&lt;p&gt;Tmux looks for its config via the &lt;code&gt;$XDG_CONFIG_HOME&lt;/code&gt; variable, set in &lt;code&gt;config/shell/dot-profile&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$XDG_CONFIG_HOME/tmux/tmux.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For the tmux plugin manager, clone TPM separately:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/tmux-plugins/tpm&lt;span class="w"&gt; &lt;/span&gt;~/.tmux/plugins/tpm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Shell Features&lt;/h2&gt;
&lt;p&gt;The dotfiles configure the following shell aliases across Bash and Zsh:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Alias&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File list with colour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ll&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Long list with human-readable sizes and colour&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;la&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;As &lt;code&gt;ll&lt;/code&gt; but includes hidden files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Directory tree view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;..&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Up one directory&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Other configurations included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Screen:&lt;/strong&gt; Virtual tabs across the bottom in standard colours.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Inputrc:&lt;/strong&gt; Case-insensitive tab completion, including hidden files.&lt;/li&gt;
&lt;/ul&gt;</content><category term="Unix &amp; Tools"></category><category term="dotfiles"></category><category term="shell"></category><category term="stow"></category><category term="zsh"></category><category term="tmux"></category><category term="vim"></category></entry><entry><title>Emotional Intelligence in the Workplace</title><link href="http://lizard-spock.co.uk/emotional-intelligence-in-the-workplace.html" rel="alternate"></link><published>2026-03-07T00:00:00+00:00</published><updated>2026-03-07T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-07:/emotional-intelligence-in-the-workplace.html</id><summary type="html">&lt;p&gt;A summary of high and low emotional intelligence (EQ) traits in leaders and employees, and how EQ shapes team dynamics and decision making.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Emotional intelligence (EQ) is the ability to recognise, understand, and manage your own emotions, as well as the emotions of those around you. In professional settings, EQ significantly influences how individuals lead, collaborate, and navigate difficult situations.&lt;/p&gt;
&lt;h2&gt;High EQ: What It Looks Like&lt;/h2&gt;
&lt;p&gt;Leaders and employees that demonstrate high EQ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Navigate not just motivating and empowering employees and team members, but also navigate complex and challenging decision making with the mastery of emotional response.&lt;/li&gt;
&lt;li&gt;Are realistic but not negative and overcome with their emotions.&lt;/li&gt;
&lt;li&gt;Are enthusiastic and confident in themselves and the team.&lt;/li&gt;
&lt;li&gt;Demonstrate trust and respect.&lt;/li&gt;
&lt;li&gt;Are communicative and cooperative.&lt;/li&gt;
&lt;li&gt;Volunteer for assignments and decisions.&lt;/li&gt;
&lt;li&gt;Include and engage others as much as possible.&lt;/li&gt;
&lt;li&gt;Share openly with the team.&lt;/li&gt;
&lt;li&gt;Demonstrate empathy.&lt;/li&gt;
&lt;li&gt;Actively listen.&lt;/li&gt;
&lt;li&gt;Are flexible.&lt;/li&gt;
&lt;li&gt;Develop their teams.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Low EQ: Warning Signs&lt;/h2&gt;
&lt;p&gt;Low EQ may show up as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Emotional outbursts, typically out of proportion to the situation at hand.&lt;/li&gt;
&lt;li&gt;Not listening to others.&lt;/li&gt;
&lt;li&gt;Becoming argumentative.&lt;/li&gt;
&lt;li&gt;Blaming others.&lt;/li&gt;
&lt;li&gt;Believing that others are overly sensitive, because the person with low EQ cannot understand how others feel.&lt;/li&gt;
&lt;li&gt;Difficulty maintaining friendships and other relationships.&lt;/li&gt;
&lt;li&gt;Stonewalling, or refusing to see other points of view.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Why It Matters&lt;/h2&gt;
&lt;p&gt;High EQ is not about suppressing emotion -- it is about channelling emotion constructively. Teams led by high-EQ individuals tend to communicate more openly, recover from setbacks more quickly, and make better collective decisions. Recognising low EQ behaviours early, in yourself and others, is the first step toward building a healthier team culture.&lt;/p&gt;</content><category term="Engineering"></category><category term="Leadership"></category><category term="Management"></category><category term="Soft Skills"></category><category term="Teams"></category></entry><entry><title>MakerWorld Parametric Models with OpenSCAD</title><link href="http://lizard-spock.co.uk/makerworld-parametric-models-openscad.html" rel="alternate"></link><published>2026-03-07T00:00:00+00:00</published><updated>2026-03-07T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-07:/makerworld-parametric-models-openscad.html</id><summary type="html">&lt;p&gt;How to create customizable parametric models on MakerWorld using OpenSCAD scripts.&lt;/p&gt;</summary><content type="html">&lt;p&gt;MakerWorld listings with a "Customize" button let users tweak model parameters, preview changes live, and download a ready-to-print file. Under the hood, these are OpenSCAD scripts. MakerWorld runs the script inside their Parametric Model Maker app and presents the configurable variables as a UI for the end user.&lt;/p&gt;
&lt;p&gt;If you can write an OpenSCAD script that generates your model and expose the key dimensions as variables, MakerWorld handles the rest: a polished customizer UI and a downloadable 3mf file.&lt;/p&gt;
&lt;p&gt;OpenSCAD is a free, code-based CAD tool. Rather than clicking tools and dragging dimensions, you describe geometry as code. For example, instead of drawing a sphere and setting its diameter to 20mm, you write:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;sphere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Think of it as scripting the feature timeline you would normally follow in Fusion 360 or Onshape.&lt;/p&gt;
&lt;h2&gt;Getting Started with OpenSCAD&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Learning resources:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;YouTube tutorials are the quickest way to get a feel for what OpenSCAD can do.&lt;/li&gt;
&lt;li&gt;The official &lt;a href="https://openscad.org/documentation.html"&gt;OpenSCAD documentation&lt;/a&gt; and &lt;a href="https://openscad.org/cheatsheet/"&gt;cheatsheet&lt;/a&gt; are available online.&lt;/li&gt;
&lt;li&gt;LLMs like ChatGPT are surprisingly effective: describe the object you want, ask for an OpenSCAD script, and iterate from there.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Testing your script:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run it locally in OpenSCAD on your own machine as you develop.&lt;/li&gt;
&lt;li&gt;Or use MakerWorld's Parametric Model Maker directly in your browser without installing anything.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Which version of OpenSCAD does MakerWorld support?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MakerWorld is compatible with the 2021 official release. The project has daily development builds with additional features, but stick with the stable 2021 release to ensure compatibility.&lt;/p&gt;
&lt;h2&gt;Publishing to MakerWorld&lt;/h2&gt;
&lt;p&gt;To add a Customize button to your listing, create a new MakerWorld listing and upload the &lt;code&gt;.scad&lt;/code&gt; file instead of a &lt;code&gt;.3mf&lt;/code&gt; file. MakerWorld will automatically detect it and enable the customizer. You also earn MakerWorld points when users download via the Customize button.&lt;/p&gt;
&lt;h2&gt;Controlling the Customizer UI&lt;/h2&gt;
&lt;p&gt;Any variable declared at the top of your script appears as an editable field in the UI automatically. To control the widget type (slider, dropdown, colour picker, help text), use comments following the OpenSCAD Customiser standard. The easiest way to explore the options is to click the "Sample Code" icon in the bottom-left of the Parametric Model Maker. It loads example code demonstrating all available widgets.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example: dropdown with named options&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Select which size you want&lt;/span&gt;
&lt;span class="n"&gt;Box_Size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// [10:Large, 5:Medium, 1:Small]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Font selector:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Label_Font&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Arial&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// font&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Available fonts are those pre-loaded by MakerWorld, which includes most of Google Fonts. The full list is in the Parametric Model Maker under the "Book" icon then "Third-party fonts".&lt;/p&gt;
&lt;h2&gt;Libraries&lt;/h2&gt;
&lt;p&gt;MakerWorld supports a curated set of OpenSCAD libraries:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;BOSL2&lt;/td&gt;
&lt;td&gt;General-purpose functions and geometry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UB&lt;/td&gt;
&lt;td&gt;Miscellaneous utilities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KeyV2&lt;/td&gt;
&lt;td&gt;Keyboard keycap generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gridfinity-rebuilt-openscad&lt;/td&gt;
&lt;td&gt;Gridfinity bin generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;threads-scad&lt;/td&gt;
&lt;td&gt;Threaded parts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Getriebe&lt;/td&gt;
&lt;td&gt;Gear generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;knurledFinishLib_v2&lt;/td&gt;
&lt;td&gt;Knurled surface textures&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Largely based on this &lt;a href="https://www.reddit.com/r/BambuLab/comments/1jl6ypa/how_to_create_customizable_models_on_maker_world/"&gt;Reddit post&lt;/a&gt; in r/BambuLab.&lt;/em&gt;&lt;/p&gt;</content><category term="Engineering"></category><category term="OpenSCAD"></category><category term="3D Print"></category><category term="MakerWorld"></category><category term="CAD"></category></entry><entry><title>OpenSCAD on Apple Silicon</title><link href="http://lizard-spock.co.uk/openscad-apple-silicon.html" rel="alternate"></link><published>2026-03-07T00:00:00+00:00</published><updated>2026-03-07T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-07:/openscad-apple-silicon.html</id><summary type="html">&lt;p&gt;Installing OpenSCAD on Apple Silicon Macs using Homebrew.&lt;/p&gt;</summary><content type="html">&lt;p&gt;OpenSCAD is a script-based 3D CAD modeller, well suited to parametric and printable part design. The snapshot release has native Apple Silicon support.&lt;/p&gt;
&lt;h2&gt;Install Homebrew&lt;/h2&gt;
&lt;p&gt;If &lt;a href="https://brew.sh"&gt;Homebrew&lt;/a&gt; is not already installed, run the following in Terminal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/bin/bash&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-fsSL&lt;span class="w"&gt; &lt;/span&gt;https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Install OpenSCAD&lt;/h2&gt;
&lt;p&gt;The snapshot cask provides the latest development build with native ARM support:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;brew&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;--cask&lt;span class="w"&gt; &lt;/span&gt;openscad@snapshot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once installed, OpenSCAD will be available in &lt;code&gt;/Applications&lt;/code&gt; and can be launched from Spotlight or the Applications folder.&lt;/p&gt;</content><category term="Engineering"></category><category term="OpenSCAD"></category><category term="3D Print"></category><category term="macOS"></category><category term="Homebrew"></category></entry><entry><title>reMarkable: Local File Transfer Without the Cloud</title><link href="http://lizard-spock.co.uk/remarkable-local-file-transfer-without-the-cloud.html" rel="alternate"></link><published>2026-03-07T00:00:00+00:00</published><updated>2026-03-07T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-07:/remarkable-local-file-transfer-without-the-cloud.html</id><summary type="html">&lt;p&gt;How to use the reMarkable tablet without cloud sync by unpairing the device and enabling the built-in USB file server at http://10.11.99.1/.&lt;/p&gt;</summary><content type="html">&lt;p&gt;The reMarkable tablet is excellent for reading and annotating PDFs, but by default it routes
everything through reMarkable's cloud. If you prefer to keep files local -- for privacy, or
simply because you do not want a subscription -- you can unpair the device and use the
built-in USB file server instead.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-unpairing-from-the-cloud"&gt;Unpairing from the Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-enabling-the-usb-web-interface"&gt;Enabling the USB Web Interface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-transferring-files"&gt;Transferring Files via http://10.11.99.1/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-tips-and-limitations"&gt;Tips and Limitations&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;1. Unpairing from the Cloud&lt;/h2&gt;
&lt;p&gt;Unpairing stops the device from syncing to reMarkable's servers. Your existing documents
remain on the device; they are simply no longer backed up or accessible from the reMarkable
apps on other devices.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On the tablet:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Settings&lt;/strong&gt; (gear icon, bottom-left of the home screen)&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Storage&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tap &lt;strong&gt;Unpair device&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Confirm when prompted&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once unpaired, the tablet no longer requires a reMarkable account or internet connection for
normal use. The cloud sync icon will disappear from the top bar.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Unpairing is reversible. You can re-pair the device at any time from the same
Settings screen by signing back in to your reMarkable account.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;2. Enabling the USB Web Interface&lt;/h2&gt;
&lt;p&gt;The reMarkable has a built-in HTTP file server that becomes accessible over USB. When enabled,
the tablet presents itself as a USB network adapter and serves files at &lt;code&gt;http://10.11.99.1/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;On the tablet:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Settings&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Storage&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;USB transfer&lt;/strong&gt; (the toggle may be labelled "USB web interface" depending on
   firmware version)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Connect the tablet to your computer&lt;/strong&gt; using the supplied USB-C cable. The tablet will
appear as a network device (USB Ethernet adapter) rather than a mass storage drive.&lt;/p&gt;
&lt;p&gt;On Linux the interface typically appears as &lt;code&gt;usb0&lt;/code&gt; or &lt;code&gt;enp0s20u1&lt;/code&gt; and receives an address in
the &lt;code&gt;10.11.99.0/24&lt;/code&gt; subnet automatically via DHCP from the tablet.&lt;/p&gt;
&lt;p&gt;Verify connectivity:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ping&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;.11.99.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;3. Transferring Files&lt;/h2&gt;
&lt;p&gt;Open a browser and navigate to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;http://10.11.99.1/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The web interface shows all documents and notebooks currently on the device, organised in
folders matching the tablet's home screen layout.&lt;/p&gt;
&lt;h3&gt;Uploading PDFs&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Import&lt;/strong&gt; (or the upload button, top-right)&lt;/li&gt;
&lt;li&gt;Select one or more PDF files from your computer&lt;/li&gt;
&lt;li&gt;The files appear on the tablet home screen immediately -- no restart required&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Supported formats: &lt;strong&gt;PDF&lt;/strong&gt; and &lt;strong&gt;EPUB&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Downloading annotated files&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Click on any document in the web interface&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Download&lt;/strong&gt; to save the annotated PDF to your computer&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The downloaded file includes all pencil annotations, highlights, and notes made on the tablet.&lt;/p&gt;
&lt;h3&gt;Command-line upload with curl&lt;/h3&gt;
&lt;p&gt;For scripting or batch uploads:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;http://10.11.99.1/documents/&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-F&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;file=@/path/to/document.pdf&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To upload into a specific folder, first find the folder UUID from the web interface URL, then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-X&lt;span class="w"&gt; &lt;/span&gt;POST&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;http://10.11.99.1/documents/{folder-uuid}&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-F&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;file=@/path/to/document.pdf&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;4. Tips and Limitations&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;No Wi-Fi required.&lt;/strong&gt; The USB file server works entirely over the USB cable with no network
  connection needed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cable must stay connected.&lt;/strong&gt; The web interface is only available while the tablet is
  plugged in. Unplugging immediately drops the &lt;code&gt;10.11.99.1&lt;/code&gt; address.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;One client at a time.&lt;/strong&gt; The built-in server is minimal; avoid opening multiple browser
  tabs uploading simultaneously.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Folder structure is flat internally.&lt;/strong&gt; The reMarkable stores documents with UUIDs
  internally; the folder hierarchy you see in the web interface is a virtual view maintained
  by the device.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Firmware updates still work offline.&lt;/strong&gt; Updates are downloaded over Wi-Fi separately from
  the cloud sync; unpairing does not block firmware updates if Wi-Fi is available.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Annotations on existing PDFs&lt;/strong&gt; are exported as a new annotated PDF -- the original on-
  device file is not modified.&lt;/li&gt;
&lt;/ul&gt;</content><category term="Hardware &amp; Homelab"></category><category term="reMarkable"></category><category term="eink"></category><category term="privacy"></category></entry><entry><title>SoC Article 01: From Room to Silicon — The Story of the Computer System</title><link href="http://lizard-spock.co.uk/soc-article-01-from-room-to-silicon.html" rel="alternate"></link><published>2026-03-07T00:00:00+00:00</published><updated>2026-03-07T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-07:/soc-article-01-from-room-to-silicon.html</id><summary type="html">&lt;p&gt;How computing evolved from room-filling mainframes to a sliver of silicon in your pocket — and why that history shapes modern SoC design.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Series: Introduction to SoC Design | Article 1 of 11&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt="image" src="http://lizard-spock.co.uk/e94c024c96e0d5c9d4abd4ff88d2b54b0c6220e6da4821532a97d5e0972e0297-901w.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;There is a photograph from 1964 that captures the scale of computing at the time. It shows two engineers installing an &lt;a href="https://en.wikipedia.org/wiki/IBM_System/360"&gt;IBM System/360&lt;/a&gt; Model 50. They are not sitting at desks. They are standing in a large, air-conditioned room, surrounded by cabinets the size of wardrobe closets, connected by thick bundles of cabling snaking under a raised false floor. The computer weighs approximately two tonnes. It required specialist riggers with cranes and fork trucks to move into the building. It draws 30 kilowatts of power — enough to heat several homes.&lt;/p&gt;
&lt;p&gt;That machine cost around $3.5 million in 1964 dollars. It performed roughly 500,000 operations per second.&lt;/p&gt;
&lt;p&gt;The phone in your pocket performs about 15 &lt;em&gt;trillion&lt;/em&gt; operations per second - thirty million times more — on a sliver of silicon roughly 100 mm² in area, weighing a fraction of a gram, drawing less than three watts. It fits comfortably in a jacket pocket.&lt;/p&gt;
&lt;p&gt;This article is the story of how we got from there to here. It is not just a history lesson. Understanding the shape of that journey — what drove miniaturisation at each step, and what trade-offs were made along the way — is essential context for understanding why modern SoC design is structured the way it is.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/01-era-scale-comparison-HQ.png"&gt;&lt;img alt="The miniaturisation journey: five eras of computing from room-sized mainframe to a fingernail-sized SoC die, showing the same computational capability in a dramatically shrinking footprint" src="http://lizard-spock.co.uk/01-era-scale-comparison-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;What is a "System"?&lt;/h2&gt;
&lt;p&gt;Before discussing a &lt;em&gt;System&lt;/em&gt; on Chip, we should understand what the word "system" means in this context.&lt;/p&gt;
&lt;p&gt;In engineering, a &lt;strong&gt;system&lt;/strong&gt; is a collection of components that work together to perform a function greater than any single component could achieve alone. A computer &lt;em&gt;system&lt;/em&gt;, in the classical sense, means all the hardware necessary to store, retrieve, and process information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;processor&lt;/strong&gt; — the arithmetic and logic engine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory&lt;/strong&gt; — where programs and data live&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storage&lt;/strong&gt; - where data persists when power is off&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Input/Output&lt;/strong&gt; — keyboards, displays, printers, serial ports&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interconnect&lt;/strong&gt; — the buses and cables that tie it all together&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Power supply&lt;/strong&gt; — the electrical infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For decades, each of these was a separate physical unit, often made by different vendors, assembled on a raised floor in a dedicated machine room. The history of computing is largely the story of these components shrinking, converging, and ultimately merging.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Era 1: The Room-Sized Machine (1950s–1960s)&lt;/h2&gt;
&lt;h3&gt;Valves and Racks&lt;/h3&gt;
&lt;p&gt;The earliest electronic computers used &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Vacuum_tube"&gt;vacuum tubes&lt;/a&gt;&lt;/strong&gt; (valves) as their switching elements. A vacuum tube is roughly the size of a light bulb. A computer that needs hundreds of thousands of switching elements built from vacuum tubes fills a building.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/ENIAC"&gt;ENIAC&lt;/a&gt;&lt;/strong&gt; (1945) is the canonical example: 17,468 vacuum tubes, 70,000 resistors, 10,000 capacitors, filling a room 2.4 m × 1.8 m × 30 m. It consumed 150 kilowatts of power and broke down regularly — with so many valves, a failure every few hours was normal. Operators spent more time repairing it than computing with it.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Manchester_Baby"&gt;Manchester Baby&lt;/a&gt;&lt;/strong&gt; (1948), while tiny by comparison, still occupied a substantial rack of equipment and required skilled operators to program it using switches and plugboards.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Approximate Physical Scale — 1950s Computer Systems

  ┌──────────────────────────────────────────────────────────────────┐
  │                                                                  │
  │  ENIAC (1945)                                                    │
  │                                                                  │
  │  [██████████████████████████████████████████████████████████]    │  ← 30 metres
  │  [█ Accumulator █][█ Multiplier █][█ Divider █][█ I/O █][█...█]  │
  │                                                                  │
  │  Weight: ~27 tonnes   Power: 150 kW   Speed: 5,000 ADD/sec       │
  │                                                                  │
  └──────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;The Transistor Changes Everything&lt;/h3&gt;
&lt;p&gt;In 1947, &lt;a href="https://en.wikipedia.org/wiki/Bell_Labs"&gt;Bell Labs&lt;/a&gt; invented the &lt;a href="https://en.wikipedia.org/wiki/Transistor"&gt;transistor&lt;/a&gt;. It did the same job as a vacuum tube — acting as an electronic switch — but was smaller, faster, cooler, more reliable, and consumed far less power. By the late 1950s, computers began to be built from transistors instead.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;IBM System/360&lt;/strong&gt; (1964) was a landmark: the first family of computers with a common instruction set, so that programs written for one model would run on any other. But it was still a room-scale machine. The System/360 Model 50 filled multiple cabinets, required dedicated air conditioning, and had to be craned into the computer room through specially widened doorways or lowered through the roof.&lt;/p&gt;
&lt;p&gt;The economics were equally extreme: only universities, large corporations, government agencies, and national laboratories could afford to own one. Everyone else bought time-shares, submitting jobs on punched cards and waiting hours for results.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/02-ibm360-room-HQ.png"&gt;&lt;img alt="Floor plan of the IBM System/360 computer room showing four cabinets — CPU, Memory, I/O Control, and Tape Drives — connected by cables under a raised floor, with a human figure showing scale" src="http://lizard-spock.co.uk/02-ibm360-room-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;img alt="image" src="http://lizard-spock.co.uk/75c93b948fd4c7e4d5d2bd57310eae25d63ba86933920bd1896ee562c266c3a4-900w.jpg"&gt;&lt;/p&gt;
&lt;h2&gt;Era 2: The Minicomputer (1965–1975)&lt;/h2&gt;
&lt;h3&gt;Thinking Small&lt;/h3&gt;
&lt;p&gt;The &lt;strong&gt;minicomputer&lt;/strong&gt; was not called "mini" because it was small by today's standards. It was called mini because it was dramatically smaller than the mainframes it accompanied — small enough to fit in a single large cabinet, deliverable in a standard lift, operable without a dedicated air-conditioned room.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Digital_Equipment_Corporation"&gt;Digital Equipment Corporation (DEC)&lt;/a&gt;&lt;/strong&gt; pioneered this category. Their &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/PDP-8"&gt;PDP-8&lt;/a&gt;&lt;/strong&gt; (1965) was a 12-bit machine that cost $18,000 — expensive, but accessible to a laboratory, university department, or medium-sized company without a dedicated data centre.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/PDP-11"&gt;PDP-11&lt;/a&gt;&lt;/strong&gt; (1970) is one of the most important computers ever designed. It was a 16-bit machine that fit in a single rack about the size of a tall filing cabinet. It had a clean, elegant instruction set that influenced virtually every processor architecture that followed — including &lt;a href="https://en.wikipedia.org/wiki/Unix"&gt;Unix&lt;/a&gt;, which was first developed on a &lt;a href="https://en.wikipedia.org/wiki/PDP-7"&gt;PDP-7&lt;/a&gt; and PDP-11.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;DEC PDP-11 (1970) — Physical Footprint:

  ┌─────────────────────┐
  │  ┌───────────────┐  │
  │  │  Backplane    │  │  ← Processor and memory cards slot in here
  │  │  (UNIBUS)     │  │
  │  │               │  │
  │  │  CPU card     │  │  ← A single card, 30 cm × 25 cm
  │  │  Memory cards │  │
  │  │  I/O cards    │  │
  │  └───────────────┘  │
  │  Power supply       │
  └─────────────────────┘
    ~ 60 cm × 45 cm × 60 cm
    Weight: ~30 kg
    Power: ~300 W
    Speed: ~1 million ops/sec
    Cost: ~$10,000 (1970)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The PDP-11 introduced several ideas that persist in modern SoC design: &lt;a href="https://en.wikipedia.org/wiki/Memory-mapped_I/O"&gt;memory-mapped I/O&lt;/a&gt; (where peripherals appear as addresses in the memory map), a bus standard (&lt;a href="https://en.wikipedia.org/wiki/Unibus"&gt;UNIBUS&lt;/a&gt;), and the concept of a clean separation between the processor and the rest of the system through a well-defined bus interface.&lt;/p&gt;
&lt;h3&gt;The Minicomputer Era's Legacy&lt;/h3&gt;
&lt;p&gt;The minicomputer era produced ideas that underpin every SoC today:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bus standards&lt;/strong&gt; — the UNIBUS, &lt;a href="https://en.wikipedia.org/wiki/Multibus"&gt;Multibus&lt;/a&gt;, and &lt;a href="https://en.wikipedia.org/wiki/S-100_bus"&gt;S-100&lt;/a&gt; buses established the principle that components from different vendors could interoperate on a common bus&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operating systems&lt;/strong&gt; — Unix was born on the PDP-11; its model of processes, file descriptors, and device drivers lives on in &lt;a href="https://en.wikipedia.org/wiki/Linux"&gt;Linux&lt;/a&gt; running on modern SoCs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modular architecture&lt;/strong&gt; — CPU, memory, and I/O were separate cards in the same backplane, a precursor to the IP block model&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Era 3: The Microprocessor (1971–1980)&lt;/h2&gt;
&lt;h3&gt;Everything on One Chip&lt;/h3&gt;
&lt;p&gt;In 1971, Intel introduced the &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Intel_4004"&gt;4004&lt;/a&gt;&lt;/strong&gt; — the first microprocessor. It placed the entire CPU — arithmetic unit, registers, control logic — onto a single chip about 12 mm². It ran at 740 kHz and processed 4-bit numbers.&lt;/p&gt;
&lt;p&gt;This was a revolutionary idea: previously, a "CPU" was a cabinet full of boards. Now it was a package you could hold between your fingers.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/03-pdp11-vs-4004-HQ.png"&gt;&lt;img alt="Side-by-side comparison: the PDP-11/20 CPU (1970) as a rack of four boards for ALU, registers, control, and bus interface versus the Intel 4004 (1971) as a single tiny chip package — the entire CPU compressed onto 12 mm²" src="http://lizard-spock.co.uk/03-pdp11-vs-4004-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Intel_8080"&gt;8080&lt;/a&gt;&lt;/strong&gt; (Intel, 1974), &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/MOS_Technology_6502"&gt;6502&lt;/a&gt;&lt;/strong&gt; (MOS Technology, 1975), and &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Zilog_Z80"&gt;Z80&lt;/a&gt;&lt;/strong&gt; (Zilog, 1976) followed in rapid succession. These 8-bit processors became the engines of the personal computer revolution.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Intel_8086"&gt;Intel 8086&lt;/a&gt;&lt;/strong&gt; (1978) and &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Motorola_68000"&gt;Motorola 68000&lt;/a&gt;&lt;/strong&gt; (1979) raised the bar to 16-bit, with the 68000 in particular earning a reputation for elegance and performance that made it the choice for the &lt;a href="https://en.wikipedia.org/wiki/Macintosh"&gt;Apple Macintosh&lt;/a&gt;, the &lt;a href="https://en.wikipedia.org/wiki/Amiga"&gt;Amiga&lt;/a&gt;, the &lt;a href="https://en.wikipedia.org/wiki/Atari_ST"&gt;Atari ST&lt;/a&gt;, and countless workstations.&lt;/p&gt;
&lt;p&gt;But the microprocessor alone was just the CPU. Everything else — memory, storage, I/O — was still provided by separate chips on a board. The "system" was still a board, just a smaller one.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Era 4: The Personal Computer (1977–1990)&lt;/h2&gt;
&lt;h3&gt;The Desktop System&lt;/h3&gt;
&lt;p&gt;The first personal computers were kits for hobbyists. The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Altair_8800"&gt;Altair 8800&lt;/a&gt;&lt;/strong&gt; (1975) was an 8080-based machine with no keyboard, no display, and no software beyond a bootloader — users programmed it by toggling switches on the front panel.&lt;/p&gt;
&lt;p&gt;Within a few years, &lt;strong&gt;Apple&lt;/strong&gt;, &lt;strong&gt;Commodore&lt;/strong&gt;, and &lt;strong&gt;Tandy&lt;/strong&gt; produced complete personal computers: CPU, RAM, ROM, keyboard, display output, and storage on a single motherboard in a desktop enclosure. The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Apple_II"&gt;Apple II&lt;/a&gt;&lt;/strong&gt; (1977) sold as a complete system you could put on a desk.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Apple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;II&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Motherboard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1977&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Complete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Computer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;One&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Board&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;┌────────────────────────────────────────────────────────────────┐&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="n"&gt;Apple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;II&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Motherboard&lt;/span&gt;&lt;span class="w"&gt;                     &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;                                                                &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6502&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CPU&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;RAM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chips&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chips&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Video&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chip&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;                                                                &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Keyboard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Cassette&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Speaker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;                                                                &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;┌────┐&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;┌────┐&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;┌────┐&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;┌────┐&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;┌────┐&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;┌────┐&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;┌────┐&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;┌────┐&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;└────┘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;└────┘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;└────┘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;└────┘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;└────┘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;└────┘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;└────┘&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;└────┘&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expansion&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cards&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;serial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;&lt;span class="p"&gt;.)&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;                                                                &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Board&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;chips&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;66&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;power&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;W&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="n"&gt;Speed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;MHz&lt;/span&gt;&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;└────────────────────────────────────────────────────────────────┘&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/IBM_Personal_Computer"&gt;IBM PC&lt;/a&gt;&lt;/strong&gt; (1981) standardised the desktop architecture that dominated computing for three decades: a processor, a chipset handling memory and I/O, expansion slots for peripherals, and a shared bus (first &lt;a href="https://en.wikipedia.org/wiki/Industry_Standard_Architecture"&gt;ISA&lt;/a&gt;, later &lt;a href="https://en.wikipedia.org/wiki/Peripheral_Component_Interconnect"&gt;PCI&lt;/a&gt;). By the late 1980s, a PC could sit on a desk, consume 50–200 W, and perform millions of operations per second for a few thousand dollars.&lt;/p&gt;
&lt;p&gt;The chip count had fallen from thousands (mainframe) to hundreds (minicomputer) to dozens on a single motherboard. But a PC motherboard was still a system assembled from many chips: CPU, north bridge, south bridge, graphics chip, sound chip, network chip, storage controller, and many more.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Era 5: The Laptop — Mobile Demands Integration&lt;/h2&gt;
&lt;h3&gt;Batteries Change Everything&lt;/h3&gt;
&lt;p&gt;The first truly portable computers appeared around 1981. The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/GRiD_Compass"&gt;Grid Compass&lt;/a&gt;&lt;/strong&gt; (1982) was used by NASA and the US military — it was functional but cost $8,000 and ran for barely four hours on battery. The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Compaq_LTE"&gt;Compaq LTE&lt;/a&gt;&lt;/strong&gt; (1987) was the first laptop to use a 3.5" hard drive and internal battery in a genuinely portable form factor.&lt;/p&gt;
&lt;p&gt;Mobile computing imposed a constraint that desktop design had never faced: &lt;strong&gt;batteries&lt;/strong&gt;. A desktop computer plugged into the wall can draw as much power as needed. A laptop must run for hours on a battery with finite energy.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;Power&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Budget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;—&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Desktop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;vs&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Laptop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;late&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1980&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;Desktop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1988&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="nv"&gt;Compaq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;LTE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1987&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;:
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;Power&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;W&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nv"&gt;Power&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;W&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;Battery&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;none&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nv"&gt;Battery&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;NiCd&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;hr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;life&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;Weight&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;kg&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="nv"&gt;Weight&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;kg&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;Size&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tower&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;case&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="nv"&gt;Size&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;×&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;×&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cm&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;Problem&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;same&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;chips&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;designed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;desktop&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;drew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;W&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;—&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;far&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;too&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;much&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;battery&lt;/span&gt;.
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;approach&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;chip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;design&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;was&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;needed&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Power pressure drove two responses:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Low-voltage CMOS&lt;/strong&gt; — designers switched from bipolar logic (powerful but power-hungry) to &lt;a href="https://en.wikipedia.org/wiki/CMOS"&gt;CMOS&lt;/a&gt; (Complementary Metal-Oxide-Semiconductor), which consumes power only when transistors switch, not when they are idle. This dramatically reduced both active and standby power.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Integration&lt;/strong&gt; — every chip-to-chip interface wastes energy driving signals off-chip and back. Merging two chips into one removes those interfaces. The laptop era was the first time integration was driven primarily by power rather than just performance.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Era 6: The Mobile Phone and the ARM Architecture&lt;/h2&gt;
&lt;h3&gt;An Architecture Built for Efficiency&lt;/h3&gt;
&lt;p&gt;In 1983, &lt;a href="https://en.wikipedia.org/wiki/Acorn_Computers"&gt;Acorn Computers&lt;/a&gt; in Cambridge designed their own processor: the &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/ARM_architecture_family"&gt;Acorn RISC Machine&lt;/a&gt;&lt;/strong&gt;, or &lt;strong&gt;ARM&lt;/strong&gt;. It was a 32-bit RISC processor designed to be simple, low-power, and fast enough for interactive computing in an inexpensive product. The original ARM1 ran at 6 MHz and consumed a fraction of a watt — remarkable for 1985.&lt;/p&gt;
&lt;p&gt;Acorn spun off &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Arm_Holdings"&gt;Advanced RISC Machines Ltd&lt;/a&gt;&lt;/strong&gt; in 1990 as a joint venture with Apple and VLSI Technology. Rather than manufacturing chips itself, ARM licenced its architecture to other companies — a business model that would eventually see ARM cores inside virtually every mobile device on the planet.&lt;/p&gt;
&lt;p&gt;The first mobile phones were large, power-hungry, and limited. As &lt;a href="https://en.wikipedia.org/wiki/GSM"&gt;GSM&lt;/a&gt; digital mobile telephony spread in the 1990s, phones needed to perform signal processing (decoding the radio channel), handle the telephone UI, and manage a small battery. They could afford perhaps 200 mW of sustained power.&lt;/p&gt;
&lt;p&gt;A phone of the early 2000s had several separate chips: a &lt;strong&gt;baseband processor&lt;/strong&gt; (running the radio protocols), an &lt;strong&gt;application processor&lt;/strong&gt; (running the UI and apps), a &lt;strong&gt;power management IC&lt;/strong&gt;, a &lt;strong&gt;display controller&lt;/strong&gt;, and various analog front-ends for audio and radio. These chips communicated over a shared PCB — the "system" was a small board inside a plastic case.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/04-smartphone-pcb-HQ.png"&gt;&lt;img alt="A pre-SoC smartphone PCB (c. 2003) showing six discrete chips — Application Processor ARM9, Baseband DSP, PMIC, SDRAM, Flash NOR, and LCD Controller — connected by PCB traces, with an annotation showing all of this becomes one SoC" src="http://lizard-spock.co.uk/04-smartphone-pcb-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This was the moment before SoC. All the pieces existed — they just were not yet on the same die.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Era 7: The System on Chip (1995–present)&lt;/h2&gt;
&lt;h3&gt;Integration Crosses a Threshold&lt;/h3&gt;
&lt;p&gt;As process technology advanced through the 1990s — from 350 nm to 250 nm to 180 nm — the number of transistors that could be fabricated reliably on a single die crossed 100 million. That is enough transistors to implement not just a CPU, but everything around it: memory controllers, DSPs, display engines, USB, audio, and power management.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/OMAP"&gt;Texas Instruments OMAP&lt;/a&gt;&lt;/strong&gt; series (early 2000s) was among the first true smartphone SoCs: ARM application processor, DSP, camera interface, display controller, and power management all on one die. This appeared in early Nokia smartphones and PDAs.&lt;/p&gt;
&lt;p&gt;Apple's acquisition of &lt;a href="https://en.wikipedia.org/wiki/P.A._Semi"&gt;PA Semi&lt;/a&gt; in 2008 and its launch of the &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Apple_A4"&gt;A4&lt;/a&gt;&lt;/strong&gt; SoC in 2010 (the first iPhone 4 chip) signalled that the world's most valuable consumer electronics company was betting everything on the SoC model. Qualcomm, Samsung, MediaTek, and HiSilicon followed with their own vertical SoC programmes.&lt;/p&gt;
&lt;p&gt;The convergence was complete:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Integration&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Journey&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Same&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Computational&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Power&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Shrinking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Footprint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;Year&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="nx"&gt;Physical&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Size&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nx"&gt;Power&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;Transistors&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;─────────────────────────────────────────────────────────────────────────&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1964&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;IBM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;System&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;rooms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tonnes&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;kW&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1970&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;DEC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PDP&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="nx"&gt;Filing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cabinet&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1977&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;Apple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;II&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;full&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nx"&gt;Desk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PCB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1982&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;Intel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80286&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;CPU&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;alone&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;pin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;DIP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="mi"&gt;134&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;1993&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;Intel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Pentium&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="mi"&gt;273&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;pin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;PGA&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;chip&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="m m-Double"&gt;3.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2003&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;Nokia&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6600&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;chips&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;PCB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;inside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mW&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;total&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2010&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;Apple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;A4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SoC&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;×&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;die&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;Apple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;A14&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SoC&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mm²&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;die&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="m m-Double"&gt;11.8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;Apple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;A18&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SoC&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;mm²&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;die&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;W&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;B&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;─────────────────────────────────────────────────────────────────────────&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Approximate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;counting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;discrete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;transistors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SSI&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;MSI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;chips&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;Moore's Law: The Engine of Miniaturisation&lt;/h2&gt;
&lt;p&gt;No account of this journey is complete without &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Moore%27s_law"&gt;Moore's Law&lt;/a&gt;&lt;/strong&gt;. In 1965, &lt;a href="https://en.wikipedia.org/wiki/Gordon_Moore"&gt;Gordon Moore&lt;/a&gt; (co-founder of Intel) observed that the number of transistors on a commercially practical integrated circuit doubled approximately every two years. This was an empirical observation about the economics of the semiconductor industry, but it became a self-fulfilling prophecy: the industry organised itself to deliver that doubling, and did so for more than fifty years.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lizard-spock.co.uk/05-moores-law-HQ.png"&gt;&lt;img alt="Transistor count chart from 1971 to 2024 on a log scale showing the exponential growth from the Intel 4004 at 2,300 transistors to the Apple A18 at 16 billion, with a dotted line showing the idealized Moore's Law doubling every two years" src="http://lizard-spock.co.uk/05-moores-law-900w.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each doubling meant that the same design could be shrunk to half the area (reducing cost), or that twice as much logic could fit in the same area (enabling integration). Both drove the SoC story.&lt;/p&gt;
&lt;p&gt;Moore's Law has slowed in recent years — physical limits make further miniaturisation increasingly difficult and expensive below 3 nm. The industry is responding with new techniques: &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/3D_integrated_circuit"&gt;3D stacking&lt;/a&gt;&lt;/strong&gt; (chips stacked vertically), &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Chiplet"&gt;chiplets&lt;/a&gt;&lt;/strong&gt; (multiple dies in one package), and new materials. But the principle — relentless pressure toward more integration per unit cost — continues.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;What "System" Means Now&lt;/h2&gt;
&lt;p&gt;Return to where we started: the IBM System/360, craned into a dedicated machine room, requiring a team of operators and a purpose-built building to run.&lt;/p&gt;
&lt;p&gt;Today's SoC is a &lt;em&gt;more capable&lt;/em&gt; system — more memory, faster clock, more peripherals, better networking — occupying an area smaller than a fingernail, drawing power measurable in milliwatts, costing a few dollars to manufacture at scale.&lt;/p&gt;
&lt;p&gt;But it is still a &lt;em&gt;system&lt;/em&gt;: processor, memory controller, interconnect, peripherals, power management, security hardware. The same logical building blocks exist. They have simply been reimplemented in silicon, brought together on a single die, separated by wires measured in nanometres rather than copper cables measured in metres.&lt;/p&gt;
&lt;p&gt;Understanding that lineage — why the blocks exist, what problems they solve, where the trade-offs come from — is the context for everything that follows in this series.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Computer systems began as room-filling collections of vacuum tubes. The transistor enabled the minicomputer — a cabinet-scale machine accessible to laboratories and companies. The microprocessor collapsed the CPU onto a single chip and made the personal computer possible. Mobile computing added battery constraints that drove integration for power efficiency. The System on Chip emerged when transistor densities crossed the threshold that made fitting an entire system — CPU, memory, peripherals, and more — onto a single die both technically feasible and economically compelling. Moore's Law underpinned the entire journey, doubling integration density roughly every two years for five decades.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Series Roadmap&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Article&lt;/th&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;01&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;From Room to Silicon — History of the Computer System (this article)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="soc-article-02-anatomy-and-motivation.html"&gt;02&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="soc-article-02-anatomy-and-motivation.html"&gt;What is a System on Chip? — Anatomy and Motivation&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="soc-article-03-design-stack.html"&gt;03&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="soc-article-03-design-stack.html"&gt;The SoC Design Stack: From Transistors to Software&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;04&lt;/td&gt;
&lt;td&gt;Processor Cores: CPU, DSP, GPU and Hardware Accelerators&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;05&lt;/td&gt;
&lt;td&gt;Memory Architecture: Caches, DRAM, and On-chip Storage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;06&lt;/td&gt;
&lt;td&gt;Interconnects and Bus Protocols: AXI, AHB, and APB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;07&lt;/td&gt;
&lt;td&gt;Clocking, Reset, and Power Domains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;08&lt;/td&gt;
&lt;td&gt;Peripherals and I/O: Connecting the SoC to the World&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;09&lt;/td&gt;
&lt;td&gt;Hardware Description Languages and RTL Design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;The SoC Design Flow: From Specification to Silicon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;HW/SW Co-Design: Bridging Software and Silicon&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Next: &lt;a href="http://lizard-spock.co.uk/soc-article-02-anatomy-and-motivation.html"&gt;Article 02 - What is a System on Chip? Anatomy and Motivation&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content><category term="Engineering"></category><category term="SoC"></category><category term="Hardware"></category><category term="Computer Architecture"></category><category term="History"></category><category term="Electronics"></category></entry><entry><title>Requirements Writing</title><link href="http://lizard-spock.co.uk/requirements-writing.html" rel="alternate"></link><published>2026-03-06T18:00:00+00:00</published><updated>2026-03-06T18:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-06:/requirements-writing.html</id><summary type="html">&lt;p&gt;Good requirements engineering is fundamental to delivering products that meet customer needs within cost and schedule. A well-formed requirement identifies …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Good requirements engineering is fundamental to delivering products that meet customer needs within cost and schedule. A well-formed requirement identifies a specific user or stakeholder, defines a positive end result, and states a measurable success criterion -- for example: &lt;em&gt;"The internet user shall be able to access their current account balance in less than 5 seconds."&lt;/em&gt; Requirements must be unambiguous, singular (one requirement per statement), and free of escape clauses such as "unless", "except", or "if possible". They should avoid designing the solution, speculating about future needs, or using vague qualitative terms like "user-friendly" or "flexible" that cannot be verified. The normative terms shall, should, and may carry specific and distinct meanings -- using them precisely is critical to a traceable and verifiable requirement set.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The IBM Requirements Writing Training document uses 'shall' or 'will' interchangeably to signal a mandatory requirement. The IEEE Standards Style Manual (also referenced below) deprecates the use of 'will' for mandatory requirements, reserving it for statements of fact only. The IEEE definition is the preferred usage.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Normative Terms&lt;/h2&gt;
&lt;p&gt;Normative requirements are normally phrased using one of the three terms below: shall, should, or may. All normative elements that are requirements (shall) are to be followed in all cases in order to be in conformity.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;Priority&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;'Shall'&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;'Must-have' for minimum viable product (MVP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;'Should'&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;'Desirable' in product and to be considered for phase 1, including any impact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;'May'&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;'Nice-to-have' and could be included if no impact to key metrics. Should log decision.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Use of Special Terms (from IEEE Standards Style Manual)&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The word &lt;strong&gt;shall&lt;/strong&gt; is used to indicate mandatory requirements strictly to be followed in order to conform to the Specification and from which no deviation is permitted (shall equals is required to).&lt;/p&gt;
&lt;p&gt;The use of the word &lt;strong&gt;must&lt;/strong&gt; is deprecated and shall not be used when stating mandatory requirements; must is used only to describe unavoidable situations.&lt;/p&gt;
&lt;p&gt;The use of the word &lt;strong&gt;will&lt;/strong&gt; is deprecated and shall not be used when stating mandatory requirements; will is only used in statements of fact.&lt;/p&gt;
&lt;p&gt;The word &lt;strong&gt;should&lt;/strong&gt; is used to indicate that among several possibilities one is recommended as particularly suitable, without mentioning or excluding others; or that a certain course of action is preferred but not necessarily required; or that (in the negative form) a certain course of action is deprecated but not prohibited (should equals is recommended that).&lt;/p&gt;
&lt;p&gt;The word &lt;strong&gt;may&lt;/strong&gt; is used to indicate a course of action permissible within the limits of the Specification (may equals is permitted to).&lt;/p&gt;
&lt;p&gt;The word &lt;strong&gt;can&lt;/strong&gt; is used for statements of possibility and capability, whether material, physical, or causal (can equals is able to).&lt;/p&gt;
&lt;p&gt;All sections are normative, unless they are explicitly indicated to be informative.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Requirement Categories&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;The following categories reflect a common industry classification used in semiconductor product development.&lt;/em&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;th&gt;Owner&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CR&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Customer Requirement&lt;/strong&gt; -- A customer need that the product needs to meet. Gathered from customer interaction, field channels or market research. May not be possible to meet all CRs on a product due to risk or resources.&lt;/td&gt;
&lt;td&gt;Marketing, Systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SR&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;System Requirement&lt;/strong&gt; -- Describes the required black-box behaviour of the device. Customer visible SRs are the primary basis for the datasheet. Often, an SR translates a CR into the plan-of-record for a product. Captures the negotiated attribute. May not fully meet the ideal CR.&lt;/td&gt;
&lt;td&gt;Systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DR&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Design Requirement&lt;/strong&gt; -- Result of distillation of SR, driven by implementation choices that do not affect the black-box behaviour but need to be defined for the design or verification team. Capture constraints required to implement the SRs.&lt;/td&gt;
&lt;td&gt;Design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VR&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Verification Requirement&lt;/strong&gt; -- Description of what needs to be done to ensure an SR and/or DR is implemented correctly. Linked to at least one SR and/or DR. Checks and coverage information is recorded in VRs.&lt;/td&gt;
&lt;td&gt;Verification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VAR&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Validation Requirement&lt;/strong&gt; -- A concise description of how an SR or DR of any requirement type will be covered with a test case during the emulation or post-silicon phase of development. Validation requirements check whether we implemented the right thing through means of functional testing or parametric silicon measurements. Test conditions are recorded in a VAR. Linked to at least one SR.&lt;/td&gt;
&lt;td&gt;Validation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Requirement Types&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Functional&lt;/td&gt;
&lt;td&gt;Normative functional requirements that can be verified and/or validated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parametric&lt;/td&gt;
&lt;td&gt;Normative parametric requirements that can be verified and/or validated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Register Field&lt;/td&gt;
&lt;td&gt;Normative register field requirements.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Informative&lt;/td&gt;
&lt;td&gt;Informative requirement content, not actionable, but provides context for better interpretation of normative requirements. Informative elements are illustrations, examples, or suggestions that explain the meaning and implications of requirements, as well as case studies on their application. May include diagrams and other attachments which are not to be treated as normative.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use Case&lt;/td&gt;
&lt;td&gt;System-level use cases. Commonly captured as diagrams and set context (informative) but can require verification and distillation into further requirements (normative).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://lizard-spock.co.uk/pdf/IBM_Requirements_Writing_Training.pdf"&gt;IBM Requirements Writing Training (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://lizard-spock.co.uk/pdf/2021-IEEE-Standards-Style-Manual.pdf"&gt;2021 IEEE Standards Style Manual (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Engineering"></category><category term="Design"></category><category term="Verilog"></category><category term="Verification"></category></entry><entry><title>Scotland Outdoor Routes</title><link href="http://lizard-spock.co.uk/scotland-outdoor-routes.html" rel="alternate"></link><published>2026-03-06T12:00:00+00:00</published><updated>2026-03-06T12:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-03-06:/scotland-outdoor-routes.html</id><summary type="html">&lt;h2&gt;Misc&lt;/h2&gt;
&lt;p&gt;Historic Scotland (Family £106/year includes entry to Edinburgh Castle):
&lt;a href="https://www.historicenvironment.scot/"&gt;https://www.historicenvironment.scot/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://members.historic-scotland.gov.uk/file/HS_Map.pdf"&gt;Site Map (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Mapping&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory …&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;</summary><content type="html">&lt;h2&gt;Misc&lt;/h2&gt;
&lt;p&gt;Historic Scotland (Family £106/year includes entry to Edinburgh Castle):
&lt;a href="https://www.historicenvironment.scot/"&gt;https://www.historicenvironment.scot/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://members.historic-scotland.gov.uk/file/HS_Map.pdf"&gt;Site Map (PDF)&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Mapping&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory Map (£25/year)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://memory-map.com/maps/uk-os-topo-maps/"&gt;https://memory-map.com/maps/uk-os-topo-maps/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bing Maps, switch from Road to Ordnance Survey (free)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.bing.com/maps"&gt;https://www.bing.com/maps&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ordnance Survey Maps (7 day free trial, £24/year)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://osmaps.ordnancesurvey.co.uk/"&gt;https://osmaps.ordnancesurvey.co.uk/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rucksack Readers for long distance routes (~£15 per map)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.rucsacs.com/book-category/scotland/"&gt;https://www.rucsacs.com/book-category/scotland/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spokes Cycle Maps (~£7 per map)&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.spokes.org.uk/spokes-maps/"&gt;http://www.spokes.org.uk/spokes-maps/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Urban Nature Maps (Edinburgh &amp;amp; Glasgow, £10 each)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://edinburgh-urban-nature-map"&gt;edinburgh-urban-nature-map&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scots Ways&lt;/td&gt;
&lt;td&gt;&lt;a href="https://scotways.com/maps-and-leaflets/"&gt;https://scotways.com/maps-and-leaflets/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;All Scotland&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.walkhighlands.co.uk/"&gt;Walk Highlands&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forestryandland.gov.scot/visit/activities/mountain-biking/7stanes"&gt;7Stanes Mountain Biking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://scotways.com/maps-and-leaflets/"&gt;Scots Ways Maps and Leaflets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Edinburgh&lt;/h2&gt;
&lt;h3&gt;Seven Hills&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Castle Rock&lt;/li&gt;
&lt;li&gt;Calton Hill&lt;/li&gt;
&lt;li&gt;Arthur's Seat&lt;/li&gt;
&lt;li&gt;Blackford Hill&lt;/li&gt;
&lt;li&gt;Braid Hills&lt;/li&gt;
&lt;li&gt;Corstorphine Hill&lt;/li&gt;
&lt;li&gt;Craiglockhart Hills&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Midlothian&lt;/h2&gt;
&lt;h2&gt;Pentland Hills&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pentlandhills.org/"&gt;www.pentlandhills.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pentlandhills.org/downloads/file/16/2019-map"&gt;Pentland Hills Map (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;East Lothian&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.eastlothian.gov.uk/info/210569/countryside_and_wildlife/12044/core_paths/2"&gt;Core Paths Map links&lt;/a&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Map&lt;/th&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23120/map_a_gullane_aberlady_and_surrounding_area"&gt;Map A&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Gullane, Aberlady and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23137/map_b_north_berwick_and_surrounding_area"&gt;Map B&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;North Berwick and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23127/map_c_whitekirk_and_surrounding_area"&gt;Map C&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Whitekirk and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23121/map_d_musselburgh_north"&gt;Map D&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Musselburgh North&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23126/map_e_prestonpans_port_seton_tranent_north"&gt;Map E&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Prestonpans, Port Seton, Tranent North&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23128/map_f_longniddry_and_haddington_west"&gt;Map F&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Longniddry and Haddington West&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23130/map_g_haddington_east_and_surrounding_area"&gt;Map G&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Haddington East and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23133/map_h_east_linton_stenton_and_surrounding_area"&gt;Map H&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;East Linton, Stenton and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23129/map_j_dunbar_and_surrounding_area"&gt;Map J&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Dunbar and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23131/map_k_lnnerwick_and_surrounding_area"&gt;Map K&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Innerwick and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23132/map_l_musselburgh_south_and_whitecraig"&gt;Map L&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Musselburgh South and Whitecraig&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23134/map_m_tranent_south_macmerry_ormiston"&gt;Map M&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Tranent South, Macmerry, Ormiston&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23122/map_n_pencaitland_and_east_saltoun"&gt;Map N&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Pencaitland and East Saltoun&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23135/map_o_gifford_and_surrounding_area"&gt;Map O&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Gifford and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23125/map_p_garvald_and_surrounding_area"&gt;Map P&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Garvald and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23136/map_q_east_lammermuir_hills"&gt;Map Q&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;East Lammermuir Hills&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23138/map_r_oldhamstocks_and_surrounding_area"&gt;Map R&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Oldhamstocks and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23123/map_s_glenkinchie_and_south_west_area"&gt;Map S&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Glenkinchie and South West area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23139/map_t_humbie_and_surrounding_area"&gt;Map T&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Humbie and surrounding area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23140/map_u_western_lammermuir_hills"&gt;Map U&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Western Lammermuir Hills&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23124/map_v_central_lammermuir_hills"&gt;Map V&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Central Lammermuir Hills&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.eastlothian.gov.uk/downloads/file/23141/map_w_whiteadder_and_south_east_lammermuir_hills"&gt;Map W&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Whiteadder and South East Lammermuir Hills&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Aviemore&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.cairngormmountain.co.uk/"&gt;https://www.cairngormmountain.co.uk/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Rothiemurchus&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://rothiemurchus.net/outdoor-activities-at-aviemore/"&gt;https://rothiemurchus.net/outdoor-activities-at-aviemore/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Loch-an-Eilein: &lt;a href="https://rothiemurchus.net/visit/loch-an-eilein/"&gt;https://rothiemurchus.net/visit/loch-an-eilein/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Laggan Wolftrax&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://forestryandland.gov.scot/visit/laggan-wolftrax"&gt;https://forestryandland.gov.scot/visit/laggan-wolftrax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.cirrus.com/download/attachments/290193638/LagganWolftraxMap.pdf?version=1&amp;amp;modificationDate=1626943260000&amp;amp;api=v2"&gt;Laggan Wolftrax Map (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Insh Marshes Nature Reserve&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rspb.org.uk/reserves-and-events/reserves-a-z/insh-marshes/"&gt;https://www.rspb.org.uk/reserves-and-events/reserves-a-z/insh-marshes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rspb.org.uk/globalassets/downloads/documents/reserves/insh-marshes-trail-guide.pdf"&gt;Insh Marshes Trail Guide (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;North Ayrshire&lt;/h2&gt;
&lt;h2&gt;Arran&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.coastalway.co.uk/"&gt;Arran Coastal Way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.arranbikeclub.com/routes"&gt;Arran Bike Routes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Aberdeenshire&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.tarland-trails.com/"&gt;Tarland Trails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="Home &amp; Garden"></category><category term="Outdoors"></category><category term="Wildlife"></category><category term="Family"></category><category term="Garden"></category><category term="Bike"></category></entry><entry><title>tmux Training Manual: Ghostty, xterm and PVE LXC Terminals</title><link href="http://lizard-spock.co.uk/tmux-training-manual-ghostty-xterm-and-pve-lxc-terminals.html" rel="alternate"></link><published>2026-02-27T12:00:00+00:00</published><updated>2026-02-27T12:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-02-27:/tmux-training-manual-ghostty-xterm-and-pve-lxc-terminals.html</id><summary type="html">&lt;p&gt;tmux is a terminal multiplexer: it lets you run multiple terminal sessions inside a single window, split panes side by …&lt;/p&gt;</summary><content type="html">&lt;p&gt;tmux is a terminal multiplexer: it lets you run multiple terminal sessions inside a single window, split panes side by side, and crucially, keep sessions alive after you disconnect. For headless Proxmox VE (PVE) LXC containers accessed over SSH, this is essential. If your SSH connection drops mid-task, tmux keeps the job running and lets you reattach exactly where you left off. This manual walks through tmux in practical exercises, covering Ghostty on macOS, xterm, and terminal sessions inside PVE LXC containers.&lt;/p&gt;
&lt;h2&gt;Getting Back to a Known State&lt;/h2&gt;
&lt;p&gt;This section comes first because it is the most important concept to internalise. Just as pressing &lt;code&gt;Escape&lt;/code&gt; repeatedly in vim returns you to a safe state, tmux has equivalent recovery paths. Learn these before anything else.&lt;/p&gt;
&lt;h3&gt;The Prefix Key&lt;/h3&gt;
&lt;p&gt;Every tmux command starts with the &lt;strong&gt;prefix key&lt;/strong&gt;, which is &lt;code&gt;Ctrl+b&lt;/code&gt; by default. You press &lt;code&gt;Ctrl+b&lt;/code&gt;, release both keys, then press the command key. Nothing happens if you just hold &lt;code&gt;Ctrl+b&lt;/code&gt; without following up.&lt;/p&gt;
&lt;p&gt;If you press &lt;code&gt;Ctrl+b&lt;/code&gt; and then the wrong key, tmux usually just ignores it. You are not stuck.&lt;/p&gt;
&lt;h3&gt;Exiting Any Mode&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;How to exit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stuck in copy mode&lt;/td&gt;
&lt;td&gt;Press &lt;code&gt;q&lt;/code&gt; or &lt;code&gt;Escape&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stuck in command mode (&lt;code&gt;:&lt;/code&gt; prompt)&lt;/td&gt;
&lt;td&gt;Press &lt;code&gt;Escape&lt;/code&gt; or &lt;code&gt;Ctrl+c&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pane running something&lt;/td&gt;
&lt;td&gt;Press &lt;code&gt;Ctrl+c&lt;/code&gt; to interrupt it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Everything looks wrong&lt;/td&gt;
&lt;td&gt;Detach with &lt;code&gt;Ctrl+b d&lt;/code&gt; and reattach fresh&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Emergency Exit Sequences&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Detach from session (session keeps running):&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;List all sessions from outside tmux:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;ls
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Reattach to a named session:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;attach&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;session-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Reattach to the most recent session:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;attach
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Kill a specific pane (with confirmation prompt):&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Kill a specific window (with confirmation prompt):&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Kill a session entirely from the command line:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;session-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Kill all tmux sessions:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;kill-server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The pattern to remember: &lt;code&gt;Ctrl+b d&lt;/code&gt; detaches safely, &lt;code&gt;tmux ls&lt;/code&gt; shows what is running, and &lt;code&gt;tmux attach -t &amp;lt;name&amp;gt;&lt;/code&gt; gets you back. These three commands will rescue you from almost any situation.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;h3&gt;Debian and Ubuntu LXC Containers&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt&lt;span class="w"&gt; &lt;/span&gt;update
sudo&lt;span class="w"&gt; &lt;/span&gt;apt&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;tmux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;macOS (Ghostty Host)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;brew&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;tmux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Verify Installation&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;-V
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Expected output: &lt;code&gt;tmux 3.x&lt;/code&gt; (version 3.3a or later is common as of 2026).&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Terminal Compatibility Notes&lt;/h2&gt;
&lt;h3&gt;Ghostty&lt;/h3&gt;
&lt;p&gt;Ghostty works excellently with tmux. It supports true colour, full mouse reporting, and passes modifier keys correctly. No special configuration is needed.&lt;/p&gt;
&lt;p&gt;If colours look wrong inside tmux running in Ghostty, set this in your shell profile:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;TERM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xterm-256color
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or add this to &lt;code&gt;~/.tmux.conf&lt;/code&gt; to force 256 colour mode:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;default-terminal&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;screen-256color&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;xterm&lt;/h3&gt;
&lt;p&gt;xterm is a reliable fallback. It handles tmux correctly but defaults to a limited colour palette. Set the terminal type explicitly if you see rendering artefacts:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;TERM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xterm-256color&lt;span class="w"&gt; &lt;/span&gt;tmux
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or add to your shell profile permanently:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;TERM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xterm-256color
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;PVE LXC Console: noVNC vs SSH&lt;/h3&gt;
&lt;p&gt;PVE's web console (noVNC) can cause key capture problems with tmux. The &lt;code&gt;Ctrl+b&lt;/code&gt; prefix may not pass through correctly because the browser intercepts some key combinations. In practice, &lt;code&gt;Ctrl+b&lt;/code&gt; often works, but scrolling, mouse support, and certain modifier combinations behave inconsistently.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recommendation: always use SSH into the LXC for tmux work.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;user@&amp;lt;lxc-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;SSH gives you a proper PTY, correct terminal type negotiation, and reliable key forwarding. noVNC is fine for quick root access or emergency recovery, but not for regular tmux sessions.&lt;/p&gt;
&lt;p&gt;If you must use the PVE noVNC console with tmux, set a longer escape time to reduce timeout frustration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-sg&lt;span class="w"&gt; &lt;/span&gt;escape-time&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;Exercise 1: First Session&lt;/h2&gt;
&lt;p&gt;This exercise covers starting, using, detaching, and reattaching to a named session.&lt;/p&gt;
&lt;h3&gt;Start a Named Session&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;training
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You are now inside a tmux session called &lt;code&gt;training&lt;/code&gt;. The green (or coloured) bar at the bottom is the &lt;strong&gt;status bar&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Reading the Status Bar&lt;/h3&gt;
&lt;p&gt;The status bar shows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Left side: session name in brackets, e.g. &lt;code&gt;[training]&lt;/code&gt;, followed by window index and name, e.g. &lt;code&gt;0:bash&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Right side: hostname and time (depending on your config)&lt;/li&gt;
&lt;li&gt;An asterisk &lt;code&gt;*&lt;/code&gt; next to the current window name&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Run a Command&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;top
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Watch it run. Now detach without killing it.&lt;/p&gt;
&lt;h3&gt;Detach from the Session&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You are back at your normal shell prompt. The &lt;code&gt;top&lt;/code&gt; command is still running inside tmux.&lt;/p&gt;
&lt;h3&gt;Verify the Session is Still Running&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;ls
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;training: 1 windows (created Thu Feb 27 12:00:00 2026)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Reattach to the Session&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;attach&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;training
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You are back inside the session. &lt;code&gt;top&lt;/code&gt; is still running. Press &lt;code&gt;q&lt;/code&gt; to quit &lt;code&gt;top&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Recovery Notes for Exercise 1&lt;/h3&gt;
&lt;p&gt;If you lose track of session names, &lt;code&gt;tmux ls&lt;/code&gt; always shows what is running. If &lt;code&gt;tmux ls&lt;/code&gt; shows nothing, there are no sessions and you start fresh with &lt;code&gt;tmux new -s &amp;lt;name&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Exercise 2: Windows&lt;/h2&gt;
&lt;p&gt;Windows in tmux are like browser tabs. Each window fills the full terminal area and can run a different program.&lt;/p&gt;
&lt;h3&gt;Create a New Window&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b c
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A new window appears. The status bar now shows two windows: &lt;code&gt;0:bash&lt;/code&gt; and &lt;code&gt;1:bash&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Name the Current Window&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b ,
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A rename prompt appears at the bottom. Type a name, for example &lt;code&gt;logs&lt;/code&gt;, then press &lt;code&gt;Enter&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Switch Between Windows&lt;/h3&gt;
&lt;p&gt;Switch to window by number:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b 0
Ctrl+b 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Switch to next window:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b n
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Switch to previous window:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b p
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;List All Windows (Known State Check)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b w
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;An interactive list of all windows appears. Use arrow keys to navigate and &lt;code&gt;Enter&lt;/code&gt; to select. Press &lt;code&gt;Escape&lt;/code&gt; to cancel without switching. This gives you a clear view of what is open.&lt;/p&gt;
&lt;h3&gt;Close a Window&lt;/h3&gt;
&lt;p&gt;The cleanest way is to exit the shell:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or force close the current window (with confirmation):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Type &lt;code&gt;y&lt;/code&gt; to confirm. If you have multiple windows, tmux moves you to the next one. If it was the last window, the session ends.&lt;/p&gt;
&lt;h3&gt;Recovery Notes for Exercise 2&lt;/h3&gt;
&lt;p&gt;If you are confused about which window you are in, &lt;code&gt;Ctrl+b w&lt;/code&gt; shows the full list. If a window is running something stuck, &lt;code&gt;Ctrl+b &amp;amp;&lt;/code&gt; closes it after confirmation.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Exercise 3: Panes&lt;/h2&gt;
&lt;p&gt;Panes split a single window into multiple terminal areas visible at the same time.&lt;/p&gt;
&lt;h3&gt;Split Horizontally (Left and Right)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b %
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The window is now split into two vertical columns (left pane and right pane).&lt;/p&gt;
&lt;h3&gt;Split Vertically (Top and Bottom)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b &amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The current pane is split into two horizontal rows.&lt;/p&gt;
&lt;h3&gt;Navigate Between Panes&lt;/h3&gt;
&lt;p&gt;Use the prefix followed by an arrow key:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b &amp;lt;arrow key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For example, &lt;code&gt;Ctrl+b&lt;/code&gt; then the right arrow moves focus to the right pane.&lt;/p&gt;
&lt;h3&gt;Show Pane Numbers (Known State Check)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b q
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Large numbers appear briefly over each pane. Press the number while it is visible to jump to that pane directly.&lt;/p&gt;
&lt;h3&gt;Resize a Pane&lt;/h3&gt;
&lt;p&gt;Hold the prefix and then repeatedly press arrow keys. In most terminals:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b :resize-pane -D 5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This resizes the current pane down by 5 rows. Directions: &lt;code&gt;-U&lt;/code&gt; (up), &lt;code&gt;-D&lt;/code&gt; (down), &lt;code&gt;-L&lt;/code&gt; (left), &lt;code&gt;-R&lt;/code&gt; (right).&lt;/p&gt;
&lt;p&gt;Alternatively, if mouse mode is enabled (covered in the config section), you can drag pane borders.&lt;/p&gt;
&lt;h3&gt;Zoom a Pane to Full Screen&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b z
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The current pane expands to fill the entire window. Press &lt;code&gt;Ctrl+b z&lt;/code&gt; again to return to the split layout. The status bar shows &lt;code&gt;[Z]&lt;/code&gt; when a pane is zoomed.&lt;/p&gt;
&lt;h3&gt;Close a Pane&lt;/h3&gt;
&lt;p&gt;The cleanest way:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or force close with confirmation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Type &lt;code&gt;y&lt;/code&gt; to confirm. If it is the last pane in the window, the window closes too.&lt;/p&gt;
&lt;h3&gt;Recovery Notes for Exercise 3&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Ctrl+b q&lt;/code&gt; shows pane numbers so you can see where you are. &lt;code&gt;Ctrl+b z&lt;/code&gt; is useful if you accidentally zoomed and the layout looks wrong: toggle it again to return to the split view.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Exercise 4: Copy Mode (and How to Exit It)&lt;/h2&gt;
&lt;p&gt;Copy mode lets you scroll back through terminal output and copy text. Knowing how to exit it reliably is as important as knowing how to enter it.&lt;/p&gt;
&lt;h3&gt;Enter Copy Mode&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b [
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The status bar shows &lt;code&gt;[Copy]&lt;/code&gt; in the top right corner. You are now in copy mode.&lt;/p&gt;
&lt;h3&gt;Navigate in Copy Mode&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Arrow keys&lt;/td&gt;
&lt;td&gt;Move cursor one line/column&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PgUp&lt;/code&gt; / &lt;code&gt;PgDn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Scroll up or down a page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;g&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Go to the top of the scrollback buffer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;G&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Go to the bottom (current output)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;?&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search backward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Next search match&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;N&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Previous search match&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Exit Copy Mode&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Press &lt;code&gt;q&lt;/code&gt; or &lt;code&gt;Escape&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is the key thing to remember. If you are in copy mode and the terminal seems unresponsive to normal commands, you are still in copy mode. Press &lt;code&gt;q&lt;/code&gt; or &lt;code&gt;Escape&lt;/code&gt; to return to normal mode.&lt;/p&gt;
&lt;h3&gt;Copy Text&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Enter copy mode: &lt;code&gt;Ctrl+b [&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Navigate to the start of the text you want&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Space&lt;/code&gt; to begin selection&lt;/li&gt;
&lt;li&gt;Move to the end of the text&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Enter&lt;/code&gt; to copy and exit copy mode&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Paste Copied Text&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b ]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This pastes the tmux clipboard into the current pane at the cursor position.&lt;/p&gt;
&lt;h3&gt;Recovery Notes for Exercise 4&lt;/h3&gt;
&lt;p&gt;If your keyboard input is being swallowed and commands are not running, the most likely cause is that you are in copy mode. Press &lt;code&gt;q&lt;/code&gt; first, then &lt;code&gt;Escape&lt;/code&gt; if &lt;code&gt;q&lt;/code&gt; did not work.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Exercise 5: PVE LXC Workflow&lt;/h2&gt;
&lt;p&gt;This exercise demonstrates the core use case for tmux in a Proxmox VE environment: running long tasks in an LXC container and safely reconnecting after a disconnect.&lt;/p&gt;
&lt;h3&gt;Step 1: SSH into the LXC Container&lt;/h3&gt;
&lt;p&gt;From your workstation (Ghostty or any terminal):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;user@&amp;lt;lxc-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Replace &lt;code&gt;&amp;lt;lxc-ip&amp;gt;&lt;/code&gt; with the IP address of your LXC container. You can find this in the PVE web interface under the container's Network tab, or by running &lt;code&gt;ip a&lt;/code&gt; inside the container.&lt;/p&gt;
&lt;h3&gt;Step 2: Start a Persistent Session&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;work
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Step 3: Run a Long Job&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;apt&lt;span class="w"&gt; &lt;/span&gt;upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This may take several minutes. Let it run.&lt;/p&gt;
&lt;h3&gt;Step 4: Detach and Close SSH&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You are back at the container's shell prompt (outside tmux). Now close the SSH connection entirely:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or close the terminal window. The &lt;code&gt;apt upgrade&lt;/code&gt; is still running inside the tmux session on the LXC container.&lt;/p&gt;
&lt;h3&gt;Step 5: Reconnect and Reattach&lt;/h3&gt;
&lt;p&gt;Open a new terminal and SSH back in:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ssh&lt;span class="w"&gt; &lt;/span&gt;user@&amp;lt;lxc-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;List running sessions:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;ls
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;work: 1 windows (created Thu Feb 27 12:05:00 2026)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Reattach:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;attach&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;work
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You are back watching &lt;code&gt;apt upgrade&lt;/code&gt; complete, exactly as you left it.&lt;/p&gt;
&lt;h3&gt;Why tmux Beats GNU Screen for LXC Work&lt;/h3&gt;
&lt;p&gt;Both tmux and screen provide session persistence, but tmux has clearer defaults, better pane support, and easier scripting. The &lt;code&gt;tmux ls&lt;/code&gt; command gives a clean session overview. Pane splitting is built in without workarounds. Configuration via &lt;code&gt;~/.tmux.conf&lt;/code&gt; is straightforward. For new setups, start with tmux.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Quick Reference Table&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Key or Command&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;New named session&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux new -s &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run from shell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List sessions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux ls&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run from shell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Attach to session&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux attach -t &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run from shell&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detach from session&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Session keeps running&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New window&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rename window&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b ,&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch to window N&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b &amp;lt;N&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0-9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next window&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Previous window&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List windows&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b w&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Interactive picker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Close window&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b &amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Confirmation required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split pane left/right&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b %&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Split pane top/bottom&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b "&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Navigate panes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b &amp;lt;arrow&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show pane numbers&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b q&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zoom pane toggle&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b z&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Status bar shows [Z]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Close pane&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Confirmation required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enter copy mode&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b [&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exit copy mode&lt;/td&gt;
&lt;td&gt;&lt;code&gt;q&lt;/code&gt; or &lt;code&gt;Escape&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start selection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Space&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;While in copy mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copy selection&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Enter&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;While in copy mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Paste&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reload config&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl+b :source-file ~/.tmux.conf&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kill session&lt;/td&gt;
&lt;td&gt;&lt;code&gt;tmux kill-session -t &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Run from shell&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;Config Tweaks&lt;/h2&gt;
&lt;p&gt;tmux reads &lt;code&gt;~/.tmux.conf&lt;/code&gt; on startup. Create or edit this file to customise behaviour. Changes take effect in new sessions, or you can reload without restarting.&lt;/p&gt;
&lt;h3&gt;Location&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;~/.tmux.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Change the Prefix Key to Ctrl+a&lt;/h3&gt;
&lt;p&gt;Many users prefer &lt;code&gt;Ctrl+a&lt;/code&gt; because it is easier to reach and was the &lt;code&gt;screen&lt;/code&gt; default:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;unbind&lt;span class="w"&gt; &lt;/span&gt;C-b
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;prefix&lt;span class="w"&gt; &lt;/span&gt;C-a
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;C-a&lt;span class="w"&gt; &lt;/span&gt;send-prefix
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After this, all commands use &lt;code&gt;Ctrl+a&lt;/code&gt; instead of &lt;code&gt;Ctrl+b&lt;/code&gt;. The &lt;code&gt;bind C-a send-prefix&lt;/code&gt; line lets you type a literal &lt;code&gt;Ctrl+a&lt;/code&gt; in programs like bash by pressing the prefix twice.&lt;/p&gt;
&lt;h3&gt;Enable Mouse Support&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;mouse&lt;span class="w"&gt; &lt;/span&gt;on
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With mouse enabled, you can click to select panes, drag borders to resize, and scroll with the mouse wheel. Scroll wheel enters copy mode automatically. To exit copy mode after scrolling, press &lt;code&gt;q&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Increase Scrollback Buffer&lt;/h3&gt;
&lt;p&gt;The default scrollback is 2000 lines, which fills up quickly. Increase it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;history-limit&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Reduce Escape Time (Useful for PVE noVNC)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-sg&lt;span class="w"&gt; &lt;/span&gt;escape-time&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This reduces the delay tmux waits after pressing &lt;code&gt;Escape&lt;/code&gt; before deciding it is not a prefix sequence. Lower values make &lt;code&gt;Escape&lt;/code&gt; feel more responsive in vim and other tools inside tmux.&lt;/p&gt;
&lt;h3&gt;Start Window and Pane Index at 1&lt;/h3&gt;
&lt;p&gt;By default windows are numbered from 0. Starting at 1 maps better to the number keys:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;base-index&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
setw&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;pane-base-index&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Reload Config Without Restarting&lt;/h3&gt;
&lt;p&gt;After editing &lt;code&gt;~/.tmux.conf&lt;/code&gt;, reload it inside a running tmux session:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b :source-file ~/.tmux.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or add a keybinding for this in &lt;code&gt;~/.tmux.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;r&lt;span class="w"&gt; &lt;/span&gt;source-file&lt;span class="w"&gt; &lt;/span&gt;~/.tmux.conf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;display-message&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Config reloaded&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then use &lt;code&gt;Ctrl+b r&lt;/code&gt; (or &lt;code&gt;Ctrl+a r&lt;/code&gt; if you changed the prefix) to reload.&lt;/p&gt;
&lt;h3&gt;Minimal Recommended Config&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Change prefix to Ctrl+a&lt;/span&gt;
unbind&lt;span class="w"&gt; &lt;/span&gt;C-b
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;prefix&lt;span class="w"&gt; &lt;/span&gt;C-a
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;C-a&lt;span class="w"&gt; &lt;/span&gt;send-prefix

&lt;span class="c1"&gt;# Enable mouse&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;mouse&lt;span class="w"&gt; &lt;/span&gt;on

&lt;span class="c1"&gt;# Increase scrollback&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;history-limit&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;10000&lt;/span&gt;

&lt;span class="c1"&gt;# Reduce escape time&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-sg&lt;span class="w"&gt; &lt;/span&gt;escape-time&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;50&lt;/span&gt;

&lt;span class="c1"&gt;# Start numbering from 1&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;base-index&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
setw&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;pane-base-index&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# Reload config&lt;/span&gt;
&lt;span class="nb"&gt;bind&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;r&lt;span class="w"&gt; &lt;/span&gt;source-file&lt;span class="w"&gt; &lt;/span&gt;~/.tmux.conf&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;display-message&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Config reloaded&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;Known State Cheatsheet&lt;/h2&gt;
&lt;p&gt;Bookmark this section. When something goes wrong, work through it from top to bottom.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Exit any mode:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In copy mode: press &lt;code&gt;q&lt;/code&gt;, then &lt;code&gt;Escape&lt;/code&gt; if needed&lt;/li&gt;
&lt;li&gt;In command mode: press &lt;code&gt;Escape&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Program stuck: press &lt;code&gt;Ctrl+c&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. Check what windows and panes are open:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b w    (list windows)
Ctrl+b q    (show pane numbers)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;3. Detach safely (session keeps running):&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b d
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;4. From the shell, list all sessions:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;ls
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;5. Reattach to a session:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;attach&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;name&amp;gt;
tmux&lt;span class="w"&gt; &lt;/span&gt;attach&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;# most recent session&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;6. Kill a stuck pane:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b x    (confirmation prompt, then y)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;7. Kill a stuck window:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Ctrl+b &amp;amp;    (confirmation prompt, then y)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;8. Kill a session entirely:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;kill-session&lt;span class="w"&gt; &lt;/span&gt;-t&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;9. Nuclear option: kill all tmux sessions:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;kill-server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;10. Start fresh:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tmux&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Following this list top to bottom will resolve the vast majority of situations where tmux feels stuck or confusing. The core principle: &lt;code&gt;Ctrl+b d&lt;/code&gt; gets you out, &lt;code&gt;tmux ls&lt;/code&gt; shows what is there, and &lt;code&gt;tmux attach&lt;/code&gt; gets you back in.&lt;/p&gt;</content><category term="Unix &amp; Tools"></category><category term="tmux"></category><category term="Terminal"></category><category term="Ghostty"></category><category term="xterm"></category><category term="Proxmox"></category><category term="LXC"></category><category term="Linux"></category><category term="Vim"></category><category term="Bash"></category><category term="Ubuntu"></category></entry><entry><title>Installing Homebrew on a Debian 13 (Trixie) LXC Container</title><link href="http://lizard-spock.co.uk/installing-homebrew-on-a-debian-13-trixie-lxc-container.html" rel="alternate"></link><published>2026-02-25T00:00:00+00:00</published><updated>2026-02-25T00:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-02-25:/installing-homebrew-on-a-debian-13-trixie-lxc-container.html</id><summary type="html">&lt;p&gt;A verified step-by-step guide to installing Homebrew (Linuxbrew) on a Debian 13 "trixie" LXC unprivileged container, including group setup, prefix pre-creation, and multi-user configuration.&lt;/p&gt;</summary><content type="html">&lt;p&gt;This tutorial documents a working, verified installation of Homebrew (Linuxbrew) on a
Debian 13 "trixie" LXC container. Every step reflects what was actually done on this system;
nothing has been invented or copied from generic guides without verification.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tested environment:&lt;/strong&gt;
- Debian GNU/Linux 13 (trixie), amd64
- LXC unprivileged container
- Homebrew 5.0.15
- Primary non-root user: &lt;code&gt;morgan&lt;/code&gt; (uid=1000)&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#1-prerequisites"&gt;Prerequisites&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#2-installation-steps"&gt;Installation Steps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#3-per-user-shell-setup"&gt;Per-User Shell Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#4-verification"&gt;Verification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#5-adding-future-users"&gt;Adding Future Users&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#6-troubleshooting"&gt;Troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2&gt;1. Prerequisites&lt;/h2&gt;
&lt;h3&gt;System packages&lt;/h3&gt;
&lt;p&gt;The Homebrew installer requires these packages. Install them as root before running the
installer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;update
apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-y&lt;span class="w"&gt; &lt;/span&gt;build-essential&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;file&lt;span class="w"&gt; &lt;/span&gt;procps
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Verify all five are present:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;ii&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;essential&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m m-Double"&gt;12.12&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nx"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;Informational&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;essential&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;packages&lt;/span&gt;
&lt;span class="nx"&gt;ii&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;curl&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="m m-Double"&gt;8.14.1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;deb13u2&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nx"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;transferring&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;syntax&lt;/span&gt;
&lt;span class="nx"&gt;ii&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m m-Double"&gt;5.46&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="nx"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;Recognize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;magic&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;
&lt;span class="nx"&gt;ii&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;git&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m m-Double"&gt;2.47.3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;deb13u1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;fast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scalable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;distributed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;revision&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;control&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;
&lt;span class="nx"&gt;ii&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;procps&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m m-Double"&gt;4.0.4&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nx"&gt;amd64&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;proc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;utilities&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;PATH gotcha: /usr/sbin must be in root's PATH&lt;/h3&gt;
&lt;p&gt;On Debian 13, &lt;code&gt;/usr/sbin&lt;/code&gt; is &lt;strong&gt;not&lt;/strong&gt; automatically in the PATH of non-login shells (including
those invoked by &lt;code&gt;su&lt;/code&gt; without &lt;code&gt;-l&lt;/code&gt;). The installer calls &lt;code&gt;useradd&lt;/code&gt;, which lives at
&lt;code&gt;/usr/sbin/useradd&lt;/code&gt;. If &lt;code&gt;/usr/sbin&lt;/code&gt; is missing from your PATH the installer will fail with a
confusing "command not found" error.&lt;/p&gt;
&lt;p&gt;Before running the installer, confirm your PATH includes &lt;code&gt;/usr/sbin&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If it does not, prepend it for the session:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/usr/sbin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or simply run the installer from a full login shell (&lt;code&gt;su -&lt;/code&gt; rather than &lt;code&gt;su&lt;/code&gt;).&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. Installation Steps&lt;/h2&gt;
&lt;p&gt;All steps in this section are run as &lt;strong&gt;root&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Step 1 — Create the dedicated &lt;code&gt;linuxbrew&lt;/code&gt; group&lt;/h3&gt;
&lt;p&gt;Homebrew on Linux uses a shared group so that multiple users can write to the installation
prefix. Create it before the installer runs so you control its GID:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;groupadd&lt;span class="w"&gt; &lt;/span&gt;linuxbrew
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Step 2 — Pre-create the Homebrew prefix directory&lt;/h3&gt;
&lt;p&gt;The Homebrew installer expects to own &lt;code&gt;/home/linuxbrew/.linuxbrew&lt;/code&gt;. In an LXC container the
installer sometimes cannot create &lt;code&gt;/home/linuxbrew&lt;/code&gt; itself due to ownership constraints on
&lt;code&gt;/home&lt;/code&gt;. Pre-create it and set the correct ownership &lt;strong&gt;before&lt;/strong&gt; running the installer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew/.linuxbrew
chown&lt;span class="w"&gt; &lt;/span&gt;-R&lt;span class="w"&gt; &lt;/span&gt;morgan:linuxbrew&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew
chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2775&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew
chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2775&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew/.linuxbrew
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;2775&lt;/code&gt; mode sets the &lt;strong&gt;setgid bit&lt;/strong&gt; (&lt;code&gt;s&lt;/code&gt;) on the directory. This causes all files and
subdirectories created inside to inherit the &lt;code&gt;linuxbrew&lt;/code&gt; group automatically, which is what
allows multiple users to install and update packages.&lt;/p&gt;
&lt;p&gt;After this step, &lt;code&gt;ls -la /home/linuxbrew/&lt;/code&gt; should show:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;drwxrwxr-x  3 morgan linuxbrew 4096 Feb 25 15:31 .
drwxr-xr-x  4 root   root      4096 Feb 25 15:31 ..
drwxrwsr-x 14 morgan linuxbrew 4096 Feb 25 15:31 .linuxbrew
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And &lt;code&gt;stat /home/linuxbrew/.linuxbrew&lt;/code&gt; confirms the setgid bit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Access: (2775/drwxrwsr-x)  Uid: ( 1000/  morgan)   Gid: ( 1001/linuxbrew)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Step 3 — Add the primary user to the linuxbrew group&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;usermod&lt;span class="w"&gt; &lt;/span&gt;-aG&lt;span class="w"&gt; &lt;/span&gt;linuxbrew&lt;span class="w"&gt; &lt;/span&gt;morgan
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;-a&lt;/code&gt; flag is critical — without it &lt;code&gt;usermod -G&lt;/code&gt; &lt;strong&gt;replaces&lt;/strong&gt; all supplementary groups
instead of appending to them.&lt;/p&gt;
&lt;h3&gt;Step 4 — Run the Homebrew installer as the primary user&lt;/h3&gt;
&lt;p&gt;Switch to the non-root user and run the official installer. Do &lt;strong&gt;not&lt;/strong&gt; run it as root:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;su&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;morgan
/bin/bash&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;-fsSL&lt;span class="w"&gt; &lt;/span&gt;https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because the prefix directory already exists and is writable by the &lt;code&gt;linuxbrew&lt;/code&gt; group (and
&lt;code&gt;morgan&lt;/code&gt; is a member), the installer will populate it without needing to create it or change
system-level ownership.&lt;/p&gt;
&lt;h3&gt;Step 5 — Create the system-wide profile.d script&lt;/h3&gt;
&lt;p&gt;To activate Homebrew automatically for every user who logs in, create a shell script in
&lt;code&gt;/etc/profile.d/&lt;/code&gt; as root:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cat&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/profile.d/homebrew.sh&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt; &amp;#39;EOF&amp;#39;&lt;/span&gt;
&lt;span class="s"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="s"&gt;if [ -d &amp;quot;/home/linuxbrew/.linuxbrew&amp;quot; ]; then&lt;/span&gt;
&lt;span class="s"&gt;    eval &amp;quot;$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)&amp;quot;&lt;/span&gt;
&lt;span class="s"&gt;fi&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;/etc/profile.d/homebrew.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is exactly the file present on this system:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# /etc/profile.d/homebrew.sh&lt;/span&gt;
&lt;span class="c1"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/home/linuxbrew/.linuxbrew&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;/home/linuxbrew/.linuxbrew/bin/brew&lt;span class="w"&gt; &lt;/span&gt;shellenv&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;if&lt;/code&gt; guard makes the script safe on systems where the prefix does not exist (e.g., before
installation, or if the directory is removed).&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. Per-User Shell Setup&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;/etc/profile.d/homebrew.sh&lt;/code&gt; script runs automatically for &lt;strong&gt;login shells&lt;/strong&gt;. This covers
&lt;code&gt;su - username&lt;/code&gt;, SSH logins, and console logins.&lt;/p&gt;
&lt;p&gt;For interactive non-login shells (e.g., a new terminal tab that sources &lt;code&gt;~/.bashrc&lt;/code&gt; instead of
&lt;code&gt;~/.bash_profile&lt;/code&gt;), a user may need to add the following to their &lt;code&gt;~/.bashrc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Homebrew (Linuxbrew)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/home/linuxbrew/.linuxbrew&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;/home/linuxbrew/.linuxbrew/bin/brew&lt;span class="w"&gt; &lt;/span&gt;shellenv&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;brew shellenv&lt;/code&gt; sets these environment variables:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HOMEBREW_PREFIX&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/home/linuxbrew/.linuxbrew&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HOMEBREW_CELLAR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/home/linuxbrew/.linuxbrew/Cellar&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HOMEBREW_REPOSITORY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/home/linuxbrew/.linuxbrew/Homebrew&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PATH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;prepends &lt;code&gt;/home/linuxbrew/.linuxbrew/bin&lt;/code&gt; and &lt;code&gt;.../sbin&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;MANPATH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;prepends &lt;code&gt;.../share/man&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;INFOPATH&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;prepends &lt;code&gt;.../share/info&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;4. Verification&lt;/h2&gt;
&lt;h3&gt;Confirm the installation prefix layout&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ls&lt;span class="w"&gt; &lt;/span&gt;-la&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew/.linuxbrew/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Expected output (all entries owned by &lt;code&gt;morgan:linuxbrew&lt;/code&gt;, setgid &lt;code&gt;s&lt;/code&gt; visible):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;56&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;drwxrwxr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Caskroom&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cellar&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Frameworks&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Homebrew&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sbin&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;share&lt;/span&gt;
&lt;span class="n"&gt;drwxrwsr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morgan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;linuxbrew&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Feb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;31&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;var&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Check the Homebrew version&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;su&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;morgan&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;brew --version&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Homebrew 5.0.15
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Run brew doctor&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;su&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;morgan&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;brew doctor&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Your system is ready to brew.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Confirm group membership&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;getent&lt;span class="w"&gt; &lt;/span&gt;group&lt;span class="w"&gt; &lt;/span&gt;linuxbrew
&lt;span class="c1"&gt;# linuxbrew:x:1001:morgan&lt;/span&gt;

id&lt;span class="w"&gt; &lt;/span&gt;morgan
&lt;span class="c1"&gt;# uid=1000(morgan) gid=1000(morgan) groups=1000(morgan),100(users),1001(linuxbrew)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Test installing a package (dry run)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;su&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;morgan&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;brew install --dry-run hello&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;==&amp;gt; Would install 1 formula:
hello
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;5. Adding Future Users&lt;/h2&gt;
&lt;p&gt;When a new user needs Homebrew access:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# As root — add the new user to the linuxbrew group&lt;/span&gt;
usermod&lt;span class="w"&gt; &lt;/span&gt;-aG&lt;span class="w"&gt; &lt;/span&gt;linuxbrew&lt;span class="w"&gt; &lt;/span&gt;newuser
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The user must log out and back in (or start a new login shell) for the group change to take
effect. The &lt;code&gt;/etc/profile.d/homebrew.sh&lt;/code&gt; script will activate &lt;code&gt;brew&lt;/code&gt; for them automatically
on their next login. No other changes are needed.&lt;/p&gt;
&lt;p&gt;To verify the new user can reach Homebrew:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;su&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;newuser&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;brew --version&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;hr&gt;
&lt;h2&gt;6. Troubleshooting&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;brew: command not found&lt;/code&gt; in a non-login shell&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;/etc/profile.d/homebrew.sh&lt;/code&gt; script only runs in login shells. In a non-login shell
(typical terminal emulators, &lt;code&gt;su username&lt;/code&gt; without the &lt;code&gt;-&lt;/code&gt;), Homebrew will not be on the PATH.&lt;/p&gt;
&lt;p&gt;Fix: source the script manually, or add the &lt;code&gt;eval&lt;/code&gt; line to &lt;code&gt;~/.bashrc&lt;/code&gt; as shown in
&lt;a href="#3-per-user-shell-setup"&gt;Section 3&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Quick test — if this works but &lt;code&gt;brew&lt;/code&gt; does not:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/home/linuxbrew/.linuxbrew/bin/brew&lt;span class="w"&gt; &lt;/span&gt;--version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;then the issue is purely PATH/environment, not the installation.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;useradd: command not found&lt;/code&gt; during installation&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;useradd&lt;/code&gt; lives at &lt;code&gt;/usr/sbin/useradd&lt;/code&gt;. On Debian 13, &lt;code&gt;/usr/sbin&lt;/code&gt; is not in the PATH of
non-login root shells. Run the installer from a full login shell:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;su&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# note the hyphen — this gives a login shell with /usr/sbin in PATH&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or prepend it explicitly before running the installer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/usr/sbin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Installer fails to create &lt;code&gt;/home/linuxbrew&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;In LXC containers, the installer may not be able to create the prefix directory itself because
&lt;code&gt;/home&lt;/code&gt; is owned by &lt;code&gt;root:root&lt;/code&gt; with mode &lt;code&gt;755&lt;/code&gt;. The installer does not have write access to
&lt;code&gt;/home&lt;/code&gt; when running as a non-root user.&lt;/p&gt;
&lt;p&gt;Solution: pre-create the directory as root before running the installer (see
&lt;a href="#step-2--pre-create-the-homebrew-prefix-directory"&gt;Step 2&lt;/a&gt;).&lt;/p&gt;
&lt;h3&gt;Permission denied errors when running &lt;code&gt;brew install&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The user must be in the &lt;code&gt;linuxbrew&lt;/code&gt; group &lt;strong&gt;and&lt;/strong&gt; must have started a new session after being
added. Check:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;id&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;# linuxbrew should appear in the groups list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;linuxbrew&lt;/code&gt; is absent, either the &lt;code&gt;usermod -aG linuxbrew username&lt;/code&gt; step was skipped, or
the user has not logged out and back in since being added.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;brew doctor&lt;/code&gt; reports warnings about &lt;code&gt;/usr/local&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;On Linux, Homebrew uses &lt;code&gt;/home/linuxbrew/.linuxbrew&lt;/code&gt; as its prefix, not &lt;code&gt;/usr/local&lt;/code&gt;. Warnings
about &lt;code&gt;/usr/local&lt;/code&gt; being absent or not owned by the current user are normal and harmless on a
Linux installation.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Quick-Reference: Full Root-Side Install Sequence&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# 1. Install dependencies&lt;/span&gt;
apt-get&lt;span class="w"&gt; &lt;/span&gt;update&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;apt-get&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-y&lt;span class="w"&gt; &lt;/span&gt;build-essential&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;curl&lt;span class="w"&gt; &lt;/span&gt;file&lt;span class="w"&gt; &lt;/span&gt;procps

&lt;span class="c1"&gt;# 2. Ensure /usr/sbin is in PATH (run as login shell or set manually)&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/usr/sbin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Create the linuxbrew group&lt;/span&gt;
groupadd&lt;span class="w"&gt; &lt;/span&gt;linuxbrew

&lt;span class="c1"&gt;# 4. Pre-create the prefix and set ownership/permissions&lt;/span&gt;
mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew/.linuxbrew
chown&lt;span class="w"&gt; &lt;/span&gt;-R&lt;span class="w"&gt; &lt;/span&gt;morgan:linuxbrew&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew
chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2775&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew
chmod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2775&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/home/linuxbrew/.linuxbrew

&lt;span class="c1"&gt;# 5. Add the primary user to the group&lt;/span&gt;
usermod&lt;span class="w"&gt; &lt;/span&gt;-aG&lt;span class="w"&gt; &lt;/span&gt;linuxbrew&lt;span class="w"&gt; &lt;/span&gt;morgan

&lt;span class="c1"&gt;# 6. Run the installer as the non-root user&lt;/span&gt;
su&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;morgan&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/bin/bash -c &amp;quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&amp;quot;&amp;#39;&lt;/span&gt;

&lt;span class="c1"&gt;# 7. Install the system-wide profile.d activation script&lt;/span&gt;
cat&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;/etc/profile.d/homebrew.sh&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt; &amp;#39;EOF&amp;#39;&lt;/span&gt;
&lt;span class="s"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="s"&gt;if [ -d &amp;quot;/home/linuxbrew/.linuxbrew&amp;quot; ]; then&lt;/span&gt;
&lt;span class="s"&gt;    eval &amp;quot;$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)&amp;quot;&lt;/span&gt;
&lt;span class="s"&gt;fi&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
chmod&lt;span class="w"&gt; &lt;/span&gt;+x&lt;span class="w"&gt; &lt;/span&gt;/etc/profile.d/homebrew.sh

&lt;span class="c1"&gt;# 8. Verify&lt;/span&gt;
su&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;morgan&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;brew --version &amp;amp;&amp;amp; brew doctor&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Hardware &amp; Homelab"></category><category term="Homebrew"></category><category term="Linux"></category><category term="Debian"></category><category term="LXC"></category><category term="Proxmox"></category><category term="Git"></category><category term="Bash"></category></entry><entry><title>FSM Diagrams in Pelican and Claude Code</title><link href="http://lizard-spock.co.uk/fsm-diagrams-in-pelican-and-claude-code.html" rel="alternate"></link><published>2026-02-22T18:00:00+00:00</published><updated>2026-02-22T18:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-02-22:/fsm-diagrams-in-pelican-and-claude-code.html</id><summary type="html">&lt;p&gt;Finite state machines turn up everywhere: protocol implementations, hardware controllers, UI flows, parsers. Drawing them well is useful but tedious …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Finite state machines turn up everywhere: protocol implementations, hardware controllers, UI flows, parsers. Drawing them well is useful but tedious. This post covers two tools I've built: a Pelican plugin that renders FSM diagrams at build time so they appear as images in published posts, and a Claude Code skill that generates diagrams from plain-English descriptions.&lt;/p&gt;
&lt;p&gt;The pattern is identical to the &lt;a href="http://lizard-spock.co.uk/wavedrom-timing-diagrams-in-pelican-with-claude-code.html"&gt;WaveDrom plugin and skill&lt;/a&gt;: describe what you want, get a fenced code block, paste it into a post, and the build renders it to SVG automatically.&lt;/p&gt;
&lt;h2&gt;The Pelican plugin&lt;/h2&gt;
&lt;p&gt;The plugin is at &lt;a href="https://github.com/morganp/pelican-fsm"&gt;github.com/morganp/pelican-fsm&lt;/a&gt;, cloned to &lt;code&gt;~/Code/pelican-fsm&lt;/code&gt; (a sibling directory to the blog repo). It intercepts fenced &lt;code&gt;```mermaid ```&lt;/code&gt; and &lt;code&gt;```dot ```&lt;/code&gt; code blocks before Pelican's standard Markdown processing, renders each one to an SVG using the appropriate CLI tool, caches the result by content hash in &lt;code&gt;content/images/fsm/&lt;/code&gt;, and replaces the block with a standard image reference. Pelican then copies the SVG to &lt;code&gt;output/images/fsm/&lt;/code&gt; as a static asset.&lt;/p&gt;
&lt;p&gt;SVGs are cached across builds, so only diagrams whose source has changed are re-rendered.&lt;/p&gt;
&lt;h3&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mermaid-js/mermaid-cli"&gt;Mermaid CLI&lt;/a&gt; for &lt;code&gt;mermaid&lt;/code&gt; blocks:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;npm&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;@mermaid-js/mermaid-cli
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://graphviz.org/"&gt;Graphviz&lt;/a&gt; for &lt;code&gt;dot&lt;/code&gt; blocks:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;brew&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;graphviz&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;# macOS&lt;/span&gt;
sudo&lt;span class="w"&gt; &lt;/span&gt;apt&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;graphviz&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# Debian/Ubuntu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Both tools are optional. If one is missing, blocks for that type fall back gracefully to a fenced &lt;code&gt;text&lt;/code&gt; block without failing the build.&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;Clone the plugin alongside your Pelican project and install it into the Pelican virtualenv in editable mode:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/morganp/pelican-fsm&lt;span class="w"&gt; &lt;/span&gt;../pelican-fsm
&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;venv/bin/activate
pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;../pelican-fsm&lt;span class="w"&gt; &lt;/span&gt;--config-settings&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;editable_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;compat
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;editable_mode=compat&lt;/code&gt; flag is required. Without it, modern setuptools editable installs use a path-hook mechanism that prevents Pelican's namespace plugin auto-discovery from finding the plugin.&lt;/p&gt;
&lt;p&gt;Pelican 4.5+ auto-discovers namespace plugins, so no changes to &lt;code&gt;pelicanconf.py&lt;/code&gt; are needed.&lt;/p&gt;
&lt;h3&gt;Optional config&lt;/h3&gt;
&lt;p&gt;If &lt;code&gt;mmdc&lt;/code&gt; or &lt;code&gt;dot&lt;/code&gt; are not on your &lt;code&gt;PATH&lt;/code&gt; during the build, set their full paths in &lt;code&gt;pelicanconf.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;FSM_MERMAID_CLI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/opt/homebrew/bin/mmdc&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;FSM_DOT_CLI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/opt/homebrew/bin/dot&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Using it in a post&lt;/h3&gt;
&lt;p&gt;Write a fenced code block with the language set to &lt;code&gt;mermaid&lt;/code&gt; or &lt;code&gt;dot&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="sb"&gt;```mermaid&lt;/span&gt;
&lt;span class="s"&gt;stateDiagram-v2&lt;/span&gt;
&lt;span class="s"&gt;    [*] --&amp;gt; Idle&lt;/span&gt;
&lt;span class="s"&gt;    Idle --&amp;gt; Running : start&lt;/span&gt;
&lt;span class="s"&gt;    Running --&amp;gt; Idle : stop&lt;/span&gt;
&lt;span class="s"&gt;    Running --&amp;gt; Error : fault&lt;/span&gt;
&lt;span class="s"&gt;    Error --&amp;gt; Idle : reset&lt;/span&gt;
&lt;span class="sb"&gt;```&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At build time this becomes an SVG embedded in the page:&lt;/p&gt;
&lt;p&gt;&lt;img alt="FSM diagram" src="http://lizard-spock.co.uk/images/fsm/fsm_ea7d29ca092a08571aa2cfe0ccc1600b.svg"&gt;&lt;/p&gt;
&lt;p&gt;Graphviz DOT works the same way, and is a better fit for hardware and RTL documentation where the compact box-and-arrow style is conventional:&lt;/p&gt;
&lt;p&gt;&lt;img alt="FSM diagram" src="http://lizard-spock.co.uk/images/fsm/fsm_d33619e8d6e9ae49f343c57a8f6db1e1.svg"&gt;&lt;/p&gt;
&lt;p&gt;If the CLI is not found or rendering fails, the block falls back to fenced &lt;code&gt;text&lt;/code&gt; — the post still builds, you just see the raw source instead of a diagram.&lt;/p&gt;
&lt;h2&gt;The Claude Code skill&lt;/h2&gt;
&lt;p&gt;The skill lives at &lt;a href="https://github.com/morganp/dotfiles/tree/main/config/claude/skills/fsm"&gt;github.com/morganp/dotfiles/tree/main/config/claude/skills/fsm&lt;/a&gt;. Claude Code auto-discovers skills from &lt;code&gt;~/.claude/skills/&lt;/code&gt; and loads them on demand.&lt;/p&gt;
&lt;p&gt;The skill triggers automatically when you describe anything involving states, transitions, or control flow: protocol implementations, UI flows, hardware FSMs, parsers, game logic. You describe the system in plain English and Claude generates the diagram.&lt;/p&gt;
&lt;p&gt;The skill knows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full Mermaid &lt;code&gt;stateDiagram-v2&lt;/code&gt; syntax: plain states, display labels, transitions with events/guards/actions, composite (nested) states, choice pseudostates, fork/join for parallel regions, concurrent regions (&lt;code&gt;--&lt;/code&gt;), notes, direction, and classDef styling&lt;/li&gt;
&lt;li&gt;Graphviz DOT FSM conventions: Moore vs Mealy annotation, initial pseudostate arrow, accepting states as double circles&lt;/li&gt;
&lt;li&gt;When to prefer each format: Mermaid for software/web docs, DOT for hardware/RTL&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Example workflow&lt;/h3&gt;
&lt;p&gt;Describe the system:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Draw the states for a TCP connection"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Claude produces:&lt;/p&gt;
&lt;p&gt;&lt;img alt="FSM diagram" src="http://lizard-spock.co.uk/images/fsm/fsm_03bf39c43e71e98bd12e737558c3f9e3.svg"&gt;&lt;/p&gt;
&lt;p&gt;Because the skill outputs a &lt;code&gt;mermaid&lt;/code&gt; fenced block, you can paste it directly into a blog post and the Pelican plugin renders it automatically.&lt;/p&gt;
&lt;h3&gt;Installing the skill&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;~/.claude/skills/fsm
curl&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;~/.claude/skills/fsm/SKILL.md&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;https://raw.githubusercontent.com/morganp/dotfiles/main/config/claude/skills/fsm/SKILL.md
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or clone the dotfiles repo and symlink:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/morganp/dotfiles&lt;span class="w"&gt; &lt;/span&gt;~/dotfiles
ln&lt;span class="w"&gt; &lt;/span&gt;-s&lt;span class="w"&gt; &lt;/span&gt;~/dotfiles/config/claude/skills/fsm&lt;span class="w"&gt; &lt;/span&gt;~/.claude/skills/fsm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Syntax quick reference&lt;/h2&gt;
&lt;p&gt;Both formats can express the same FSM concepts, but use different syntax. The table below maps them side by side.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;Mermaid &lt;code&gt;stateDiagram-v2&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;Graphviz DOT&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Graph declaration&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stateDiagram-v2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;digraph FSM { ... }&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default node style&lt;/td&gt;
&lt;td&gt;automatic&lt;/td&gt;
&lt;td&gt;&lt;code&gt;node [shape=circle]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Left-to-right layout&lt;/td&gt;
&lt;td&gt;&lt;code&gt;direction LR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rankdir=LR&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comment&lt;/td&gt;
&lt;td&gt;&lt;code&gt;%% comment&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;// comment&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plain state&lt;/td&gt;
&lt;td&gt;&lt;code&gt;StateName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;StateName&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State with display label&lt;/td&gt;
&lt;td&gt;&lt;code&gt;state "Label" as Name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Name [label="Label"]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Initial pseudostate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[*] --&amp;gt; State&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;__start [shape=point width=0.2]&lt;/code&gt; + &lt;code&gt;__start -&amp;gt; State&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Final/accepting state&lt;/td&gt;
&lt;td&gt;&lt;code&gt;State --&amp;gt; [*]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;State [shape=doublecircle]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transition&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A --&amp;gt; B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A -&amp;gt; B&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transition with event&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A --&amp;gt; B : event&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A -&amp;gt; B [label="event"]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transition with action&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A --&amp;gt; B : event / action()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A -&amp;gt; B [label="event / action()"]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guarded transition&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A --&amp;gt; B : [guard]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;A -&amp;gt; B [label="[guard]"]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Composite (nested) state&lt;/td&gt;
&lt;td&gt;&lt;code&gt;state S { ... }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;subgraph cluster_S { ... }&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Choice pseudostate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;state C &amp;lt;&amp;lt;choice&amp;gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C [shape=diamond]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fork pseudostate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;state F &amp;lt;&amp;lt;fork&amp;gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;invisible node + multiple outgoing edges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Join pseudostate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;state J &amp;lt;&amp;lt;join&amp;gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;invisible node + multiple incoming edges&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concurrent regions&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--&lt;/code&gt; inside composite&lt;/td&gt;
&lt;td&gt;parallel &lt;code&gt;subgraph&lt;/code&gt; blocks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Project structure&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morganp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="c1"&gt;# blog source (main branch)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsm&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;# SVG cache (persists across make clean)&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pelican&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fsm&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="c1"&gt;# github.com/morganp/pelican-fsm&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pelican&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fsm_renderer&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c1"&gt;# plugin entry point, signal registration&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;preprocessor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="c1"&gt;# Markdown extension + preprocessor&lt;/span&gt;

&lt;span class="o"&gt;~/.&lt;/span&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;skills&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fsm&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SKILL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="c1"&gt;# Claude Code skill definition&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The combination is useful for any documentation that involves control flow: describe the behaviour, get the diagram from Claude, drop it into a post, and the plugin renders it at build time. No manual editing of diagram syntax, no copy-pasting between browser tabs.&lt;/p&gt;</content><category term="Engineering"></category><category term="FSM"></category><category term="Pelican"></category><category term="Mermaid"></category><category term="Graphviz"></category><category term="claude"></category><category term="ai"></category><category term="Python"></category><category term="Git"></category><category term="Bash"></category><category term="Homebrew"></category><category term="Ubuntu"></category><category term="RTL"></category></entry><entry><title>Verilog Lint Skill for Claude Code</title><link href="http://lizard-spock.co.uk/verilog-lint-skill-for-claude-code.html" rel="alternate"></link><published>2026-02-22T12:00:00+00:00</published><updated>2026-02-22T12:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-02-22:/verilog-lint-skill-for-claude-code.html</id><summary type="html">&lt;p&gt;I've been using Claude Code for RTL generation lately, and the missing piece was a tight feedback loop between code …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I've been using Claude Code for RTL generation lately, and the missing piece was a tight feedback loop between code generation and linting. Writing Verilog by hand is tedious; having Claude generate it and immediately validate it with real tools closes that gap nicely.&lt;/p&gt;
&lt;h2&gt;What it does&lt;/h2&gt;
&lt;p&gt;The skill connects two open-source linters into an agentic write → lint → fix → re-lint loop:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Verilator&lt;/strong&gt; (&lt;code&gt;--lint-only -Wall&lt;/code&gt;) catches semantic errors: undeclared signals, bit-width mismatches, blocking assignments in &lt;code&gt;always_ff&lt;/code&gt; blocks, multi-driven nets&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Verible&lt;/strong&gt; (&lt;code&gt;verible-verilog-lint&lt;/code&gt;) enforces style: naming conventions, whitespace, port alignment, &lt;code&gt;always_ff&lt;/code&gt;/&lt;code&gt;always_comb&lt;/code&gt; discipline&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When Claude generates RTL, the skill automatically:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Writes the code to a temp file&lt;/li&gt;
&lt;li&gt;Runs both linters&lt;/li&gt;
&lt;li&gt;Parses error messages with line numbers&lt;/li&gt;
&lt;li&gt;Applies fixes and re-lints — up to 3 times&lt;/li&gt;
&lt;li&gt;Reports clean status or surfaces a diagnostic table if errors remain&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Why two tools&lt;/h2&gt;
&lt;p&gt;They complement each other. Verilator thinks like a synthesizer — it catches things that will fail elaboration or produce incorrect silicon. Verible doesn't simulate; it reads the source and checks against Google's SystemVerilog style guide. Together they cover both "will this work" and "is this readable".&lt;/p&gt;
&lt;h2&gt;Both are free and open source&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Verilator: &lt;code&gt;brew install verilator&lt;/code&gt; / &lt;code&gt;apt install verilator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Verible: &lt;code&gt;brew tap chipsalliance/verible &amp;amp;&amp;amp; brew install verible&lt;/code&gt; (macOS), or grab a binary from the &lt;a href="https://github.com/chipsalliance/verible/releases"&gt;GitHub releases page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;RTL patterns baked in&lt;/h2&gt;
&lt;p&gt;The skill includes reference patterns for mistake-free SystemVerilog: synchronous-reset flip-flops, &lt;code&gt;always_comb&lt;/code&gt; combinational blocks, parameterized FSMs with &lt;code&gt;typedef enum&lt;/code&gt;. Claude defaults to these when generating new modules, which avoids most of the common lint warnings before the first pass even runs.&lt;/p&gt;
&lt;h2&gt;Same pattern as WaveDrom&lt;/h2&gt;
&lt;p&gt;This follows the same skill format as the &lt;a href="http://lizard-spock.co.uk/wavedrom-timing-diagrams-in-pelican-with-claude-code.html"&gt;WaveDrom timing diagram skill&lt;/a&gt; — a &lt;code&gt;SKILL.md&lt;/code&gt; file that gives Claude structured instructions, reference tables, and workflow steps. Both skills live in &lt;code&gt;~/.claude/skills/&lt;/code&gt; and are picked up automatically by Claude Code.&lt;/p&gt;
&lt;p&gt;The combination is handy for hardware work: describe a protocol, get a timing diagram, then generate and lint the RTL that implements it.&lt;/p&gt;</content><category term="Engineering"></category><category term="Verilog"></category><category term="SystemVerilog"></category><category term="RTL"></category><category term="claude"></category><category term="ai"></category><category term="Hardware"></category><category term="Linting"></category></entry><entry><title>WaveDrom Timing Diagrams in Pelican with Claude Code</title><link href="http://lizard-spock.co.uk/wavedrom-timing-diagrams-in-pelican-with-claude-code.html" rel="alternate"></link><published>2026-02-20T12:00:00+00:00</published><updated>2026-02-20T12:00:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2026-02-20:/wavedrom-timing-diagrams-in-pelican-with-claude-code.html</id><summary type="html">&lt;p&gt;&lt;a href="https://wavedrom.com"&gt;WaveDrom&lt;/a&gt; is a JavaScript library that renders digital timing diagrams from a simple JSON-based format called WaveJSON. It's widely used …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="https://wavedrom.com"&gt;WaveDrom&lt;/a&gt; is a JavaScript library that renders digital timing diagrams from a simple JSON-based format called WaveJSON. It's widely used in hardware documentation — you describe signal transitions in a compact string notation, and WaveDrom draws the waveform. This post covers two tools I've built around it: a Pelican plugin that renders diagrams at build time, and a Claude Code skill that generates WaveJSON from plain English.&lt;/p&gt;
&lt;h2&gt;The Pelican plugin&lt;/h2&gt;
&lt;p&gt;The plugin is at &lt;a href="https://github.com/morganp/pelican-wavedrom"&gt;github.com/morganp/pelican-wavedrom&lt;/a&gt;, cloned to &lt;code&gt;~/Code/pelican-wavedrom&lt;/code&gt; — a sibling directory to the blog repo. It intercepts fenced &lt;code&gt;```wavedrom ```&lt;/code&gt; code blocks before Pelican's standard Markdown processing, renders each one to an SVG using &lt;code&gt;wavedrom-cli&lt;/code&gt;, caches the result by content hash in &lt;code&gt;content/images/wavedrom/&lt;/code&gt;, and replaces the block with a standard image reference. Pelican then copies the SVG to &lt;code&gt;output/images/wavedrom/&lt;/code&gt; as a static asset.&lt;/p&gt;
&lt;p&gt;SVGs are cached across builds — only diagrams whose source has changed are re-rendered.&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;The plugin requires &lt;code&gt;wavedrom-cli&lt;/code&gt; globally via npm:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;npm&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-g&lt;span class="w"&gt; &lt;/span&gt;wavedrom-cli
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then clone the plugin alongside your blog repo and install it into the Pelican virtualenv in editable mode:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://github.com/morganp/pelican-wavedrom&lt;span class="w"&gt; &lt;/span&gt;../pelican-wavedrom
&lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;venv/bin/activate
pip&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;../pelican-wavedrom&lt;span class="w"&gt; &lt;/span&gt;--config-settings&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;editable_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;compat
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;editable_mode=compat&lt;/code&gt; flag is required. Without it, modern setuptools editable installs use a path-hook mechanism that prevents Pelican's namespace plugin auto-discovery from finding the plugin.&lt;/p&gt;
&lt;p&gt;Pelican 4.5+ auto-discovers namespace plugins — no changes to &lt;code&gt;pelicanconf.py&lt;/code&gt; are needed.&lt;/p&gt;
&lt;h3&gt;Optional config&lt;/h3&gt;
&lt;p&gt;If &lt;code&gt;wavedrom-cli&lt;/code&gt; is not on your &lt;code&gt;PATH&lt;/code&gt; during the build (e.g. in a CI environment), set its full path in &lt;code&gt;pelicanconf.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;WAVEDROM_CLI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/opt/homebrew/bin/wavedrom-cli&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Using it in a post&lt;/h3&gt;
&lt;p&gt;Write a fenced code block with the language set to &lt;code&gt;wavedrom&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="sb"&gt;```wavedrom&lt;/span&gt;
&lt;span class="s"&gt;{ &amp;quot;signal&amp;quot;: [&lt;/span&gt;
&lt;span class="s"&gt;  { &amp;quot;name&amp;quot;: &amp;quot;CLK&amp;quot;,     &amp;quot;wave&amp;quot;: &amp;quot;p.....|...&amp;quot; },&lt;/span&gt;
&lt;span class="s"&gt;  { &amp;quot;name&amp;quot;: &amp;quot;Data&amp;quot;,    &amp;quot;wave&amp;quot;: &amp;quot;x.345x|=.x&amp;quot;, &amp;quot;data&amp;quot;: [&amp;quot;head&amp;quot;, &amp;quot;body&amp;quot;, &amp;quot;tail&amp;quot;, &amp;quot;data&amp;quot;] },&lt;/span&gt;
&lt;span class="s"&gt;  { &amp;quot;name&amp;quot;: &amp;quot;Request&amp;quot;, &amp;quot;wave&amp;quot;: &amp;quot;0.1..0|1.0&amp;quot; }&lt;/span&gt;
&lt;span class="s"&gt;]}&lt;/span&gt;
&lt;span class="sb"&gt;```&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At build time (&lt;code&gt;make html&lt;/code&gt; or &lt;code&gt;make github&lt;/code&gt;) this becomes an SVG embedded in the page:&lt;/p&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_da1bb22d431f672f9f36b629cf1f4152.svg"&gt;&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;wavedrom-cli&lt;/code&gt; is not found or rendering fails, the block falls back to a fenced &lt;code&gt;json&lt;/code&gt; block — the post still builds, you just see the raw JSON instead of a diagram.&lt;/p&gt;
&lt;h2&gt;The Claude Code skill&lt;/h2&gt;
&lt;p&gt;The skill lives at &lt;code&gt;~/.claude/skills/wavedrom/SKILL.md&lt;/code&gt;. Claude Code auto-discovers skills from &lt;code&gt;~/.claude/skills/&lt;/code&gt; and loads them on demand.&lt;/p&gt;
&lt;p&gt;The skill triggers automatically when you describe anything related to timing diagrams, waveforms, or digital protocols — SPI, I2C, UART, AXI handshakes, clock enables, request/acknowledge patterns. You describe the signals in plain English; Claude generates the WaveJSON.&lt;/p&gt;
&lt;p&gt;The skill includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The full WaveJSON wave-character reference (&lt;code&gt;p&lt;/code&gt;, &lt;code&gt;n&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;z&lt;/code&gt;, &lt;code&gt;.&lt;/code&gt;, &lt;code&gt;=&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;–&lt;code&gt;9&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Signal properties (&lt;code&gt;phase&lt;/code&gt;, &lt;code&gt;period&lt;/code&gt;, &lt;code&gt;node&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Top-level properties (&lt;code&gt;edge&lt;/code&gt;, &lt;code&gt;config&lt;/code&gt;, &lt;code&gt;head&lt;/code&gt;, &lt;code&gt;foot&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Group and spacer syntax&lt;/li&gt;
&lt;li&gt;Edge annotation syntax for timing arrows between signals&lt;/li&gt;
&lt;li&gt;Common patterns: SPI transactions, request/acknowledge handshakes, clock-with-enable, grouped signals&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Example workflow&lt;/h3&gt;
&lt;p&gt;Describe the protocol:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"Draw an I2C start condition followed by a 7-bit address byte with ACK"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Claude generates the WaveJSON and explains the timing. Because the skill outputs a &lt;code&gt;wavedrom&lt;/code&gt; fenced block (not just JSON), you can paste it directly into a blog post and the Pelican plugin renders it automatically.&lt;/p&gt;
&lt;h2&gt;WaveJSON quick reference&lt;/h2&gt;
&lt;p&gt;The wave string for each signal is a sequence of characters:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Char&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;p&lt;/code&gt; / &lt;code&gt;n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Positive / negative clock (with tick mark)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt; / &lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Logic low / high&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unknown / undefined&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;z&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;High impedance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Continue previous state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Multi-bit data (label from &lt;code&gt;data&lt;/code&gt; array)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;–&lt;code&gt;9&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Coloured data states&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\|&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gap / break in time axis&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;A minimal diagram:&lt;/p&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_47846f1d1444efee9e793db00192ea4d.svg"&gt;&lt;/p&gt;
&lt;p&gt;An SPI transaction with chip select:&lt;/p&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_41ab2e5fe0cdd7dde2f60fec31f05df5.svg"&gt;&lt;/p&gt;
&lt;p&gt;A request/acknowledge handshake with an edge annotation showing propagation delay:&lt;/p&gt;
&lt;p&gt;&lt;img alt="WaveDrom timing diagram" src="http://lizard-spock.co.uk/images/wavedrom/wavedrom_df96e15d2ad371db91e44c66212ec566.svg"&gt;&lt;/p&gt;
&lt;h2&gt;Project structure&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;morganp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="c1"&gt;# blog source (main branch)&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;wavedrom&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# SVG cache (persists across make clean)&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pelican&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;wavedrom&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="c1"&gt;# github.com/morganp/pelican-wavedrom&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pelican&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;wavedrom_generator&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="c1"&gt;# plugin entry point, signal registration&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;preprocessor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# Markdown extension + preprocessor&lt;/span&gt;

&lt;span class="o"&gt;~/.&lt;/span&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;skills&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wavedrom&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SKILL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="c1"&gt;# Claude Code skill definition&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The combination is useful for hardware documentation: describe a protocol in English, get WaveJSON from Claude, drop the block into a post, and the plugin renders it at build time. No manual JSON editing, no copy-pasting between browser tabs.&lt;/p&gt;
&lt;p&gt;The same skill format is used by the &lt;a href="http://lizard-spock.co.uk/verilog-lint-skill-for-claude-code.html"&gt;Verilog lint skill&lt;/a&gt; — describe a module, get generated RTL, and the lint loop validates it automatically.&lt;/p&gt;</content><category term="Engineering"></category><category term="WaveDrom"></category><category term="Timing"></category><category term="Electronics"></category><category term="Pelican"></category><category term="claude"></category><category term="ai"></category><category term="Verilog"></category><category term="Python"></category><category term="Git"></category><category term="Bash"></category><category term="Homebrew"></category><category term="RTL"></category></entry><entry><title>Top Museums for Families</title><link href="http://lizard-spock.co.uk/top-museums-for-families.html" rel="alternate"></link><published>2025-12-05T15:06:00+00:00</published><updated>2025-12-05T15:06:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-12-05:/top-museums-for-families.html</id><content type="html">&lt;p&gt;&lt;a href="https://www.beamish.org.uk/"&gt;Beamish&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.life.org.uk"&gt;Life Science Centre&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://play.eureka.org.uk/"&gt;Eureka: Children’s Museum&lt;/a&gt;
&lt;a href="https://discover.eureka.org.uk/"&gt;Eureka: Science Museum&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://edencamp.co.uk"&gt;Eden Camp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://dynamicearth.org.uk"&gt;Dynamic Earth&lt;/a&gt;&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="Family"></category></entry><entry><title>Reduce Rack Drum Kit Size</title><link href="http://lizard-spock.co.uk/reduce-rack-drum-kit-size.html" rel="alternate"></link><published>2025-12-05T14:50:00+00:00</published><updated>2025-12-05T14:50:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-12-05:/reduce-rack-drum-kit-size.html</id><summary type="html">&lt;p&gt;For the Yamaha DTX8 the cymbals mount on to the horizontal drum rack tubes. A more compact setup can be …&lt;/p&gt;</summary><content type="html">&lt;p&gt;For the Yamaha DTX8 the cymbals mount on to the horizontal drum rack tubes. A more compact setup can be achieved if the cymbal mounts are onto of the vertical tubes. Some drum racks already have this setup, typically on the lower end as it requires less harder to be supplied. It seems like a great way to save space if trying to fit a drum kit into your home!  &lt;a href="https://www.musicstore.com/en_GB/GBP/Gibraltar-Rack-Tube-Attachment-SC-RMAA-/art-DRU0025312-000?campaign=GShopping/GB&amp;amp;ProgramUUID=fp4KAQMEqOEAAAGSjgtiaHEt&amp;amp;gad_source=1"&gt;Gibraltar have this clamp&lt;/a&gt;, to convert other drum racks with (1.5”) 38.1mm tubing.&lt;/p&gt;</content><category term="Music"></category><category term="Drum"></category></entry><entry><title>Expanding Yamaha DTX8 Drum Kit</title><link href="http://lizard-spock.co.uk/expanding-yamaha-dtx8-drum-kit.html" rel="alternate"></link><published>2025-12-05T14:43:00+00:00</published><updated>2025-12-05T14:43:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-12-05:/expanding-yamaha-dtx8-drum-kit.html</id><summary type="html">&lt;h2&gt;TOM&lt;/h2&gt;
&lt;p&gt;Parts Required for adding 4th Tom (second floor tom) to a Yamaha DTX8 kit.&lt;/p&gt;
&lt;p&gt;Mounting bracket for rack: Yamaha …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;TOM&lt;/h2&gt;
&lt;p&gt;Parts Required for adding 4th Tom (second floor tom) to a Yamaha DTX8 kit.&lt;/p&gt;
&lt;p&gt;Mounting bracket for rack: Yamaha TPCL500 Tom Holder. 
&lt;a href="https://www.yamahamusiclondon.com/TPCL500-Tom-Holder/pidJTPCL500"&gt;UK supplier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;10” tom, on the DTX8 they are all 10”: Yamaha XP125T M.  
Note are the Mesh heads(M), not the (X) heads.   &lt;a href="https://www.yamahamusiclondon.com/XP125T-M-Real-Wood-Finish-Tom-Pack/pidJXP125TMRW-TOMPACK"&gt;UK supplier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;eBay might also be a good source for used components.&lt;/p&gt;
&lt;h2&gt;Adding a Cymbal&lt;/h2&gt;
&lt;p&gt;Cable splitting tom1 for tom1 single zone and a single zone splash cymbal.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Yamaha PCY10010-inch cymbal pad&lt;/li&gt;
&lt;li&gt;Yamaha CYAT500 Cymbal Attachment  &lt;a href="https://www.yamahamusiclondon.com/DTX6-and-8-Splash-Pack/pidDTX68-SPLASHPACK"&gt;Splash £180 UK Supplier&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alternatively for another crash or simply larger 13” pad a Yamaha PCY135A pad could be used.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.yamahamusiclondon.com/DTX6-Crash-Pack/pidDTX6-CRASHPACK"&gt;Crash £200 UK Supplier&lt;/a&gt;.&lt;/p&gt;</content><category term="Music"></category><category term="Drum"></category></entry><entry><title>Yamaha Drum App</title><link href="http://lizard-spock.co.uk/yamaha-drum-app.html" rel="alternate"></link><published>2025-12-05T14:38:00+00:00</published><updated>2025-12-05T14:38:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-12-05:/yamaha-drum-app.html</id><summary type="html">&lt;p&gt;For Yamaha electronic drum kits (DTX) there is a &lt;a href="https://uk.yamaha.com/en/products/musical_instruments/drums/el_drums/apps/index.html"&gt;‘DTX Touch app’&lt;/a&gt; for iPhone, iPad, Android that lets you more …&lt;/p&gt;</summary><content type="html">&lt;p&gt;For Yamaha electronic drum kits (DTX) there is a &lt;a href="https://uk.yamaha.com/en/products/musical_instruments/drums/el_drums/apps/index.html"&gt;‘DTX Touch app’&lt;/a&gt; for iPhone, iPad, Android that lets you more easily manage the kit sounds.&lt;/p&gt;</content><category term="Music"></category><category term="Drum"></category></entry><entry><title>Command Line Disk Usage</title><link href="http://lizard-spock.co.uk/command-line-disk-usage.html" rel="alternate"></link><published>2025-09-06T13:19:00+01:00</published><updated>2025-09-06T13:19:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-09-06:/command-line-disk-usage.html</id><summary type="html">&lt;h1&gt;NCurses Disk Usage&lt;/h1&gt;
&lt;p&gt;A useful Command Line Iterface (CLI) for exploring disk usage:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ncdu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example output.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ncdu 2.9.1 …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h1&gt;NCurses Disk Usage&lt;/h1&gt;
&lt;p&gt;A useful Command Line Iterface (CLI) for exploring disk usage:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ncdu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example output.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ncdu 2.9.1 ~ Use the arrow keys to navigate, press ? for help
--- ... github.io --------------------------
  115.6 MiB [##################] /venv
   59.7 MiB [#########         ] /output
   47.6 MiB [#######           ] /.git
   46.1 MiB [#######           ] /content
    8.0 KiB [                  ]  .DS_Store
    8.0 KiB [                  ]  tasks.py
    8.0 KiB [                  ] /__pycache__
    4.0 KiB [                  ]  Makefile
    4.0 KiB [                  ]  readme.md
    4.0 KiB [                  ]  pelicanconf.py
    4.0 KiB [                  ]  python_search_category.py
    4.0 KiB [                  ]  python_search_and_replace.py
    4.0 KiB [                  ]  create_new_post.py
    4.0 KiB [                  ]  publishconf.py
    4.0 KiB [                  ]  .gitignore
    4.0 KiB [                  ]  CNAME
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you are using MacOS then &lt;a href="https://brew.sh"&gt;brew&lt;/a&gt; can be used to install:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;brew install ncdu
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;Disk Usage&lt;/h1&gt;
&lt;p&gt;The disk usage tool &lt;code&gt;du&lt;/code&gt; is a simpler non interactive way of listing file sizes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;du -h -d 1
  60M   ./output
  46M   ./content
 8.0K   ./__pycache__
 116M   ./venv
  48M   ./.git
 313M   .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;-h&lt;/code&gt; gives human readable output, ie sizes in k, M, G TBytes.&lt;br&gt;
thr &lt;code&gt;-d 1&lt;/code&gt; on MacOS limits listing to 1 directory deep. &lt;code&gt;-s&lt;/code&gt;can be used to summarise the requested directory.&lt;/p&gt;
&lt;h1&gt;Tree&lt;/h1&gt;
&lt;p&gt;Another alternative is to use &lt;code&gt;tree&lt;/code&gt; to list folde contents with the &lt;code&gt;-h&lt;/code&gt;option to give human readable file sizes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tree -L 1 -h
[ 608]  .
├── [ 128]  __pycache__
├── [  19]  CNAME
├── [ 224]  content
├── [1.2K]  create_new_post.py
├── [2.8K]  Makefile
├── [ 28K]  output
├── [2.1K]  pelicanconf.py
├── [ 528]  publishconf.py
├── [1.3K]  python_search_and_replace.py
├── [1.7K]  python_search_category.py
├── [2.2K]  readme.md
├── [4.1K]  tasks.py
├── [ 224]  venv
└── [ 224]  venv_old
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;MacOS install tree with &lt;a href="https://brew.sh"&gt;brew&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;brew install tree
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Unix &amp; Tools"></category><category term="OS X"></category><category term="CLI"></category><category term="Git"></category></entry><entry><title>Book: Mastering the command line</title><link href="http://lizard-spock.co.uk/book-mastering-the-command-line.html" rel="alternate"></link><published>2025-05-31T10:11:00+01:00</published><updated>2025-05-31T10:11:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-05-31:/book-mastering-the-command-line.html</id><summary type="html">&lt;!--to publish change draft to published--&gt;

&lt;p&gt;&lt;a href="https://leanpub.com/masteringcli"&gt;Mastering the command line like a hacker by Xiaodong Xu&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The book focuses on bash and zsh, which is great …&lt;/p&gt;</summary><content type="html">&lt;!--to publish change draft to published--&gt;

&lt;p&gt;&lt;a href="https://leanpub.com/masteringcli"&gt;Mastering the command line like a hacker by Xiaodong Xu&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The book focuses on bash and zsh, which is great since I use both of those shells.&lt;/p&gt;
&lt;p&gt;The useful sections from the book include:&lt;/p&gt;
&lt;h1&gt;Zsh Completion&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# ~/.zshrc&lt;/span&gt;
&lt;span class="n"&gt;autoload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;U&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;compinit&lt;/span&gt;
&lt;span class="n"&gt;compinit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;

&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;dotfiles&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zsh&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;autosuggestions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;zsh&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;autosuggestions&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zsh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The zsh-autosuggestions.zsh needs to be &lt;a href="https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md"&gt;installed/downloaded from Github&lt;/a&gt;, adding as a seperate depo or adding as a submodule to your dotfiles depo.&lt;/p&gt;
&lt;h1&gt;History&lt;/h1&gt;
&lt;h2&gt;BASH History&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;.&lt;span class="nv"&gt;bashrc&lt;/span&gt;
#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Save&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;lins&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;history&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;same&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;scroll&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;back&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;terminal&lt;/span&gt;
&lt;span class="nv"&gt;HISTFILESIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;
&lt;span class="nv"&gt;HISTSIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;

#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;duplicate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;commands&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ignore&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;commands&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;starting&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;space&lt;/span&gt;
&lt;span class="nv"&gt;HISTCONTROL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;erasedups:ignorespace&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;ZSH History&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gh"&gt;#&lt;/span&gt; ~/.zshrc 
&lt;span class="gh"&gt;#&lt;/span&gt; Save 5000 lins of history, with the same scroll back in the terminal
SAVEHIST=5000
HISTSIZE=5000

&lt;span class="gh"&gt;#&lt;/span&gt; Do not save duplicate commands, ignore commands starting with a space
setopt HIST_IGNORE_ALL_DUPS
setopt HIST_IGNORE_SPACE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Using History&lt;/h2&gt;
&lt;p&gt;View the last 5 commands&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;# Bash
$ history 5
# Zsh
$ history -5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For zsh we can see the last time the command was run and the time taken with :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;history -i -D
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alternative command to history:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;fc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Searching History&lt;/h2&gt;
&lt;p&gt;The most common way is piping history through grep to search.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;history&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;cmd&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ctrl+r is another option which starts a reverse search through the history.&lt;/p&gt;
&lt;p&gt;Ctrl+p and Ctrl+n can be used to scroll forwards and backwards through previous commands. Although for me the up down cursors workk mor enaturally.&lt;/p&gt;
&lt;h2&gt;Repeating Commands&lt;/h2&gt;
&lt;p&gt;Repeat the last command used (Bang Bang)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;!!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;great example is when you run a command but it fails because of require Superuser access.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;cmd_that_needs_root
&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;fail
$&lt;span class="w"&gt; &lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;!!
&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;yay!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Execute command 2 back.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;!-2
#Note
!! =&amp;gt; !-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Execute command 100 from history&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="sx"&gt;!100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Last Argument&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;!$&lt;/code&gt; recalls the last Argument. typicall usage could be with mkdir and cd:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;notes
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;!$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;!--Image Example: image location content/images/photo.jpg--&gt;
&lt;p&gt;&lt;img alt="photo" src="http://lizard-spock.co.uk/photo.jpg"&gt;&lt;/p&gt;</content><category term="Programming"></category><category term="Python"></category><category term="Bash"></category></entry><entry><title>Better Python Iterators</title><link href="http://lizard-spock.co.uk/better-python-iterators.html" rel="alternate"></link><published>2025-03-01T12:24:00+00:00</published><updated>2025-03-01T12:24:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-03-01:/better-python-iterators.html</id><summary type="html">&lt;!--to publish change draft to published--&gt;

&lt;p&gt;Pyhton can convert most (all) lists/collections into iterator objects, this is done by calling &lt;code&gt;iter()&lt;/code&gt; ie&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;num_list = [1, 2 …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;!--to publish change draft to published--&gt;

&lt;p&gt;Pyhton can convert most (all) lists/collections into iterator objects, this is done by calling &lt;code&gt;iter()&lt;/code&gt; ie&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;num_list = [1, 2, 3] 
num_iter = iter(num_list)  # Returns Iterator
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Python in the background is calling the objects &lt;code&gt;__iter__()&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;A typical method for returning an Iterator is using a for loop to compile/create the elements. However the draw back to this is that the for loop can not begin executing until the full iterator is created.&lt;br&gt;
This could make it the program look like it has stalled while it compiles long and or complex iterator objects.&lt;/p&gt;
&lt;h2&gt;Generator Functions&lt;/h2&gt;
&lt;p&gt;Generator function allow an optimisation that it allows the use of the iterator after each element has been created. Generator functions return elemnts using &lt;code&gt;yield&lt;/code&gt; instead of &lt;code&gt;return&lt;/code&gt; on the complete list. The a benefit of this approach is that the full iterator never has to be held in memory at the same time, allowing much larger data sets to be analysed.&lt;/p&gt;
&lt;h2&gt;Generator Example&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;def my_generator(n):

    # initialize counter
    value = 0

    # loop until counter is less than n
    while value &amp;lt; n:

        # produce the current value of the counter
        yield value

        # increment the counter
        value += 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Non-Generator Example&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;def my_nongenerator(n):

    # initialize counter
    value = 0
    this_list = list()
    # loop until counter is less than n
    while value &amp;lt; n:

        # produce the current value of the counter
        this_list.append( value )

        # increment the counter
        value += 1
    return this_list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Python"></category></entry><entry><title>Packaging Python Projects</title><link href="http://lizard-spock.co.uk/packaging-python-projects.html" rel="alternate"></link><published>2025-02-28T15:22:00+00:00</published><updated>2025-02-28T15:22:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-02-28:/packaging-python-projects.html</id><summary type="html">&lt;!--to publish change draft to published--&gt;

&lt;p&gt;How to package a pythin script or project for distribution. Offical Docs are [here][python_package].
Packaging for pip requires use …&lt;/p&gt;</summary><content type="html">&lt;!--to publish change draft to published--&gt;

&lt;p&gt;How to package a pythin script or project for distribution. Offical Docs are [here][python_package].
Packaging for pip requires use of a [build backend][], [Hatchling][] is the default for this example.&lt;/p&gt;
&lt;p&gt;This run through uses the testPyPI. &lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://test.pypi.org/account/register/"&gt;Register for a test.pypi account&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Initialise Python project area:
note: the build process also uses the gitignore to excluded the venv folder.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;mkdir packaging_tutorial
cd packagin_tutorial
python3 -m venv venv
source venv/bin/activate
curl --output .gitignore &amp;quot;https://raw.githubusercontent.com/github/gitignore/refs/heads/main/Python.gitignore&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Create the folder structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;packaging_tutorial&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;LICENSE&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pyproject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toml&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;README&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;md&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;example_package_YOUR_USERNAME_HERE&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;py&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;tests&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;__init__.py&lt;/code&gt; can be empty, but allows project to be imported in standard way.&lt;/p&gt;
&lt;p&gt;pyproject.toml - directs pip how to build the project&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[build-system]&lt;/span&gt;
&lt;span class="na"&gt;requires&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;[&amp;quot;hatchling&amp;quot;]&lt;/span&gt;
&lt;span class="na"&gt;build-backend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hatchling.build&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;[project]&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;example_package_YOUR_USERNAME_HERE&amp;quot;&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;0.0.1&amp;quot;&lt;/span&gt;
&lt;span class="na"&gt;authors&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;{ name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Example Author&amp;quot;, email=&amp;quot;author@example.com&amp;quot; },&lt;/span&gt;
&lt;span class="na"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;A small example package&amp;quot;&lt;/span&gt;
&lt;span class="na"&gt;readme&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;README.md&amp;quot;&lt;/span&gt;
&lt;span class="na"&gt;requires-python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;gt;=3.8&amp;quot;&lt;/span&gt;
&lt;span class="na"&gt;classifiers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;&amp;quot;Programming Language&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;: Python :: 3&amp;quot;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;&amp;quot;Operating System&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;: OS Independent&amp;quot;,&lt;/span&gt;
&lt;span class="na"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;license&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;MIT&amp;quot;&lt;/span&gt;
&lt;span class="na"&gt;license-files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;[&amp;quot;LICEN[CS]E*&amp;quot;]&lt;/span&gt;

&lt;span class="k"&gt;[project.urls]&lt;/span&gt;
&lt;span class="na"&gt;Homepage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/pypa/sampleproject&amp;quot;&lt;/span&gt;
&lt;span class="na"&gt;Issues&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://github.com/pypa/sampleproject/issues&amp;quot;&lt;/span&gt;


&lt;span class="na"&gt;[python_package]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;https://packaging.python.org/en/latest/tutorials/packaging-projects/&lt;/span&gt;
&lt;span class="na"&gt;[build backend]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;https://packaging.python.org/en/latest/glossary/&lt;/span&gt;&lt;span class="c1"&gt;#term-Build-Backend&lt;/span&gt;
&lt;span class="na"&gt;[Hatchling]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;https://hatch.pypa.io/latest/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Generate Distrubution Archive&lt;/h2&gt;
&lt;p&gt;Update &lt;code&gt;build&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install --upgrade build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Build:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python3 -m build
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This should create&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;example_package_YOUR_USERNAME_HERE&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m m-Double"&gt;0.0.1&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;py3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;none&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;whl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Built&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Distribution&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;example_package_YOUR_USERNAME_HERE&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="m m-Double"&gt;0.0.1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gz&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Distibution&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Upload!&lt;/h2&gt;
&lt;p&gt;Create and store API token. &lt;a href="https://test.pypi.org/manage/account/#api-tokens"&gt;Create Token&lt;/a&gt;, set scope to entire account.&lt;/p&gt;
&lt;p&gt;Update &lt;code&gt;twine&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install --upgrade twine
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Upload the files in dist&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;python3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;twine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;upload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;repository&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testpypi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once Complete the uploaded package can be viewed here:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//test.pypi.org/project/example_package_YOUR_USERNAME_HERE.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Test install&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;python3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//test.pypi.org/simple/ --no-deps example-package-YOUR-USERNAME-HERE&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Python"></category></entry><entry><title>Pelican New Post script</title><link href="http://lizard-spock.co.uk/pelican-new-post-script.html" rel="alternate"></link><published>2025-01-03T16:44:00+00:00</published><updated>2025-01-03T16:44:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-01-03:/pelican-new-post-script.html</id><summary type="html">&lt;p&gt;In the aim of keeping the navigation of the Blog posts clean, I have limited my self to a few …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In the aim of keeping the navigation of the Blog posts clean, I have limited my self to a few general categories, but remeberign them while editing in vim and not creating typos is a pain. Therefore I have added the category selection to my pyhton script for creating the new markdown files.&lt;/p&gt;
&lt;p&gt;When running this file from the command line, top level of my pelican project, it first prompts for a category selection then requests The title of the post. The new file is created and correctly formated for a Pelican markdown post.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;
&lt;span class="normal"&gt;31&lt;/span&gt;
&lt;span class="normal"&gt;32&lt;/span&gt;
&lt;span class="normal"&gt;33&lt;/span&gt;
&lt;span class="normal"&gt;34&lt;/span&gt;
&lt;span class="normal"&gt;35&lt;/span&gt;
&lt;span class="normal"&gt;36&lt;/span&gt;
&lt;span class="normal"&gt;37&lt;/span&gt;
&lt;span class="normal"&gt;38&lt;/span&gt;
&lt;span class="normal"&gt;39&lt;/span&gt;
&lt;span class="normal"&gt;40&lt;/span&gt;
&lt;span class="normal"&gt;41&lt;/span&gt;
&lt;span class="normal"&gt;42&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/python3&lt;/span&gt;
&lt;span class="c1"&gt;# coding=utf-8&lt;/span&gt;

&lt;span class="c1"&gt;# CLI for creating a new markdown post&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;html&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="c1"&gt;# datetime object containing current date and time&lt;/span&gt;
&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# dd/mm/YY H:M&lt;/span&gt;
&lt;span class="n"&gt;dt_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;%Y-%m-&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt; %H:%M&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;dt_string_simple&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;%Y-%m-&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create dictionary of categories, ask for user selection.&lt;/span&gt;
&lt;span class="n"&gt;cat_dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Cooking&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Engineering&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Outdoor&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Photography&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tech&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;cat_dict&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;post_cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Enter Post Category :&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;post_cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_cat&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#Request title of blog post&lt;/span&gt;
&lt;span class="n"&gt;post_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Enter Post Title : &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;post_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# sanitize&lt;/span&gt;
&lt;span class="n"&gt;post_title_safe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;new_post_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dt_string_simple&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;_&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;post_title_safe&lt;/span&gt;

&lt;span class="n"&gt;this_file_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./content/posts/&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;new_post_name&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;.md&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_file_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Title: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Date: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;dt_string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Category: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;cat_dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;post_cat&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tags: python&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Author: morganp&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Status: draft&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;lt;!--to publish change draft to published--&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;this_file_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Python"></category><category term="Vim"></category><category term="Pelican"></category></entry><entry><title>Python Base Types</title><link href="http://lizard-spock.co.uk/python-base-types.html" rel="alternate"></link><published>2025-01-02T18:09:00+00:00</published><updated>2025-01-02T18:09:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-01-02:/python-base-types.html</id><summary type="html">&lt;p&gt;Making notes as I work through &lt;a href="https://www.dr-chuck.com"&gt;Dr Chucks&lt;/a&gt; Python for Everyone course on &lt;a href="https://www.coursera.org/specializations/python"&gt;Coursera&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are 3 main types in …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Making notes as I work through &lt;a href="https://www.dr-chuck.com"&gt;Dr Chucks&lt;/a&gt; Python for Everyone course on &lt;a href="https://www.coursera.org/specializations/python"&gt;Coursera&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are 3 main types in Python:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lists []&lt;/li&gt;
&lt;li&gt;Dictionaries {}&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Tuple"&gt;Tuples&lt;/a&gt; ()&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;List&lt;/h2&gt;
&lt;p&gt;Lists are mutable, ie elements can be changed.&lt;br&gt;
Creation of a list:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;emptylist = []
thislist  = [&amp;quot;A&amp;quot;,&amp;quot;B&amp;quot;,&amp;quot;C&amp;quot;]
print( thislist )
  [&amp;#39;A&amp;#39;, &amp;#39;B&amp;#39;, &amp;#39;C&amp;#39;]
print( thislist[1] )
  B
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Dictionary&lt;/h2&gt;
&lt;p&gt;Dictionaries are key value pairs.&lt;br&gt;
Creation of Dictionary&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;emptydict = {}
thisdict  = {0:&amp;quot;A&amp;quot;, 1:&amp;quot;B&amp;quot;, 2:&amp;quot;C&amp;quot;} 
print( thisdict )
  {0: &amp;#39;A&amp;#39;, 1: &amp;#39;B&amp;#39;, 2: &amp;#39;C&amp;#39;}
print( thisdict[1] )
  B
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Tuple&lt;/h2&gt;
&lt;p&gt;Tuples are unmodifiable lists. elements can not be changed or reordered.&lt;br&gt;
Creation of Tuple.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;emptytuple = () # This is of no real use as imutable
thistuple  = (&amp;quot;A&amp;quot;, &amp;quot;B&amp;quot;, &amp;quot;C&amp;quot;)
print( thistuple )
  (&amp;#39;A&amp;#39;, &amp;#39;B&amp;#39;, &amp;#39;C&amp;#39;)
print( thistuple[1] )
  B
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Python"></category></entry><entry><title>Modify Pelican theme</title><link href="http://lizard-spock.co.uk/modify-pelican-theme.html" rel="alternate"></link><published>2025-01-02T16:53:00+00:00</published><updated>2025-01-02T16:53:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-01-02:/modify-pelican-theme.html</id><summary type="html">&lt;p&gt;First figure out which theme you are using.
List installed themes via:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c"&gt;% pelican-themes -l&lt;/span&gt;
&lt;span class="n"&gt;simple&lt;/span&gt;
&lt;span class="s"&gt;notmyidea&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;pelicanconf.py does not …&lt;/p&gt;</summary><content type="html">&lt;p&gt;First figure out which theme you are using.
List installed themes via:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c"&gt;% pelican-themes -l&lt;/span&gt;
&lt;span class="n"&gt;simple&lt;/span&gt;
&lt;span class="s"&gt;notmyidea&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;pelicanconf.py does not set a THEME, therfore defaulting to notmyidea.&lt;/p&gt;
&lt;p&gt;The template locaions are (update your python version as appropriate):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nx"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;venv&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;python3&lt;/span&gt;&lt;span class="m m-Double"&gt;.13&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;pelican&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;themes&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;notmyidea&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;templates&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At a minimum a theme must contain these files, which could be altered in your local copy of the theme.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;└── templates
    ├── archives.html         // to display archives
    ├── period_archives.html  // to display time-period archives
    ├── article.html          // processed for each article
    ├── author.html           // processed for each author
    ├── authors.html          // must list all the authors
    ├── categories.html       // must list all the categories
    ├── category.html         // processed for each category
    ├── index.html            // the index (list all the articles)
    ├── page.html             // processed for each page
    ├── tag.html              // processed for each tag
    └── tags.html             // must list all the tags. Can be a tag cloud.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Python"></category><category term="Pelican"></category></entry><entry><title>Pelican Site add Tags and Categories list</title><link href="http://lizard-spock.co.uk/pelican-site-add-tags-and-categories-list.html" rel="alternate"></link><published>2025-01-02T15:39:00+00:00</published><updated>2025-01-02T15:39:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-01-02:/pelican-site-add-tags-and-categories-list.html</id><summary type="html">&lt;p&gt;I think it improves website usability when they are navigatable via the URL.&lt;/p&gt;
&lt;p&gt;For example when viewing Posts under the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I think it improves website usability when they are navigatable via the URL.&lt;/p&gt;
&lt;p&gt;For example when viewing Posts under the caetegory 'Tech' ie https://lizard-spock.co.uk/category/tech.html, &lt;/p&gt;
&lt;p&gt;removing the category and viewing  https://lizard-spock.co.uk/category/ should list the possible categories.&lt;/p&gt;
&lt;p&gt;The page is created by pelican but it is placed as :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://lizard-spock.co.uk/categories.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Not&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://lizard-spock.co.uk/category/index.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To remedy this, modify your pelicanconf.py Adding in some page mappings.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gu"&gt;##&lt;/span&gt; Adding template pages creating /tag/index.html from tags.html
TEMPLATE_PAGES = {&amp;#39;tags.html&amp;#39;: &amp;#39;tag/index.html&amp;#39;}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Above takes the tags.html template and makes it available via example.com/tag&lt;/p&gt;</content><category term="Programming"></category><category term="Python"></category><category term="Pelican"></category></entry><entry><title>Japanese Garden 10 Years on</title><link href="http://lizard-spock.co.uk/japanese-garden-10-years-on.html" rel="alternate"></link><published>2025-01-02T13:02:00+00:00</published><updated>2025-01-02T13:02:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2025-01-02:/japanese-garden-10-years-on.html</id><summary type="html">&lt;p&gt;An update to the Japanese Garden, aorund 10 years after it was built.&lt;br&gt;
The ground cover is being removed in …&lt;/p&gt;</summary><content type="html">&lt;p&gt;An update to the Japanese Garden, aorund 10 years after it was built.&lt;br&gt;
The ground cover is being removed in some of these images for the next iteration.  &lt;/p&gt;
&lt;p&gt;The large panorama is 270 degree view of 3 sides of it.
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_4220.jpeg"&gt;
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_4221.jpeg"&gt;
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_4223.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;Various iterations of ground cover, last one was partially paved.
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_2181.jpeg"&gt;
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_2495.jpeg"&gt;
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_2496.jpeg"&gt;
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_2612.jpeg"&gt;&lt;/p&gt;
&lt;h2&gt;Older pictures during Construction&lt;/h2&gt;
&lt;p&gt;Then main structure nearly complete
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_0988.jpeg"&gt;
&lt;img alt="photo" src="http://lizard-spock.co.uk/IMG_1120.jpeg"&gt;&lt;/p&gt;
&lt;p&gt;Leveling up the roofs for the seating area.
The large panorama is a 270 degree view of 3 sides of it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="270 degree panorama of the garden" src="http://lizard-spock.co.uk/IMG_9401.jpeg"&gt;&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="Garden"></category><category term="DIY"></category></entry><entry><title>Python Regular Expressions</title><link href="http://lizard-spock.co.uk/python-regular-expressions.html" rel="alternate"></link><published>2024-12-23T10:21:00+00:00</published><updated>2024-12-23T10:21:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-12-23:/python-regular-expressions.html</id><summary type="html">&lt;h2&gt;Python Regular Expressions Quick Guide:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;beginning&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;h2&gt;Python Regular Expressions Quick Guide:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;beginning&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character&lt;/span&gt;
&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;whitespace&lt;/span&gt;
&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;whitespace&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Repeats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;zero&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="vm"&gt;?&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;Repeats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;zero&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;greedy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Repeats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="vm"&gt;?&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;Repeats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;more&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;greedy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aeiou&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;^XYZ&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;character&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a-z0-9&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;range&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Indicates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;extraction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;start&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Indicates&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;extraction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Based on Dr Chucks from Python for Everyone course.&lt;/p&gt;
&lt;h2&gt;Usage:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;list_of_strings&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Python"></category></entry><entry><title>Adaptive Filter Theory Notes 1</title><link href="http://lizard-spock.co.uk/adaptive-filter-theory-notes-1.html" rel="alternate"></link><published>2024-12-19T11:04:00+00:00</published><updated>2024-12-19T11:04:00+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-12-19:/adaptive-filter-theory-notes-1.html</id><summary type="html">&lt;p&gt;Notes From Reading Adaptive Signal Theory (5th Ed) by Simon Haykin&lt;/p&gt;
&lt;h2&gt;Three Basic Kinds Of Estimation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Filtering  - Extraction of Current …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;p&gt;Notes From Reading Adaptive Signal Theory (5th Ed) by Simon Haykin&lt;/p&gt;
&lt;h2&gt;Three Basic Kinds Of Estimation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Filtering  - Extraction of Current and previous information. RealTime operation.&lt;/li&gt;
&lt;li&gt;Smoothing  - Data after the time of interest is used. Posteriori operation.&lt;/li&gt;
&lt;li&gt;Prediction - forcasting for some time in the future. RealTime operation.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Filter optimization is useful to think of minimising the mean-square-error. &lt;/p&gt;
&lt;p&gt;For stationary inputs the &lt;strong&gt;Wiener&lt;/strong&gt; filter is considered optimal in mean-square-error sense.&lt;/p&gt;
&lt;p&gt;Plots of the mean-square value of the error signal versus the adjustable parameters of the linear filter is known as the &lt;strong&gt;error-performance-surface&lt;/strong&gt;. The min point on this is the Wiener solution.&lt;/p&gt;
&lt;p&gt;Wiener Filter is no good with moving signals, or precense of noise. Kalman Filters are useful in this sitation.&lt;/p&gt;</content><category term="Engineering"></category><category term="DSP"></category></entry><entry><title>Node Red vs Home Assistant</title><link href="http://lizard-spock.co.uk/node-red-vs-home-assistant.html" rel="alternate"></link><published>2024-10-24T15:58:00+01:00</published><updated>2024-10-24T15:58:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-24:/node-red-vs-home-assistant.html</id><summary type="html">&lt;p&gt;Node Red vs Home Assistant&lt;/p&gt;
&lt;p&gt;Which is better* ?&lt;/p&gt;
&lt;p&gt;*better: CPU/RAM efficient, easier to learn and or offer better support …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Node Red vs Home Assistant&lt;/p&gt;
&lt;p&gt;Which is better* ?&lt;/p&gt;
&lt;p&gt;*better: CPU/RAM efficient, easier to learn and or offer better support of devices&lt;/p&gt;
&lt;p&gt;Materials used for comparison &lt;a href="https://letsautomate.net/nodered/home-assistant-vs-node-red-which-is-the-better-choice/"&gt;video this review&lt;/a&gt;, end with the conclusion:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Home Assistant and Node-RED have their merits when it comes to automating your home. The choice ultimately depends on your preferences and specific requirements. While Home Assistant offers a user-friendly interface and integration within a single system, Node-RED provides versatility, the ability to connect to multiple Home Assistant instances and other APIs. Consider your needs, technical proficiency, and desired level of customization to determine which platform suits you best. Let us know your thoughts in the comments.&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="Hardware &amp; Homelab"></category><category term="HomeAssistant"></category></entry><entry><title>Proxmox Plex Container</title><link href="http://lizard-spock.co.uk/proxmox-plex-container.html" rel="alternate"></link><published>2024-10-24T13:10:00+01:00</published><updated>2024-10-24T13:10:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-24:/proxmox-plex-container.html</id><summary type="html">&lt;p&gt;With Proxmox installed time to setup Plex in a container, and migrate from Synology NAS.&lt;/p&gt;
&lt;p&gt;I am following these guides …&lt;/p&gt;</summary><content type="html">&lt;p&gt;With Proxmox installed time to setup Plex in a container, and migrate from Synology NAS.&lt;/p&gt;
&lt;p&gt;I am following these guides for &lt;a href="https://www.derekseaman.com/2023/04/proxmox-plex-lxc-with-alder-lake-transcoding.html"&gt;plex setup&lt;/a&gt;, and there following guide for &lt;a href="https://www.derekseaman.com/2023/04/migration-guide-plex-on-synology-to-proxmox-lxc.html"&gt;synology to proxmox migration&lt;/a&gt;.&lt;/p&gt;</content><category term="Hardware &amp; Homelab"></category><category term="Proxmox"></category><category term="Plex"></category></entry><entry><title>Starting with ProxMox</title><link href="http://lizard-spock.co.uk/starting-with-proxmox.html" rel="alternate"></link><published>2024-10-24T12:56:00+01:00</published><updated>2024-10-24T12:56:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-24:/starting-with-proxmox.html</id><summary type="html">&lt;p&gt;Having decided that &lt;a href="https://www.proxmox.com/en/"&gt;Proxmox&lt;/a&gt; is the way forward to manage docker and ivrtualisation outside of the synology NAS. i need …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Having decided that &lt;a href="https://www.proxmox.com/en/"&gt;Proxmox&lt;/a&gt; is the way forward to manage docker and ivrtualisation outside of the synology NAS. i need to figure out how to install , use and manage proxmox.&lt;/p&gt;
&lt;p&gt;For the first instance I will be following the &lt;a href="https://noted.lol/proxmox-for-beginners/"&gt;guide to Proxmox&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There is another good tutorial &lt;a href="https://www.derekseaman.com/2023/10/home-assistant-proxmox-ve-8-0-quick-start-guide-2.html"&gt;here&lt;/a&gt; which covers installing proxmox and then creating a virtual machine for home assistant.&lt;/p&gt;
&lt;p&gt;Note from &lt;a href="https://pve.proxmox.com/pve-docs/chapter-pve-faq.html#:~:text=You%20manage%20a%20Docker%20instance,inside%20a%20Proxmox%20QEMU%20VM."&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;You&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;manage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;instance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;using&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Engine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;command&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;interface&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;It&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;recommended&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;directly&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Proxmox&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;VE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;host&lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;want&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;containers&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;example&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;images&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;best&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;them&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;inside&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Proxmox&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;QEMU&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;VM&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Hardware &amp; Homelab"></category><category term="Proxmox"></category><category term="Docker"></category></entry><entry><title>Beelink N200 Proxmox and Plex</title><link href="http://lizard-spock.co.uk/beelink-n200-proxmox-and-plex.html" rel="alternate"></link><published>2024-10-24T11:43:00+01:00</published><updated>2024-10-24T11:43:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-24:/beelink-n200-proxmox-and-plex.html</id><summary type="html">&lt;p&gt;To improve the Plex transcoding options and off load the computation from the NAS, the plan is purchase a BeeLink …&lt;/p&gt;</summary><content type="html">&lt;p&gt;To improve the Plex transcoding options and off load the computation from the NAS, the plan is purchase a BeeLink EQ13 Alder Lake N200 16GB Ram and 500GB Drive, currently for sale at £215.&lt;/p&gt;
&lt;p&gt;The Beelink will then have &lt;a href="https://www.proxmox.com/en/"&gt;proxmox&lt;/a&gt; installed as the main operating system. 
A docker container for Plex and the other dockers that are currently hosted on the NAS box.&lt;/p&gt;
&lt;p&gt;Theguide for plex install I will be following &lt;a href="https://forum.level1techs.com/t/plex-on-proxmox-with-igpu-hardware-transcode-best-practices/210491"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A virtual machine for Hssistant OS can also be installed to run &lt;a href="https://www.home-assistant.io/"&gt;HomeAssistant&lt;/a&gt;.&lt;/p&gt;</content><category term="Hardware &amp; Homelab"></category><category term="Networking"></category><category term="Plex"></category><category term="Proxmox"></category><category term="Docker"></category></entry><entry><title>Cat8 T-568</title><link href="http://lizard-spock.co.uk/cat8-t-568.html" rel="alternate"></link><published>2024-10-21T13:31:00+01:00</published><updated>2024-10-21T13:31:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-21:/cat8-t-568.html</id><summary type="html">&lt;p&gt;Cat 8 Wiring, comes in 2 variants T-568A and T-568B.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="Wiring Diagram" src="http://lizard-spock.co.uk/T-568AB.png"&gt;&lt;/p&gt;
&lt;p&gt;Cat8 replaces the need for crimping tools with field termination …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Cat 8 Wiring, comes in 2 variants T-568A and T-568B.  &lt;/p&gt;
&lt;p&gt;&lt;img alt="Wiring Diagram" src="http://lizard-spock.co.uk/T-568AB.png"&gt;&lt;/p&gt;
&lt;p&gt;Cat8 replaces the need for crimping tools with field termination kits. Both ends need to wired the same otherwise there is no perfomance difference.&lt;/p&gt;</content><category term="Hardware &amp; Homelab"></category><category term="Ethernet"></category><category term="Networking"></category></entry><entry><title>Synology Connecting Across VLAN with active VPN</title><link href="http://lizard-spock.co.uk/synology-connecting-across-vlan-with-active-vpn.html" rel="alternate"></link><published>2024-10-16T11:30:00+01:00</published><updated>2024-10-16T11:30:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-16:/synology-connecting-across-vlan-with-active-vpn.html</id><summary type="html">&lt;p&gt;When a Synology NAS creates a VPN connection it overides the default gateway, except for devices listed as contained within …&lt;/p&gt;</summary><content type="html">&lt;p&gt;When a Synology NAS creates a VPN connection it overides the default gateway, except for devices listed as contained within its subnet. According to the &lt;a href="https://community.synology.com/enu/forum/1/post/138785"&gt;a post&lt;/a&gt; on the synology forum even if the subnet is changed to 255.255.0.0 it will not see devices on another VLAN. It feels like a subnet mask of 255.255.255.0 is hardcoded.&lt;/p&gt;
&lt;p&gt;For Allowing my Synology NAS to create a VPN connection and see device on my VLANS I had to add a &lt;em&gt;static route&lt;/em&gt; defining a gatweway for the VLAN IP/subnet.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;Network&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Destination&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;192&lt;/span&gt;.&lt;span class="mi"&gt;168&lt;/span&gt;.&lt;span class="mi"&gt;107&lt;/span&gt;.&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;VLAN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;107&lt;/span&gt;
&lt;span class="nv"&gt;Netmask&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;.&lt;span class="mi"&gt;255&lt;/span&gt;.&lt;span class="mi"&gt;255&lt;/span&gt;.&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Standard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;netmask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;VLAN&lt;/span&gt;
&lt;span class="nv"&gt;Gateway&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;192&lt;/span&gt;.&lt;span class="mi"&gt;168&lt;/span&gt;.&lt;span class="mi"&gt;100&lt;/span&gt;.&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;#&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Gateway&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Synology&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;NASs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;VLAN&lt;/span&gt;
&lt;span class="nv"&gt;Interface&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;physical&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Synology&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;NAS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;uses&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;connect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;VLAN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="screen grab of route" src="/images/Tech/Synology_static_route.png"&gt;&lt;/p&gt;</content><category term="Hardware &amp; Homelab"></category><category term="Synology"></category><category term="Networking"></category><category term="VLAN"></category><category term="VPN"></category></entry><entry><title>TeX hyphenation</title><link href="http://lizard-spock.co.uk/tex-hyphenation.html" rel="alternate"></link><published>2024-10-14T14:45:00+01:00</published><updated>2024-10-14T14:45:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-14:/tex-hyphenation.html</id><summary type="html">&lt;p&gt;When TeX/LaTeX is fully justifying text there are times when it could do better but it does not know …&lt;/p&gt;</summary><content type="html">&lt;p&gt;When TeX/LaTeX is fully justifying text there are times when it could do better but it does not know how to hyphenate certain words. Here we can give it guidnace on how to split words.&lt;/p&gt;
&lt;p&gt;For example (insert into the pre-amble):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;\hyphenation{acro-nym}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Multiple hyphenation points can also be defined, and for related words:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;\hyphenation{ac-ro-nym ac-ro-nym-ic a-cro-nym-i-cal-ly}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The hyphenation point can be inserted manually with a &lt;code&gt;\-&lt;/code&gt;, but it is best to setup in the pre-amble and keep all the layout rules together.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;acro\-nym
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Preventing Hyphenation&lt;/h2&gt;
&lt;p&gt;Preventing hyphenation can be done by decalring in the pre-amble without a hyphen or inline with an &lt;code&gt;\mbox&lt;/code&gt; command&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;\hyphenation{automobile}

this will stop hyphenation of inline text \mbox{automobile}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Global Hyphenation Control&lt;/h2&gt;
&lt;p&gt;Use the hphenat package to prevent all hyphenation&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;usepackage&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hyphenat&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There are some better ideas on this &lt;a href="https://tex.stackexchange.com/q/5036/165015"&gt;TeX SO Question&lt;/a&gt;.&lt;/p&gt;</content><category term="Unix &amp; Tools"></category><category term="TeX"></category></entry><entry><title>TeX Paragraph Box</title><link href="http://lizard-spock.co.uk/tex-paragraph-box.html" rel="alternate"></link><published>2024-10-11T14:18:00+01:00</published><updated>2024-10-11T14:18:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-11:/tex-paragraph-box.html</id><summary type="html">&lt;p&gt;&lt;code&gt;parbox&lt;/code&gt; is a LaTeX command used to place a box around text. &lt;/p&gt;
&lt;p&gt;Remeber that optional arguments are in [] (Square brackets …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;code&gt;parbox&lt;/code&gt; is a LaTeX command used to place a box around text. &lt;/p&gt;
&lt;p&gt;Remeber that optional arguments are in [] (Square brackets)&lt;/p&gt;
&lt;p&gt;Typical usage is :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;parbox&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;alignment&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="err"&gt;}{&lt;/span&gt;&lt;span class="nc"&gt;text&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The options are:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;alignment&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Top&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;alligned&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vertically&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;centered&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Bottom&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;alligned&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Stretch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fill&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vertically&lt;/span&gt;

&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fractional&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;followed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ISO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;units&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;supported&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;\documentclass&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;article&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;\parbox&lt;/span&gt;&lt;span class="na"&gt;[b]&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;2.3cm&lt;span class="nb"&gt;}{&lt;/span&gt;b for bottom aligned&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\end&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If a large amount of text is to be placed in the box &lt;code&gt;minipage&lt;/code&gt; is preffered over &lt;code&gt;parbox&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;\documentclass&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;article&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;minipage&lt;span class="nb"&gt;}{&lt;/span&gt;2.3cm&lt;span class="nb"&gt;}&lt;/span&gt;
    minipage not parbox
  &lt;span class="k"&gt;\end&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;minipage&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\end&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;minipage&lt;/code&gt; supports all the arguments of &lt;code&gt;\parbox&lt;/code&gt;, as well as &lt;code&gt;\footnote&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;\documentclass&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;article&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;minipage&lt;span class="nb"&gt;}{&lt;/span&gt;5cm&lt;span class="nb"&gt;}&lt;/span&gt;
    minipage not parbox &lt;span class="k"&gt;\footnote&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;this is a foot note&lt;span class="nb"&gt;}&lt;/span&gt;.
    Second Line with another foot note &lt;span class="k"&gt;\footnote&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;Another foot note&lt;span class="nb"&gt;}&lt;/span&gt;.
  &lt;span class="k"&gt;\end&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;minipage&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\end&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="TeX minipage with footnotes example output" src="/images/Tech/Tex/tex_minipage_footnote.png"&gt;&lt;/p&gt;</content><category term="Unix &amp; Tools"></category><category term="TeX"></category></entry><entry><title>LaTeX macros</title><link href="http://lizard-spock.co.uk/latex-macros.html" rel="alternate"></link><published>2024-10-10T14:17:00+01:00</published><updated>2024-10-10T14:17:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-10-10:/latex-macros.html</id><summary type="html">&lt;p&gt;LaTeX macros can be used as simple text replacments for example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;\documentclass&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;article&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\newcommand&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\LUG&lt;/span&gt;&lt;span class="nb"&gt;}{&lt;/span&gt;LEGO User Group&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;LaTeX macros can be used as simple text replacments for example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;\documentclass&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;article&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\newcommand&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\LUG&lt;/span&gt;&lt;span class="nb"&gt;}{&lt;/span&gt;LEGO User Group&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;\section&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;Welcome to the &lt;span class="k"&gt;\LUG&lt;/span&gt;&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\end&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;More Advanced usage allows LaTeX macros to be used like functions:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;\documentclass&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;article&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\newcommand&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\LUG&lt;/span&gt;&lt;span class="nb"&gt;}&lt;/span&gt;[1]&lt;span class="nb"&gt;{&lt;/span&gt;&lt;span class="k"&gt;\textbf&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;#1&lt;span class="nb"&gt;}&lt;/span&gt; LEGO User Group&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;\section&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;Welcome to the &lt;span class="k"&gt;\LUG&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;tartan&lt;span class="nb"&gt;}}&lt;/span&gt;
&lt;span class="k"&gt;\end&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;document&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Unix &amp; Tools"></category><category term="TeX"></category></entry><entry><title>Tools for Technical Writing</title><link href="http://lizard-spock.co.uk/tools-for-technical-writing.html" rel="alternate"></link><published>2024-09-10T10:17:00+01:00</published><updated>2024-09-10T10:17:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-09-10:/tools-for-technical-writing.html</id><summary type="html">&lt;p&gt;WYSIWYG editor for LaTeX &lt;a href="https://www.lyx.org/"&gt;lyx&lt;/a&gt;, and a manager for Bibliography &lt;a href="https://www.jabref.org/"&gt;JabRef&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lyx Tutorial: &lt;a href="https://wiki.lyx.org/Mac/Mac"&gt;Lyx mac Guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;JabRef Tutorial: &lt;a href="https://docs.jabref.org/getting-started"&gt;Getting Started …&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;WYSIWYG editor for LaTeX &lt;a href="https://www.lyx.org/"&gt;lyx&lt;/a&gt;, and a manager for Bibliography &lt;a href="https://www.jabref.org/"&gt;JabRef&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lyx Tutorial: &lt;a href="https://wiki.lyx.org/Mac/Mac"&gt;Lyx mac Guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;JabRef Tutorial: &lt;a href="https://docs.jabref.org/getting-started"&gt;Getting Started&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tools avialable via home brew:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;brew install lyx
brew install jabref
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Unix &amp; Tools"></category><category term="TeX"></category></entry><entry><title>Bike Chain Cleaning</title><link href="http://lizard-spock.co.uk/bike-chain-cleaning.html" rel="alternate"></link><published>2024-06-14T12:27:00+01:00</published><updated>2024-06-14T12:27:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-06-14:/bike-chain-cleaning.html</id><summary type="html">&lt;p&gt;Chain Cleaning method:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; Clean the chain with WD40 (water dispersant).
 Wipe dry with kitchen roll. 
 Spray with Comma White Grease …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Chain Cleaning method:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; Clean the chain with WD40 (water dispersant).
 Wipe dry with kitchen roll. 
 Spray with Comma White Grease and wipe clean again.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The chain should be lubricated on the moving parts of the chain, not the surface in contact with cogs.&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="Outdoors"></category><category term="Bike"></category></entry><entry><title>Pyhton_virtual_env</title><link href="http://lizard-spock.co.uk/pyhton_virtual_env.html" rel="alternate"></link><published>2024-05-30T16:03:00+01:00</published><updated>2024-05-30T16:03:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-05-30:/pyhton_virtual_env.html</id><summary type="html">&lt;p&gt;Creating/Setup a pyhton virtual enviroment called 'venv'&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python3 -m venv venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Load the virtual env called venv&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;source venv …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Creating/Setup a pyhton virtual enviroment called 'venv'&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;python3 -m venv venv
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Load the virtual env called venv&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;source venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://realpython.com/python-virtual-environments-a-primer/"&gt;RealPython Guide&lt;/a&gt;, &lt;a href="https://docs.python.org/3/library/venv.html"&gt;Docs&lt;/a&gt;.&lt;/p&gt;</content><category term="Programming"></category><category term="Python"></category><category term="Command Line"></category></entry><entry><title>Convolution in Python</title><link href="http://lizard-spock.co.uk/convolution-in-python.html" rel="alternate"></link><published>2024-05-03T14:25:00+01:00</published><updated>2024-05-03T14:25:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-05-03:/convolution-in-python.html</id><summary type="html">&lt;p&gt;Convolution in Python, for merging filter responses, creating pascals triangle ...&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;b …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Convolution in Python, for merging filter responses, creating pascals triangle ...&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;convolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Python"></category><category term="Signal"></category><category term="Matlab"></category></entry><entry><title>Perforce Update files in a Shelve</title><link href="http://lizard-spock.co.uk/perforce-update-files-in-a-shelve.html" rel="alternate"></link><published>2024-04-30T11:04:00+01:00</published><updated>2024-04-30T11:04:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-04-30:/perforce-update-files-in-a-shelve.html</id><summary type="html">&lt;p&gt;Perforce can temporarily checkins of changes that you might want to share with others before fully commiting them to the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Perforce can temporarily checkins of changes that you might want to share with others before fully commiting them to the code base. These P4 Shelves have some properties that seem undesirable for a revision control system. They are not imuttable. &lt;/p&gt;
&lt;p&gt;From there nature they are temporary but they can also be altered and maintain the same changelist number. Solution based on &lt;a href="https://stackoverflow.com/a/23109698/97073"&gt;this SO answer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lets create file a.txt with some default content, and create a shelve.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;File a - line 1&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;
&lt;span class="nv"&gt;p4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;
&lt;span class="nv"&gt;p4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;shelve&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;...

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Change&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3265397&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;created&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;open&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;.
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Shelving&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;change&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3265397&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Remeber the Changelist number for the shelve, we will refer to it as \&amp;lt;change#&amp;gt;. 
Now lets modify a and create a b.txt. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;p4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;edit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;
&lt;span class="nv"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;File a - line 2 after intial shelve&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;
&lt;span class="nv"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;File b - line 1 Missed in first shelve&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;
&lt;span class="nv"&gt;p4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;

&lt;span class="nv"&gt;p4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;reopen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;change&lt;/span&gt;#&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;&lt;span class="sc"&gt;#1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="c1"&gt;; change 3265397&lt;/span&gt;

&lt;span class="nv"&gt;p4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;shelve&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;change&lt;/span&gt;#&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Shelving&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;change&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3265397&lt;/span&gt;.
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;.&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;&lt;span class="sc"&gt;#1&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;.&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;.&lt;span class="nv"&gt;txt&lt;/span&gt;&lt;span class="sc"&gt;#1&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Change&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3265397&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;files&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;shelved&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Revision Control"></category><category term="Command Line"></category></entry><entry><title>Python merge PDFs</title><link href="http://lizard-spock.co.uk/python-merge-pdfs.html" rel="alternate"></link><published>2024-04-22T18:49:00+01:00</published><updated>2024-04-22T18:49:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-04-22:/python-merge-pdfs.html</id><summary type="html">&lt;p&gt;Using python script to merge pdfs together.&lt;/p&gt;
&lt;p&gt;Install package&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install pypdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;pypdf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PdfWriter&lt;/span&gt;

&lt;span class="n"&gt;pdfs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;file1.pdf …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Using python script to merge pdfs together.&lt;/p&gt;
&lt;p&gt;Install package&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pip install pypdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;pypdf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PdfWriter&lt;/span&gt;

&lt;span class="n"&gt;pdfs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;file1.pdf&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;file2.pdf&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;file3.pdf&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;file4.pdf&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;#merger = PdfMerger()&lt;/span&gt;
&lt;span class="n"&gt;merger&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PdfWriter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pdfs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;merger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;merger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;result.pdf&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;merger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/3444645/merge-pdf-files"&gt;source&lt;/a&gt;&lt;/p&gt;</content><category term="Programming"></category><category term="Python"></category></entry><entry><title>Pythonista pip install pelican</title><link href="http://lizard-spock.co.uk/pythonista-pip-install-pelican.html" rel="alternate"></link><published>2024-04-20T12:04:00+01:00</published><updated>2024-04-20T12:04:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-04-20:/pythonista-pip-install-pelican.html</id><summary type="html">&lt;p&gt;On the journey towards publish static site generator blog posts from iPadOS, my next step after installing stash on pythonista …&lt;/p&gt;</summary><content type="html">&lt;p&gt;On the journey towards publish static site generator blog posts from iPadOS, my next step after installing stash on pythonista is uisng pip to install the pelican library.&lt;/p&gt;</content><category term="Programming"></category><category term="Python"></category><category term="Pelican"></category></entry><entry><title>Pythonista using stash for pip</title><link href="http://lizard-spock.co.uk/pythonista-using-stash-for-pip.html" rel="alternate"></link><published>2024-04-19T17:04:00+01:00</published><updated>2024-04-19T17:04:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-04-19:/pythonista-using-stash-for-pip.html</id><summary type="html">&lt;p&gt;Installing stash on pythonista&lt;/p&gt;</summary><content type="html">&lt;p&gt;To run pip in pythonista we need to install &lt;a href="https://github.com/ywangd/stash"&gt;stash&lt;/a&gt; first.&lt;/p&gt;
&lt;p&gt;See stash page sfor latest details, at time of install I had to run this from the pythinista terminal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;requests&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://bit.ly/get-stash&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="installing stash" src="img/install_stash.png" title="Installing Stash"&gt;&lt;/p&gt;
&lt;p&gt;Then to start stash from a new (restart pyhtonista app) find and run the launch_stash.py script&lt;/p&gt;
&lt;p&gt;&lt;img alt="start stash" src="img/launch_stash.png" title="Starting Stash"&gt;&lt;/p&gt;
&lt;p&gt;there will then be a second terminal with the stash command line open up&lt;/p&gt;
&lt;p&gt;&lt;img alt="running stash" src="img/running_stash.png" title="Running Stash"&gt;&lt;/p&gt;</content><category term="Programming"></category><category term="Python"></category></entry><entry><title>Python read a CSV file</title><link href="http://lizard-spock.co.uk/python-read-a-csv-file.html" rel="alternate"></link><published>2024-04-19T12:34:00+01:00</published><updated>2024-04-19T12:34:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-04-19:/python-read-a-csv-file.html</id><summary type="html">&lt;p&gt;Python example for reading data from a csv file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;, newline=&amp;#39;&amp;#39;) as csvfile:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;spamreader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;csv …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Python example for reading data from a csv file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;, newline=&amp;#39;&amp;#39;) as csvfile:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;spamreader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;delimiter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quotechar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;|&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;spamreader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Import csv into a numpy array.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data.csv&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# data_array = np.array(data)  # Conversion for strings&lt;/span&gt;
&lt;span class="n"&gt;data_array&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# Conversion for doubles&lt;/span&gt;

&lt;span class="c1"&gt;# Print first 10 data elements.&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Outputs: &lt;/p&gt;
&lt;p&gt;&lt;a href="https://saturncloud.io/blog/loading-csv-data-into-a-numpy-array-a-comprehensive-guide/"&gt;source&lt;/a&gt;&lt;/p&gt;</content><category term="Programming"></category><category term="Pelican"></category><category term="Python"></category></entry><entry><title>Python Sinewave</title><link href="http://lizard-spock.co.uk/python-sinewave.html" rel="alternate"></link><published>2024-04-19T12:34:00+01:00</published><updated>2024-04-19T12:34:00+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2024-04-19:/python-sinewave.html</id><summary type="html">&lt;p&gt;Create and plot a sinewave in python&lt;/p&gt;</summary><content type="html">&lt;p&gt;Python example for creatign and plotting a sinewave:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;numpy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;matplotlib.pyplot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;plt&lt;/span&gt;

&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;48000&lt;/span&gt;
&lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#Hz&lt;/span&gt;
&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# Linear Amplitude&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# Seconds sample length&lt;/span&gt;

&lt;span class="n"&gt;amp_db&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;sine_&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s1"&gt;Hz_&lt;/span&gt;&lt;span class="si"&gt;%4.2f&lt;/span&gt;&lt;span class="s1"&gt;_amp&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;amp_db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;label_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Sinewave &lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt;Hz &lt;/span&gt;&lt;span class="si"&gt;%5.2f&lt;/span&gt;&lt;span class="s2"&gt;dB&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;amp_db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#samples = np.linspace(0, t, int(fs*t), endpoint=False)&lt;/span&gt;
&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;

&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;amp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;fig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subplots&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;label_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Sinewave&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;savefig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.png&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Generates and saves this plot&lt;/p&gt;
&lt;p&gt;&lt;img alt="1kHz Sinewave" src="img/sine_1000Hz_0.00_amp.png" title="Generate Sinewave Plot"&gt;&lt;/p&gt;
&lt;p&gt;To export the 'signal' data as a CSV file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;csv&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_name&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.csv&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;newline&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;f_writer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;delimiter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;quotechar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;|&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quoting&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;QUOTE_MINIMAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;f_writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writerows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;*.csv output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;
&lt;span class="mf"&gt;0.13052619222005157&lt;/span&gt;
&lt;span class="mf"&gt;0.25881904510252074&lt;/span&gt;
&lt;span class="mf"&gt;0.3826834323650898&lt;/span&gt;
&lt;span class="mf"&gt;0.49999999999999994&lt;/span&gt;
&lt;span class="mf"&gt;0.6087614290087207&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Programming"></category><category term="Python"></category><category term="Signal"></category><category term="DSP"></category></entry><entry><title>"Home Directory File Structure"</title><link href="http://lizard-spock.co.uk/home-directory-file-structure.html" rel="alternate"></link><published>2015-10-22T10:32:44+01:00</published><updated>2015-10-22T10:32:44+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-10-22:/home-directory-file-structure.html</id><summary type="html">&lt;p&gt;Apples default directory structure is :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Documents&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Downloads&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Library&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;# Hidden by default&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Movies&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Music&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pictures&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;My current …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Apples default directory structure is :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Documents&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Downloads&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Library&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="c1"&gt;# Hidden by default&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Movies&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Music&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pictures&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;My current setup After adding Dropbox, dotfiles stored on github, Code, and user level applications folder:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Applications&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Documents&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Downloads&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dropbox&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Library&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Movies&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Music&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pictures&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Public&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dotfiles&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At present though my Dropbox is a mess of some documents, some code and lots of ebooks. Free Dropbox does not have enough space for me to the entire home directory. Considering a BtSync pro account which allows selective sync. BtSync will allow me to set the root as my home directory and select which folders from that to sync. &lt;/p&gt;
&lt;p&gt;I have started using USB flash drives again, and have found &lt;a href="http://www.cis.upenn.edu/~bcpierce/unison"&gt;unison&lt;/a&gt; to be a useful tool for syncing local drives to each other.&lt;/p&gt;
&lt;p&gt;Me example unison sync (USB drive is called 'Dropbox'):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;unison&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;Volumes&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;Dropbox&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;Unison&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;fat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;links&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;\
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Code&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;\
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Documents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;\
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Dropbox&lt;/span&gt;

#&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;fat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Work&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;With&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;FAT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;filesystem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ThumbDrive&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
#&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Accept&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;merges&lt;/span&gt;
#&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;links&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;follow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;symlinks&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that the 'Dropbox' root is my home directory I can reorganise. Books should become a top level folder, and share a place along side Music and Movies.&lt;/p&gt;
&lt;p&gt;Dropbox is kept but mainly used for sharing temporary files with others.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Applications&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Books&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Desktop&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Documents&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Downloads&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dropbox&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Library&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Movies&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Music&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pictures&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Public&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dotfiles&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Dropbox: sending large files
BT Sync: Synchronising files (eBook collection)
Unison: Synchronising local drives (Thumbdrive to local documents/ebooks)
ReadyNAS: Remote access to larger volume drives (Movies and TV Collections)
 Above could be a BT Sync non populated folder  &lt;/p&gt;</content><category term="Unix &amp; Tools"></category><category term="Filesystem"></category></entry><entry><title>"JapaneseGarden"</title><link href="http://lizard-spock.co.uk/japanesegarden.html" rel="alternate"></link><published>2015-10-10T12:50:55+01:00</published><updated>2015-10-10T12:50:55+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-10-10:/japanesegarden.html</id><content type="html">&lt;p&gt;First step creating the retaining wall, to become a raised bed.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Japanese garden, June 2014" src="/images/Gardening/JapaneseGarden/morganp-20140616--_MG_9132.jpg"&gt;
&lt;img alt="Japanese garden, October 2014" src="/images/Gardening/JapaneseGarden/morganp-20141025-Garden-IMG_9608.jpg"&gt;
&lt;img alt="Japanese garden, March 2015" src="/images/Gardening/JapaneseGarden/morganp-20150306--IMG_0145.jpg"&gt;
&lt;img alt="Japanese garden, March 2015" src="/images/Gardening/JapaneseGarden/morganp-20150306--IMG_0149.jpg"&gt;
&lt;img alt="Japanese garden, March 2015" src="/images/Gardening/JapaneseGarden/morganp-20150309--IMG_0158.jpg"&gt;
&lt;img alt="Japanese garden, April 2015" src="/images/Gardening/JapaneseGarden/morganp-20150420--IMG_0417.jpg"&gt;
&lt;img alt="Japanese garden, April 2015" src="/images/Gardening/JapaneseGarden/morganp-20150420--IMG_0418.jpg"&gt;
&lt;img alt="Japanese garden, April 2015" src="/images/Gardening/JapaneseGarden/morganp-20150420--IMG_0419.jpg"&gt;&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="DIY"></category><category term="Garden"></category></entry><entry><title>"Potting Bench"</title><link href="http://lizard-spock.co.uk/potting-bench.html" rel="alternate"></link><published>2015-10-10T12:23:15+01:00</published><updated>2015-10-10T12:23:15+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-10-10:/potting-bench.html</id><summary type="html">&lt;p&gt;Homemade potting bench, using 15 2.4M Fence boards (£45).&lt;/p&gt;
&lt;p&gt;&lt;img alt="Homemade potting bench" src="/images/Gardening/PottingBench/morganp-20150414--IMG_0330.jpg"&gt;
&lt;img alt="Homemade potting bench" src="/images/Gardening/PottingBench/morganp-20150414--IMG_0332.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Note for ease of building the height was 1.2M …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Homemade potting bench, using 15 2.4M Fence boards (£45).&lt;/p&gt;
&lt;p&gt;&lt;img alt="Homemade potting bench" src="/images/Gardening/PottingBench/morganp-20150414--IMG_0330.jpg"&gt;
&lt;img alt="Homemade potting bench" src="/images/Gardening/PottingBench/morganp-20150414--IMG_0332.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Note for ease of building the height was 1.2M, half a 2.4 meter board, this is too high.&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="DIY"></category><category term="Garden"></category></entry><entry><title>"Self Watering Propagator"</title><link href="http://lizard-spock.co.uk/self-watering-propagator.html" rel="alternate"></link><published>2015-10-10T12:04:12+01:00</published><updated>2015-10-10T12:04:12+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-10-10:/self-watering-propagator.html</id><content type="html">&lt;p&gt;Propagator hack using some seed trays and capillary matting.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Propagator" src="/images/Gardening/Propogator/morganp-20150328--IMG_0176.jpg"&gt;
&lt;img alt="Propagator" src="/images/Gardening/Propogator/morganp-20150328--IMG_0178.jpg"&gt;
&lt;img alt="Propagator" src="/images/Gardening/Propogator/morganp-20150328--IMG_0179.jpg"&gt;
&lt;img alt="Propagator" src="/images/Gardening/Propogator/morganp-20150328--IMG_0180.jpg"&gt;&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="DIY"></category><category term="Garden"></category></entry><entry><title>"Planter"</title><link href="http://lizard-spock.co.uk/planter.html" rel="alternate"></link><published>2015-10-10T10:52:30+01:00</published><updated>2015-10-10T10:52:30+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-10-10:/planter.html</id><content type="html">&lt;p&gt;3 Fence boards used to create planter.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Wooden planter made from fence boards" src="/images/Gardening/Planter/morganp-20150504-Planter-IMG_0543.jpg"&gt;&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="DIY"></category><category term="Garden"></category><category term="Woodwork"></category></entry><entry><title>"Matlab: floating point checking equality"</title><link href="http://lizard-spock.co.uk/matlab-floating-point-checking-equality.html" rel="alternate"></link><published>2015-06-10T20:43:32+01:00</published><updated>2015-06-10T20:43:32+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-06-10:/matlab-floating-point-checking-equality.html</id><summary type="html">&lt;p&gt;As previously decribed &lt;a href="/blog/engineering/floating-point-arithmetic-is-not-associative/"&gt;floating point arithmetic is not associative&lt;/a&gt;. Which means it is very easy for floating point models not …&lt;/p&gt;</summary><content type="html">&lt;p&gt;As previously decribed &lt;a href="/blog/engineering/floating-point-arithmetic-is-not-associative/"&gt;floating point arithmetic is not associative&lt;/a&gt;. Which means it is very easy for floating point models not to match even though they are performing the same arithmetic operations. In matlab we compare the results:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;a = 0.1 + 0.2 + 0.3 ;
b = 0.1 + (0.2 + 0.3);

isequal(a, b)
&amp;gt; 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;a &amp;amp; b are not equal, they are a least significant bit out, when comparing floating point numbers it is common to allow this amount of tolerance. Matlab anonymous functions can be used to create a new &lt;code&gt;isequal&lt;/code&gt; function which takes a tolerance value. Idea from &lt;a href="http://stackoverflow.com/questions/2202641/how-do-i-compare-all-elements-of-two-arrays"&gt;Stackoverflow&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;isequalAbs = @(x,y,tol) ( all(abs(x-y) &amp;lt;= tol ));
floating_point_tol = 1e-15;

isequalAbs(a, b, floating_point_tol)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Maths"></category><category term="Matlab"></category></entry><entry><title>"Matlab: linear progressions"</title><link href="http://lizard-spock.co.uk/matlab-linear-progressions.html" rel="alternate"></link><published>2015-06-10T20:19:05+01:00</published><updated>2015-06-10T20:19:05+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-06-10:/matlab-linear-progressions.html</id><summary type="html">&lt;p&gt;Progressions can be created using the &lt;a href="http://uk.mathworks.com/help/matlab/ref/colon.html"&gt;Colon&lt;/a&gt; operator&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;min   = 10
max   = 100
steps = 20

step_size = (max-min)/steps

i = min:step_size …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Progressions can be created using the &lt;a href="http://uk.mathworks.com/help/matlab/ref/colon.html"&gt;Colon&lt;/a&gt; operator&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;min   = 10
max   = 100
steps = 20

step_size = (max-min)/steps

i = min:step_size:max
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alternatively &lt;a href="http://uk.mathworks.com/help/matlab/ref/linspace.html"&gt;linspace&lt;/a&gt; can be used:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;min   = 10
max   = 100
steps = 20

i = linspace(min,max,steps)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This also allows for easily switching to a log scale using &lt;a href="http://uk.mathworks.com/help/matlab/ref/logspace.html"&gt;logspace&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Matlab: functions inputs parsed based on outputs"</title><link href="http://lizard-spock.co.uk/matlab-functions-inputs-parsed-based-on-outputs.html" rel="alternate"></link><published>2015-06-10T20:10:54+01:00</published><updated>2015-06-10T20:10:54+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-06-10:/matlab-functions-inputs-parsed-based-on-outputs.html</id><summary type="html">&lt;p&gt;It is quite common to detect how many input arguments have been passed to a function, using &lt;code&gt;nargin&lt;/code&gt; (N arguments …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It is quite common to detect how many input arguments have been passed to a function, using &lt;code&gt;nargin&lt;/code&gt; (N arguments in).  Commonly used to set defaults for arguments not specified.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;result&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fun_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;a,b,c&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;nargin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;a must be supplied&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;nargin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;nargin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;% ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However I just discovered &lt;code&gt;nargout&lt;/code&gt; (N arguments out(.&lt;/p&gt;
&lt;p&gt;This allows the scripts to differentiate between:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;x     = fun(a)
[x,y] = fun(a)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example 1:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;[ varargout ] = nargout_test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; input_args &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;disp&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;nargout : &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;num2str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nargout&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;% Set outputs&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;i&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;nargout&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;varargout&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example 2, changing input args usage based on number of outputs:
note the input keyword change to the input arguments &lt;code&gt;varargin&lt;/code&gt; Variable argument in.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;[ varargout ] = nargout_test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; varargin &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;disp&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;nargin : &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;num2str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nargin&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nb"&gt;disp&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;nargout : &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;num2str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nargout&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;nargout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Too many output arguments&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;nargout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c"&gt;% single output first input means something&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;varargout&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;varargin&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;nargout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c"&gt;% two outputs first input means some thing else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;varargout&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;varargin&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;varargin&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;varargout&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;varargin&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;varargin&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A good example is the &lt;a href="http://uk.mathworks.com/matlabcentral/fileexchange/13792-the-dc-blocking-filter/"&gt;dcblock script by J M De Freitas&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Which has this syntax:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SYNTAX&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dcblock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dcblock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aQ&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dcblock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fc,fc&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dcblock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="n"&gt;dcblock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="n"&gt;dcblock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="n"&gt;dcblock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"SystemVerilog: RTL Types"</title><link href="http://lizard-spock.co.uk/systemverilog-rtl-types.html" rel="alternate"></link><published>2015-03-26T20:08:34+00:00</published><updated>2015-03-26T20:08:34+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-03-26:/systemverilog-rtl-types.html</id><summary type="html">&lt;p&gt;&lt;code&gt;reg&lt;/code&gt; and &lt;code&gt;wire&lt;/code&gt; were the original synthesisable types. Wires are constantly assigned and regs are evaluated at particular points, the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;code&gt;reg&lt;/code&gt; and &lt;code&gt;wire&lt;/code&gt; were the original synthesisable types. Wires are constantly assigned and regs are evaluated at particular points, the advantage here is for the simulator to make optimisations.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;wire&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;assign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w_data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Same function as above using reg&lt;/span&gt;
&lt;span class="kt"&gt;reg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;always&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;r_data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A common mistake when learning Verilog is to assume the reg type implies a register in hardware. The earlier optimisation for the simulator can be done through the context of its usage.&lt;/p&gt;
&lt;p&gt;This introduces &lt;code&gt;logic&lt;/code&gt; which can be used in place of wire and reg.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;logic&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;w_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;assign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w_data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Same function as above using reg&lt;/span&gt;
&lt;span class="kt"&gt;logic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;always&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;r_data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The type &lt;code&gt;bit&lt;/code&gt; and &lt;code&gt;byte&lt;/code&gt; have also been created that can only hold 2 states 0 or 1 no x or z. &lt;code&gt;byte&lt;/code&gt; implies &lt;code&gt;bit [7:0]&lt;/code&gt;. Using these types offers a small speed improvement but I would recommend not using them in RTL as your verification may miss uninitialized values or critical resets.&lt;/p&gt;
&lt;p&gt;The usage of &lt;code&gt;bit&lt;/code&gt; and &lt;code&gt;byte&lt;/code&gt; would be more common in testbench components, but can lead to issues in case of having to drive x's to stimulate data corruption and recovery.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;At the time of writing I was under the impression that &lt;code&gt;logic&lt;/code&gt; could not be used for tristate, I am unable to find the original paper that I based this on. Until further updates, comments or edits, I revoke my assertion that &lt;em&gt;logic can not be used to create tri-state lines&lt;/em&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The &lt;code&gt;tri&lt;/code&gt; type has been added, for explicitly defining a tri-state line. It is based on the properties of a &lt;code&gt;wire&lt;/code&gt;, &lt;code&gt;logic&lt;/code&gt; is based on the properties of a &lt;code&gt;reg&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;tri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;assign&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t_data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;1&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;bz&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you no longer have to support backwards compatibility Verilog then I would recommend switching to using &lt;code&gt;logic&lt;/code&gt; and &lt;code&gt;tri&lt;/code&gt;. Using &lt;code&gt;logic&lt;/code&gt; aids re-factoring and and &lt;code&gt;tri&lt;/code&gt;  reflects the design intent of a tristate line.&lt;/p&gt;
&lt;p&gt;Originally posted as a&lt;a href="http://stackoverflow.com/a/13285242/97073"&gt; SO answer&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Verilog"></category><category term="SystemVerilog"></category><category term="RTL"></category></entry><entry><title>"Verilog: define if not defined"</title><link href="http://lizard-spock.co.uk/verilog-define-if-not-defined.html" rel="alternate"></link><published>2015-03-26T19:45:10+00:00</published><updated>2015-03-26T19:45:10+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-03-26:/verilog-define-if-not-defined.html</id><summary type="html">&lt;p&gt;To set a default define option while allowing it to be overridden from the command line.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="sb"&gt;`ifndef mode_sel&lt;/span&gt;
&lt;span class="sb"&gt;  `&lt;/span&gt;define mode_sel …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;To set a default define option while allowing it to be overridden from the command line.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="sb"&gt;`ifndef mode_sel&lt;/span&gt;
&lt;span class="sb"&gt;  `&lt;/span&gt;define mode_sel 0
`endif
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The command line should override testbench defined options but this has proven unreliable.&lt;/p&gt;
&lt;p&gt;command line to set value:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;irun -define mode_sel=1 ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Verilog"></category></entry><entry><title>"Verilog: shm waveforms"</title><link href="http://lizard-spock.co.uk/verilog-shm-waveforms.html" rel="alternate"></link><published>2015-03-26T19:38:29+00:00</published><updated>2015-03-26T19:38:29+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-03-26:/verilog-shm-waveforms.html</id><summary type="html">&lt;p&gt;The best practice is to use a tcl file:&lt;/p&gt;
&lt;p&gt;shm.tcl &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;database -open waves -shm
probe -create your_top_level -depth all …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;The best practice is to use a tcl file:&lt;/p&gt;
&lt;p&gt;shm.tcl &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;database -open waves -shm
probe -create your_top_level -depth all -all -shm -database waves
run 
exit
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;run with :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;irun -access +r testcase.sv -input shm.tcl
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alternatively the following can be added to the simulation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;initial begin
  $shm_open(&amp;quot;waves.shm&amp;quot;); $shm_probe(&amp;quot;AS&amp;quot;);
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;run with &lt;code&gt;irun -access +r testcase.sv&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;NB: I have had trouble getting this last version to work, the tcl file method is more reliable.&lt;/p&gt;</content><category term="Engineering"></category><category term="Verilog"></category></entry><entry><title>"Verilog Timeformat"</title><link href="http://lizard-spock.co.uk/verilog-timeformat.html" rel="alternate"></link><published>2015-03-26T19:21:25+00:00</published><updated>2015-03-26T19:21:25+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-03-26:/verilog-timeformat.html</id><summary type="html">&lt;p&gt;Time can be displayed during simulation using &lt;code&gt;%t&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$display(&amp;quot;%t&amp;quot;, $realtime);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Timeformat is used to control the way (&lt;code&gt;%t&lt;/code&gt;) this …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Time can be displayed during simulation using &lt;code&gt;%t&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$display(&amp;quot;%t&amp;quot;, $realtime);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Timeformat is used to control the way (&lt;code&gt;%t&lt;/code&gt;) this is displayed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;//$timeformat(unit#, prec#, &amp;quot;unit&amp;quot;, minwidth);&lt;/span&gt;
&lt;span class="no"&gt;$&lt;/span&gt;&lt;span class="n"&gt;timeformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot; ms&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// -3 and &amp;quot; ms&amp;quot; give useful display msg&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;unit is the base that time is to be displayed in, from 0 to -15&lt;/li&gt;
&lt;li&gt;precision is the number of decimal points to display.&lt;/li&gt;
&lt;li&gt;"unit" is a string appended to the time, such as " ns".&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;minwidth is the minimum number of characters that will be displayed.&lt;/p&gt;
&lt;p&gt;0 = 1 sec
 -1 = 100 ms
 -2 = 10 ms
 -3 = 1 ms
 -4 = 100 us
 -5 = 10 us
 -6 = 1 us
 -7 = 100 ns
 -8 = 10 ns
 -9 = 1 ns
-10 = 100 ps
-11 = 10 ps
-12 = 1 ps
-13 = 100 fs
-14 = 10 fs
-15 = 1 fs&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content><category term="Engineering"></category><category term="Verilog"></category></entry><entry><title>"Tiered Raised Bed"</title><link href="http://lizard-spock.co.uk/tiered-raised-bed.html" rel="alternate"></link><published>2015-03-24T19:17:45+00:00</published><updated>2015-03-24T19:17:45+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-03-24:/tiered-raised-bed.html</id><content type="html">&lt;p&gt;Decorative raised bed for lavender:
&lt;img alt="Raised Bed" src="/images/Gardening/morganp-20141012-RaisedBed-IMG_9605.jpg"&gt;
&lt;img alt="Raised Bed" src="/images/Gardening/morganp-20141012-RaisedBed-IMG_9607.jpg"&gt;&lt;/p&gt;
&lt;p&gt;A couple of images before it was filled:
&lt;img alt="Raised Bed" src="/images/Gardening/morganp-20140708-RaisedBed-_MG_9173.jpg"&gt;
&lt;img alt="Raised Bed" src="/images/Gardening/morganp-20140708-RaisedBed-_MG_9175.jpg"&gt;&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="DIY"></category><category term="Garden"></category><category term="Woodwork"></category></entry><entry><title>"OS X disable back gesture"</title><link href="http://lizard-spock.co.uk/os-x-disable-back-gesture.html" rel="alternate"></link><published>2015-02-18T18:26:07+00:00</published><updated>2015-02-18T18:26:07+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-02-18:/os-x-disable-back-gesture.html</id><summary type="html">&lt;p&gt;After accidentally scrolling back a page when browsing the web in chrome too many times. Figured out how to disable …&lt;/p&gt;</summary><content type="html">&lt;p&gt;After accidentally scrolling back a page when browsing the web in chrome too many times. Figured out how to disable it: from your terminal&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;defaults write com.google.Chrome AppleEnableSwipeNavigateWithScrolls -bool FALSE
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://apple.stackexchange.com/questions/21236/how-do-i-disable-chromes-two-finger-back-forward-navigation"&gt;From 
http://apple.stackexchange.com&lt;/a&gt;.&lt;/p&gt;</content><category term="Unix &amp; Tools"></category><category term="OS X"></category></entry><entry><title>"SystemVerilog: Constrained Random"</title><link href="http://lizard-spock.co.uk/systemverilog-constrained-random.html" rel="alternate"></link><published>2015-02-18T17:01:56+00:00</published><updated>2015-02-18T17:01:56+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-02-18:/systemverilog-constrained-random.html</id><summary type="html">&lt;p&gt;A minimal example of constrained random to constraining a 4 bit value to 0 to 11 when randomised.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tb …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;A minimal example of constrained random to constraining a 4 bit value to 0 to 11 when randomised.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cr_example_t&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;rand&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;constrain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;sel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;endclass&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;cr_example_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cr_example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;initial&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;test_program&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;cr_example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;randomise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cr_example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cr_example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="n"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;endmodule&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Verilog"></category><category term="SystemVerilog"></category><category term="Verification"></category></entry><entry><title>"Verilog: Thermometer Code"</title><link href="http://lizard-spock.co.uk/verilog-thermometer-code.html" rel="alternate"></link><published>2015-02-18T16:51:43+00:00</published><updated>2015-02-18T16:51:43+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-02-18:/verilog-thermometer-code.html</id><summary type="html">&lt;p&gt;Efficiently create a [thermometer code][wiki] in verilog:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;localparam&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;M&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;32&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="cp"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;therm_code&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$clog2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mi"&gt;0 …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Efficiently create a [thermometer code][wiki] in verilog:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;localparam&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;M&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;32&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="cp"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;therm_code&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$clog2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="cp"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;val&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Verilog"></category></entry><entry><title>"Vim: Macro"</title><link href="http://lizard-spock.co.uk/vim-macro.html" rel="alternate"></link><published>2015-02-18T16:41:40+00:00</published><updated>2015-02-18T16:41:40+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-02-18:/vim-macro.html</id><summary type="html">&lt;p&gt;When &lt;code&gt;.&lt;/code&gt; just will not do (repeats last action) because you need to capture  a movement as well, macros are quick …&lt;/p&gt;</summary><content type="html">&lt;p&gt;When &lt;code&gt;.&lt;/code&gt; just will not do (repeats last action) because you need to capture  a movement as well, macros are quick to create and use.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;q&amp;lt;number&amp;gt;&amp;lt;actions&amp;gt;q
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Replay macro&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;@&amp;lt;number&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Replay macro 10 times&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Example
Yank and put line, then repeat 10 times.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;q1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;yyP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;

&lt;span class="mi"&gt;10@1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Unix &amp; Tools"></category><category term="Vim"></category></entry><entry><title>"Find your ruby gems path"</title><link href="http://lizard-spock.co.uk/find-your-ruby-gems-path.html" rel="alternate"></link><published>2015-02-18T16:39:32+00:00</published><updated>2015-02-18T16:39:32+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2015-02-18:/find-your-ruby-gems-path.html</id><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt; ruby -r rubygems -e &amp;quot;p Gem.path&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From &lt;a href="http://gilesbowkett.blogspot.co.uk/2009/06/find-your-ruby-gems-path.html"&gt;Giles Bowkett&lt;/a&gt;.&lt;/p&gt;</content><category term="Programming"></category><category term="Ruby"></category></entry><entry><title>"Bread: Doves Gluten free"</title><link href="http://lizard-spock.co.uk/bread-doves-gluten-free.html" rel="alternate"></link><published>2014-12-21T20:12:44+00:00</published><updated>2014-12-21T20:12:44+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-12-21:/bread-doves-gluten-free.html</id><summary type="html">&lt;p&gt;For use with the Panasonic Bread Maker SD-2501 &amp;amp; SD-2500.&lt;br&gt;
&lt;strong&gt;&lt;a href="http://www.lakeland.co.uk/content/documents/Panasonic_Bread_Maker_Instructions_15352.pdf"&gt;Online Manual&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Gluten Recipes can not use timer function.&lt;/p&gt;
&lt;p&gt;For best …&lt;/p&gt;</summary><content type="html">&lt;p&gt;For use with the Panasonic Bread Maker SD-2501 &amp;amp; SD-2500.&lt;br&gt;
&lt;strong&gt;&lt;a href="http://www.lakeland.co.uk/content/documents/Panasonic_Bread_Maker_Instructions_15352.pdf"&gt;Online Manual&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Gluten Recipes can not use timer function.&lt;/p&gt;
&lt;p&gt;For best results follow this order of ingredients: &lt;br&gt;
water, salt, fat, gluten free bread mix.&lt;/p&gt;
&lt;h2&gt;Doves Farm Gluten Free (Panasonic recipe)&lt;/h2&gt;
&lt;p&gt;SD-2501 Menu 12&lt;br&gt;
 SD-2500 Menu 11&lt;/p&gt;
&lt;p&gt;Dark Crust (1hr 55min)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;Water&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="mi"&gt;320&lt;/span&gt;&lt;span class="nv"&gt;ml&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;330&lt;/span&gt;&lt;span class="nv"&gt;ml&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Brown&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;flour&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;Cider&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Vinegar&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;teaspoon&lt;/span&gt;
&lt;span class="nv"&gt;Salt&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;teaspoon&lt;/span&gt;
&lt;span class="nv"&gt;Vegtable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Oil&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tablespoon&lt;/span&gt;
&lt;span class="nv"&gt;Medium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Egg&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nv"&gt;Medium&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Egg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;White&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nv"&gt;Sugar&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;tablespoon&lt;/span&gt;
&lt;span class="nv"&gt;Flour&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="nv"&gt;g&lt;/span&gt;
&lt;span class="nv"&gt;Yeast&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;teaspoon&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;&lt;a href="http://www.dovesfarm.co.uk/recipes/gluten-free-white-bread-for-bread-machines"&gt;Doves farm recommends these ingredients&lt;/a&gt;:&lt;/h2&gt;
&lt;p&gt;SD-2501 Menu 12&lt;br&gt;
 SD-2500 Menu 11&lt;/p&gt;
&lt;p&gt;Dark Crust (1hr 55min)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;         Medium        Large
Milk     310g          465g
Vinegar  1 teaspoon    1.5 teaspoon
Oil      6 tablespoon  9   tablespoon
Eggs     2             3
Flour    450g          675g
Salt     1 teaspoon    1.5 teaspoon
Sugar    2 tablespoon  3   tablespoon
Yeast    2 teaspoon    3   teaspoon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Mix milk, vinegar, oil and eggs. Pour into the bread machine.&lt;/li&gt;
&lt;li&gt;Add flour, salt and sugar, stir.&lt;/li&gt;
&lt;li&gt;Sprinkle Yeast on top&lt;/li&gt;
&lt;li&gt;Start machine, pausing after a few minutes to scrape down the sides.&lt;/li&gt;
&lt;li&gt;Resume programme until completion&lt;/li&gt;
&lt;/ol&gt;</content><category term="Home &amp; Garden"></category><category term="Recipe"></category><category term="Bread"></category><category term="Gluten Free"></category><category term="Cooking"></category></entry><entry><title>"Verilog: Calculate primes"</title><link href="http://lizard-spock.co.uk/verilog-calculate-primes.html" rel="alternate"></link><published>2014-12-20T07:28:41+00:00</published><updated>2014-12-20T07:28:41+00:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-12-20:/verilog-calculate-primes.html</id><summary type="html">&lt;p&gt;Based on my answer to &lt;a href="http://stackoverflow.com/q/27461173/97073"&gt;this SO Question&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.mathsisfun.com/definitions/prime-number.html"&gt;Definition of Prime&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A Prime Number can be divided evenly only by …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;Based on my answer to &lt;a href="http://stackoverflow.com/q/27461173/97073"&gt;this SO Question&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.mathsisfun.com/definitions/prime-number.html"&gt;Definition of Prime&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A Prime Number can be divided evenly only by 1, or itself. 
And it must be a whole number greater than 1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A simple method would be to iterate over numbers 2 to N, checking if it was divisible by all natural numbers greater than 2, and below the current value.&lt;/p&gt;
&lt;p&gt;Once checked that it is not divisible by 2 there is not point checking for 4, 6, 8 etc. 
Remembering the definition of prime all numbers that are not prime are integer multiples of prime. so we have reduced the amount of work involved in testing primality.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;parameter&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;
&lt;span class="n"&gt;reg&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;31:0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;prime_number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;0:N-1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Store&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;prime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;
&lt;span class="k"&gt;integer&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;primality&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;
&lt;span class="k"&gt;integer&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Currently&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;looking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;th prime &lt;/span&gt;
&lt;span class="s1"&gt;integer          index    ; // Counts 1 to k, indexing previous primes &lt;/span&gt;
&lt;span class="s1"&gt;integer          number_ut; // Number Under test&lt;/span&gt;

&lt;span class="s1"&gt;reg        [1:0] state   ; &lt;/span&gt;
&lt;span class="s1"&gt;localparam       S_INC   = 2&amp;#39;&lt;/span&gt;&lt;span class="n"&gt;b01&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;localparam&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;S_CHECK&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;b10;&lt;/span&gt;

&lt;span class="s1"&gt;initial begin&lt;/span&gt;
&lt;span class="s1"&gt;  prime_number[0] = &amp;#39;&lt;/span&gt;&lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;Preload&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Prime&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S_CHECK&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;Check&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;first&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;number_ut&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;d3; // Number Under Test&lt;/span&gt;
&lt;span class="s1"&gt;  k               = &amp;#39;&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Position&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;preloaded&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;d0;&lt;/span&gt;
&lt;span class="s1"&gt;  test            = &amp;#39;&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;always&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posedge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S_INC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;number_ut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number_ut&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S_CHECK&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;d0;&lt;/span&gt;
&lt;span class="s1"&gt;    test      &amp;lt;= &amp;#39;&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Safe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S_CHECK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Prime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exact&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;divisor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;Reject %3d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number_ut&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S_INC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;Passed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Prime&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;check&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="k"&gt;Use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;nd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;etc&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;&amp;quot;Found the %1d th Prime, it is %1d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number_ut&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;prime_number&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number_ut&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S_INC&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number_ut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;prime_number&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;index&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.edaplayground.com/x/BzX"&gt;Example on EDA Playground&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is however just a programming exercise as the resulting hardware is likely substantially bigger than just implementing a look up table to the maxim number of primes you can fit in &lt;code&gt;prime_number&lt;/code&gt;. The look up table will also be ready from time zero and not need to recompute every time you power up.&lt;/p&gt;</content><category term="Engineering"></category><category term="Math"></category><category term="Verilog"></category></entry><entry><title>"tcsh Remove trailing /"</title><link href="http://lizard-spock.co.uk/tcsh-remove-trailing.html" rel="alternate"></link><published>2014-10-08T21:15:43+01:00</published><updated>2014-10-08T21:15:43+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-10-08:/tcsh-remove-trailing.html</id><summary type="html">&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/tcsh&lt;/span&gt;

&lt;span class="nb"&gt;set &lt;/span&gt;&lt;span class="nv"&gt;var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;helloworld/&amp;quot;&lt;/span&gt;

&lt;span class="c"&gt;## http://dbaspot.com/shell/350417-sed-removing-trailing.html&lt;/span&gt;
&lt;span class="nb"&gt;set …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;
&lt;span class="normal"&gt;5&lt;/span&gt;
&lt;span class="normal"&gt;6&lt;/span&gt;
&lt;span class="normal"&gt;7&lt;/span&gt;
&lt;span class="normal"&gt;8&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/tcsh&lt;/span&gt;

&lt;span class="nb"&gt;set &lt;/span&gt;&lt;span class="nv"&gt;var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;helloworld/&amp;quot;&lt;/span&gt;

&lt;span class="c"&gt;## http://dbaspot.com/shell/350417-sed-removing-trailing.html&lt;/span&gt;
&lt;span class="nb"&gt;set &lt;/span&gt;&lt;span class="nv"&gt;var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;$var&amp;quot;&lt;/span&gt; | sed -e &lt;span class="s1"&gt;&amp;#39;s,\(.\)/$,\1,&amp;#39;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$var&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;</content><category term="Unix &amp; Tools"></category></entry><entry><title>"F-Stop Loka &amp; Tripod"</title><link href="http://lizard-spock.co.uk/f-stop-loka-tripod.html" rel="alternate"></link><published>2014-09-18T11:28:47+01:00</published><updated>2014-09-18T11:28:47+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-09-18:/f-stop-loka-tripod.html</id><summary type="html">&lt;p&gt;F-stop Loka with side mounted Manfrotto 055XPROB (3 stage carbon), with a Manfrotto 488 rc2 head.&lt;/p&gt;
&lt;p _="%" _images_Photography_Loka_morganp-20140416-Loka-_MG_7449.jpg="/images/Photography/Loka/morganp-20140416-Loka-_MG_7449.jpg" centre img&gt;{% img centre /images/Photography …&lt;/p&gt;</summary><content type="html">&lt;p&gt;F-stop Loka with side mounted Manfrotto 055XPROB (3 stage carbon), with a Manfrotto 488 rc2 head.&lt;/p&gt;
&lt;p _="%" _images_Photography_Loka_morganp-20140416-Loka-_MG_7449.jpg="/images/Photography/Loka/morganp-20140416-Loka-_MG_7449.jpg" centre img&gt;{% img centre /images/Photography/Loka/morganp-20140416-Loka-_MG_7445.jpg %}&lt;/p&gt;
&lt;p&gt;Tripod relatively secure in this position, although if not tightly strapped down movement does loosen the straps.&lt;/p&gt;
&lt;p&gt;NB: also a thinktank skin 50 mounted on the hip belt.&lt;/p&gt;</content><category term="Photography"></category><category term="fstop"></category></entry><entry><title>"Command line bulk file rename"</title><link href="http://lizard-spock.co.uk/command-line-bulk-file-rename.html" rel="alternate"></link><published>2014-09-05T18:06:05+01:00</published><updated>2014-09-05T18:06:05+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-09-05:/command-line-bulk-file-rename.html</id><summary type="html">&lt;p&gt;To prepend to to filenames&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cd to_folder
ls | xargs -I {} mv {} addthis-{}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or target jpgs&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cd to_folder
ls *.jpg | xargs …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;To prepend to to filenames&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cd to_folder
ls | xargs -I {} mv {} addthis-{}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or target jpgs&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cd to_folder
ls *.jpg | xargs -I {} mv {} addthis-{}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;http://www.peteryu.ca/tutorials/shellscripting/batch_rename&lt;/p&gt;</content><category term="Unix &amp; Tools"></category><category term="Command Line"></category></entry><entry><title>"Word WORD the Difference"</title><link href="http://lizard-spock.co.uk/word-word-the-difference.html" rel="alternate"></link><published>2014-08-19T06:27:30+01:00</published><updated>2014-08-19T06:27:30+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-08-19:/word-word-the-difference.html</id><summary type="html">&lt;p&gt;Just realised there is a difference between word and WORD in Vim.&lt;/p&gt;
&lt;p&gt;WORD is non-blank delimited by whitespace.
word is …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Just realised there is a difference between word and WORD in Vim.&lt;/p&gt;
&lt;p&gt;WORD is non-blank delimited by whitespace.
word is alpha-numeric and other non-blank characters delimited by whitespace and punctuation. 'iskeyword' can be used to move delimiters in to part of the selection of the word.&lt;/p&gt;
&lt;p&gt;by default :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;this-is-four-words
this-is-one-WORD
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Unix &amp; Tools"></category><category term="Vim"></category></entry><entry><title>"List files ignored by git"</title><link href="http://lizard-spock.co.uk/list-files-ignored-by-git.html" rel="alternate"></link><published>2014-07-30T20:18:07+01:00</published><updated>2014-07-30T20:18:07+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-07-30:/list-files-ignored-by-git.html</id><content type="html">&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4VBG9FlyiOw"&gt;From Github Training &amp;amp; Guides&lt;/a&gt;.  &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git ls-files --others --ignored --exclude-standard
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Unix &amp; Tools"></category><category term="Git"></category></entry><entry><title>"xkill"</title><link href="http://lizard-spock.co.uk/xkill.html" rel="alternate"></link><published>2014-07-30T20:16:39+01:00</published><updated>2014-07-30T20:16:39+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-07-30:/xkill.html</id><summary type="html">&lt;p&gt;I just discovered the &lt;code&gt;xkill&lt;/code&gt; command, when a window has crashed you
can call xkill and get a skull and …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I just discovered the &lt;code&gt;xkill&lt;/code&gt; command, when a window has crashed you
can call xkill and get a skull and crossbones cursor to kill the application.&lt;/p&gt;
&lt;p&gt;It even works well with remote GUI applications (Sun Grid Engine SGE).&lt;/p&gt;</content><category term="Unix &amp; Tools"></category><category term="SGE"></category></entry><entry><title>"Submit to SGE as if working locally"</title><link href="http://lizard-spock.co.uk/submit-to-sge-as-if-working-locally.html" rel="alternate"></link><published>2014-07-30T20:13:23+01:00</published><updated>2014-07-30T20:13:23+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-07-30:/submit-to-sge-as-if-working-locally.html</id><summary type="html">&lt;p&gt;Setting an alias in you .tcshrc&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;alias qrun &amp;#39;qrsh -V -noshell -cwd !*&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or bash &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;alias qrun=&amp;#39;qrsh -V -noshell -cwd …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Setting an alias in you .tcshrc&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;alias qrun &amp;#39;qrsh -V -noshell -cwd !*&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;or bash &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;alias qrun=&amp;#39;qrsh -V -noshell -cwd !*&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which makes submitting any script to the grid just:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;qrun helloworld.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Originally asked on &lt;a href="http://superuser.com/a/751162/42141"&gt;superuser&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="SGE"></category><category term="Bash"></category></entry><entry><title>"Simulink: Scroll wheel erratic behaviour"</title><link href="http://lizard-spock.co.uk/simulink-scroll-wheel-erratic-behaviour.html" rel="alternate"></link><published>2014-07-30T20:08:10+01:00</published><updated>2014-07-30T20:08:10+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-07-30:/simulink-scroll-wheel-erratic-behaviour.html</id><summary type="html">&lt;p&gt;On Mac OS X matlab behaves quite oddly with the track pad zooming
in and out very quickly and erratically …&lt;/p&gt;</summary><content type="html">&lt;p&gt;On Mac OS X matlab behaves quite oddly with the track pad zooming
in and out very quickly and erratically to remove this behaviour
&lt;strong&gt;Disable Mouse Scroll Wheel Zoom Behavior&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To disable the zoom behavior for the scroll wheel:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;File &amp;gt; 
  Simulink Preferences &amp;gt; 
    Editor Defaults &amp;gt; 
      Scroll wheel controls zooming preference.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you hold the Ctrl key and use the scroll wheel, the scroll wheel behavior is the opposite of how the preference is set. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.mathworks.co.uk/help/simulink/ug/zooming-block-diagrams.html"&gt;source&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Simulink"></category><category term="Matlab"></category></entry><entry><title>"Matlab editor no tabs"</title><link href="http://lizard-spock.co.uk/matlab-editor-no-tabs.html" rel="alternate"></link><published>2014-07-30T20:04:15+01:00</published><updated>2014-07-30T20:04:15+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-07-30:/matlab-editor-no-tabs.html</id><summary type="html">&lt;p&gt;Matlab always use to open text files in tabs in the same editor window. When switching to 2014a documents started …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Matlab always use to open text files in tabs in the same editor window. When switching to 2014a documents started opening as separate windows.&lt;/p&gt;
&lt;p&gt;It seems to have been a problem which &lt;a href="http://www.mathworks.co.uk/matlabcentral/answers/9587-editor-multiple-tabs"&gt;occasionally shows up for others&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Current solution is to dock the editor (ctrl-shift-D) , open multiple files (2 or more) then undock the group (ctrl-shift-U).&lt;/p&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Simulink: Globally set sample time"</title><link href="http://lizard-spock.co.uk/simulink-globally-set-sample-time.html" rel="alternate"></link><published>2014-07-30T20:01:49+01:00</published><updated>2014-07-30T20:01:49+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-07-30:/simulink-globally-set-sample-time.html</id><summary type="html">&lt;p&gt;To set each constant in a model to sample time -1:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;blks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;find_system&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;dut&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BlockType&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Constant&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;length …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;To set each constant in a model to sample time -1:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;blks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;find_system&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;dut&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;BlockType&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Constant&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;length&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;blks&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;set_param&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;blks&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;SampleTime&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;-1&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.mathworks.co.uk/help/hdlcoder/ug/resource-sharing.html#btg_5ht-1"&gt;Source&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Matlab"></category><category term="Simulink"></category></entry><entry><title>"Simulink: list programmable block properties"</title><link href="http://lizard-spock.co.uk/simulink-list-programmable-block-properties.html" rel="alternate"></link><published>2014-07-30T20:00:28+01:00</published><updated>2014-07-30T20:00:28+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-07-30:/simulink-list-programmable-block-properties.html</id><summary type="html">&lt;p&gt;Select a block ie gain in Simulink then in Matlab type:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;get(gcbh)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This shows the list of properties which …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Select a block ie gain in Simulink then in Matlab type:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;get(gcbh)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This shows the list of properties which can be controlled from Matlab. TO change one for example changing the gain paramter from double to a 10 bit fixed point number (&lt;code&gt;sfix10_en9&lt;/code&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;set_param(gcbh, &amp;#39;ParamDataTypeStr&amp;#39;, &amp;#39;fixdt(1,10,9)&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.mathworks.co.uk/matlabcentral/newsreader/view_thread/306640"&gt;From Matlab Central&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Simulink"></category><category term="Matlab"></category></entry><entry><title>"Matlab: Find all gain blocks"</title><link href="http://lizard-spock.co.uk/matlab-find-all-gain-blocks.html" rel="alternate"></link><published>2014-07-30T19:58:53+01:00</published><updated>2014-07-30T19:58:53+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-07-30:/matlab-find-all-gain-blocks.html</id><summary type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find_system(&amp;#39;BlockType&amp;#39;, &amp;#39;Gain&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will list all gain blocks in currently loaded models. to limit to a particulat model:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find_system …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find_system(&amp;#39;BlockType&amp;#39;, &amp;#39;Gain&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will list all gain blocks in currently loaded models. to limit to a particulat model:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;find_system(&amp;#39;testharness&amp;#39;, &amp;#39;BlockType&amp;#39;, &amp;#39;Gain&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.mathworks.co.uk/help/simulink/slref/find_system.html"&gt;From Mathworks&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Matlab"></category><category term="Simulink"></category></entry><entry><title>"error: storage class specified for parameter"</title><link href="http://lizard-spock.co.uk/error-storage-class-specified-for-parameter.html" rel="alternate"></link><published>2014-06-19T20:42:33+01:00</published><updated>2014-06-19T20:42:33+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-06-19:/error-storage-class-specified-for-parameter.html</id><summary type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;specified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://stackoverflow.com/q/3676969/97073"&gt;There is probably a missing semicolon &lt;code&gt;;&lt;/code&gt; in a header file!&lt;/a&gt; Just written my first …&lt;/p&gt;</summary><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;specified&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://stackoverflow.com/q/3676969/97073"&gt;There is probably a missing semicolon &lt;code&gt;;&lt;/code&gt; in a header file!&lt;/a&gt; Just written my first C Header and received the above warning. It was indeed due to a missing semicolon.&lt;/p&gt;</content><category term="Programming"></category><category term="C"></category></entry><entry><title>"Shell redirection"</title><link href="http://lizard-spock.co.uk/shell-redirection.html" rel="alternate"></link><published>2014-06-19T20:10:57+01:00</published><updated>2014-06-19T20:10:57+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-06-19:/shell-redirection.html</id><summary type="html">&lt;p&gt;To redirect stdout and stderr in bash we use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./ShellFile.sh &amp;amp;&amp;gt; test.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However in tcsh that results in: &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Invalid …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;To redirect stdout and stderr in bash we use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./ShellFile.sh &amp;amp;&amp;gt; test.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However in tcsh that results in: &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Invalid null command.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Switch the order of &lt;code&gt;&amp;amp;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; in tcsh :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./ShellFile.sh &amp;gt;&amp;amp; test.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Unix &amp; Tools"></category><category term="Bash"></category><category term="Tcsh"></category><category term="Command Line"></category></entry><entry><title>"Floating Point Arithmetic is not Associative"</title><link href="http://lizard-spock.co.uk/floating-point-arithmetic-is-not-associative.html" rel="alternate"></link><published>2014-06-19T20:00:45+01:00</published><updated>2014-06-19T20:00:45+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-06-19:/floating-point-arithmetic-is-not-associative.html</id><summary type="html">&lt;p&gt;This can be shown with some easy examples:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;2 …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;This can be shown with some easy examples:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%.20f&amp;#39;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Display&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;fractional&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;places&lt;/span&gt;
&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;%.20f&amp;#39;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;b&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;ans&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;60000000000000008882&lt;/span&gt;

&lt;span class="nv"&gt;ans&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;.&lt;span class="mi"&gt;59999999999999997780&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Multiplication examples:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;c = 0.1 &lt;span class="gs"&gt;*  0.2 *&lt;/span&gt; 0.3 ;
d = 0.1 &lt;span class="gs"&gt;* (0.2 *&lt;/span&gt; 0.3);

sprintf(&amp;#39;%.20f&amp;#39;, c)
sprintf(&amp;#39;%.20f&amp;#39;, d)

ans =
0.00600000000000000099

ans =
0.00600000000000000012
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By default gcc will not rearrange equations for optimal performance as this would change the accuracy.
The GCC flag &lt;code&gt;-ffast-math&lt;/code&gt; optimizes equations as if they were associative.&lt;/p&gt;
&lt;p&gt;The examples shown here were found on &lt;a href="https://news.ycombinator.com/item?id=7479550"&gt;Hacker News&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Adobe Creative Cloud is ..."</title><link href="http://lizard-spock.co.uk/adobe-creative-cloud-is.html" rel="alternate"></link><published>2014-06-19T18:15:59+01:00</published><updated>2014-06-19T18:15:59+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-06-19:/adobe-creative-cloud-is.html</id><summary type="html">&lt;p&gt;Inconsistent, annoying, &lt;strong&gt;cheap&lt;/strong&gt;?&lt;/p&gt;
&lt;!-- more --&gt;

&lt;p&gt;My main bugbear with the creative cloud application is the way it updates applications.
Photoshop CC and …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Inconsistent, annoying, &lt;strong&gt;cheap&lt;/strong&gt;?&lt;/p&gt;
&lt;!-- more --&gt;

&lt;p&gt;My main bugbear with the creative cloud application is the way it updates applications.
Photoshop CC and Lightroom are handled differently.&lt;/p&gt;
&lt;p&gt;Photoshop switches from installed to update. Which is great it will pull in the update on my command.&lt;/p&gt;
&lt;p&gt;Lightroom switches from Installed to &lt;strong&gt;Try&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Not only that but I have now have 2 version of Photoshop CC and CC (2014) ready
for updates, one of which has not already been installed.&lt;/p&gt;
&lt;p&gt;SO I have 2 applications with updates ready, one wants an update the other refuses
to acknowledge it has been installed and wants a new install. A new program,
Photoshop CC (2014), which only requires an update.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Adobe Creative Cloud update inconsistency" src="/images/Photography/CC_update.png" title="Adobe Creative Cloud is Inconsistent"&gt;&lt;/p&gt;</content><category term="Photography"></category><category term="Creative Cloud"></category><category term="Lightroom"></category></entry><entry><title>"Octopress categories with different styles"</title><link href="http://lizard-spock.co.uk/octopress-categories-with-different-styles.html" rel="alternate"></link><published>2014-06-14T08:24:01+01:00</published><updated>2014-06-14T08:24:01+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-06-14:/octopress-categories-with-different-styles.html</id><summary type="html">&lt;p&gt;As I use the code blocks for ingredient lists on my recipe pages I wanted to 
have a different style …&lt;/p&gt;</summary><content type="html">&lt;p&gt;As I use the code blocks for ingredient lists on my recipe pages I wanted to 
have a different style, lighter background instead of black.&lt;/p&gt;
&lt;p&gt;I currently manually set a different layout in the _post header:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;
&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Tech&lt;/span&gt;

&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;recipe&lt;/span&gt;
&lt;span class="n"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Cooking&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;!-- more --&gt;

&lt;p&gt;The layout will then look for a matching layout in &lt;code&gt;source/_layouts&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Manually create your new layout (instructions from top level Octopress site):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;cp source/_layouts/post.html source/_layouts/recipe.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Edit &lt;code&gt;source/_layouts/recipe.html&lt;/code&gt; changing the role to &lt;code&gt;recipe&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="nv"&gt;layout&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;default&lt;/span&gt;
&lt;span class="nv"&gt;single&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;article&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;hentry&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;recipe&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;\{\&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;article&lt;/span&gt;.&lt;span class="nv"&gt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;\&lt;span class="o"&gt;%&lt;/span&gt;\}
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;footer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;meta&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will now pick up the styling that &lt;code&gt;post&lt;/code&gt; also gets but we can target our modifications to &lt;code&gt;article[role="recipe"]&lt;/code&gt;.
For custom stylings apply changes in to the relevant file in &lt;code&gt;sass/custom/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To modify the background colour of a code block&lt;br&gt;
&lt;code&gt;sass/custom/_styles.scss&lt;/code&gt; add:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Customise the recipe layout&lt;/span&gt;
&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;recipe&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pre&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;$&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;NB: &lt;code&gt;$sidebar-bg&lt;/code&gt; is defined in &lt;code&gt;sass/base/_theme.scss&lt;/code&gt;&lt;/p&gt;</content><category term="Programming"></category><category term="Octopress"></category></entry><entry><title>"Verilog: Timeout"</title><link href="http://lizard-spock.co.uk/verilog-timeout.html" rel="alternate"></link><published>2014-06-14T08:08:26+01:00</published><updated>2014-06-14T08:08:26+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-06-14:/verilog-timeout.html</id><summary type="html">&lt;p&gt;To wait for a maximum of &lt;code&gt;10ns&lt;/code&gt; for positive edge on clk then carry on with simulation.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wait_or_timeout&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;begin …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;To wait for a maximum of &lt;code&gt;10ns&lt;/code&gt; for positive edge on clk then carry on with simulation.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;fork&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wait_or_timeout&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;disable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wait_or_timeout&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posedge&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;clk&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;disable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;wait_or_timeout&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;join&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Often use to fail simulation if the expected signal does not occur,
this stops simulation hanging and allows status reports to be generated.&lt;/p&gt;
&lt;p&gt;Originally posted as &lt;a href="http://stackoverflow.com/a/12372233/97073"&gt;SO answer&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Verilog"></category></entry><entry><title>"Matlab Remove Elements from Array"</title><link href="http://lizard-spock.co.uk/matlab-remove-elements-from-array.html" rel="alternate"></link><published>2014-06-02T19:08:09+01:00</published><updated>2014-06-02T19:08:09+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-06-02:/matlab-remove-elements-from-array.html</id><summary type="html">&lt;p&gt;Removing elements based on index&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;A&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;10&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1-D&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;array&lt;/span&gt;
&lt;span class="nt"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;3&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;4&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;5&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;6&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;7&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;8&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;9 …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Removing elements based on index&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;A&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;10&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1-D&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;array&lt;/span&gt;
&lt;span class="nt"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;3&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;4&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;5&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;6&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;7&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;8&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;9&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;10&lt;/span&gt;

&lt;span class="nt"&gt;ind&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="cp"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;indices&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;removed&lt;/span&gt;
&lt;span class="nt"&gt;A&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ind&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;remove&lt;/span&gt;

&lt;span class="nt"&gt;A&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;3&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;5&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;6&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;8&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;9&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Based on &lt;a href="http://www.mathworks.co.uk/matlabcentral/newsreader/view_thread/1486880"&gt;Matlab Central&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Matlab: Formatting Strings"</title><link href="http://lizard-spock.co.uk/matlab-formatting-strings.html" rel="alternate"></link><published>2014-06-02T18:46:09+01:00</published><updated>2014-06-02T18:46:09+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-06-02:/matlab-formatting-strings.html</id><summary type="html">&lt;p&gt;The official documentation can be found on &lt;a href="http://www.mathworks.co.uk/help/matlab/matlab_prog/formatting-strings.html#bq0z8vc-6"&gt;mathworks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To display a number with 3 Integer decimal places and 3 fraction …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The official documentation can be found on &lt;a href="http://www.mathworks.co.uk/help/matlab/matlab_prog/formatting-strings.html#bq0z8vc-6"&gt;mathworks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To display a number with 3 Integer decimal places and 3 fraction places 
&lt;code&gt;$f7.3&lt;/code&gt; 7 rather than 6 as need place for the decimal point.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;6.3-%6.3f-&amp;#39;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;6.3-%6.3f-&amp;#39;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;6.3-%6.3f-&amp;#39;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;-ve numbers&lt;/h2&gt;
&lt;p&gt;If signed you need to leave space for -ve &lt;code&gt;$f8.3&lt;/code&gt; :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;7.3-%7.3f-&amp;#39;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;7.3-%7.3f-&amp;#39;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;8.3-%8.3f-&amp;#39;&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;.&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;23&lt;/span&gt;.&lt;span class="mi"&gt;678&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For reliable and consistent floating point displays use:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c"&gt;%(fractional places + integer places + 2).(fractional places)f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Matlab: Grid"</title><link href="http://lizard-spock.co.uk/matlab-grid.html" rel="alternate"></link><published>2014-05-28T19:49:38+01:00</published><updated>2014-05-28T19:49:38+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-05-28:/matlab-grid.html</id><summary type="html">&lt;p&gt;&lt;img alt="Matlab plot with X and Y grid" src="/images/Engineering/matlab_grid/grid_on.png"&gt;&lt;/p&gt;
&lt;p&gt;To add X and Y grids to plots :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;grid on;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;img alt="Matlab plot with Y grid only" src="/images/Engineering/matlab_grid/y_grid_on.png"&gt;&lt;/p&gt;
&lt;p&gt;To add Y only grid:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;set(gca,&amp;#39;XGrid&amp;#39;,&amp;#39;off&amp;#39;,&amp;#39;YGrid …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;&lt;img alt="Matlab plot with X and Y grid" src="/images/Engineering/matlab_grid/grid_on.png"&gt;&lt;/p&gt;
&lt;p&gt;To add X and Y grids to plots :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;grid on;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;!-- more --&gt;

&lt;p&gt;&lt;img alt="Matlab plot with Y grid only" src="/images/Engineering/matlab_grid/y_grid_on.png"&gt;&lt;/p&gt;
&lt;p&gt;To add Y only grid:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;set(gca,&amp;#39;XGrid&amp;#39;,&amp;#39;off&amp;#39;,&amp;#39;YGrid&amp;#39;,&amp;#39;on&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;img alt="Matlab plot with X grid only" src="/images/Engineering/matlab_grid/x_grid_on.png"&gt;&lt;/p&gt;
&lt;p&gt;To add X only grid&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;set(gca,&amp;#39;XGrid&amp;#39;,&amp;#39;on&amp;#39;,&amp;#39;YGrid&amp;#39;,’off&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Matlab: Line Breaks in Strings"</title><link href="http://lizard-spock.co.uk/matlab-line-breaks-in-strings.html" rel="alternate"></link><published>2014-05-28T19:34:30+01:00</published><updated>2014-05-28T19:34:30+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-05-28:/matlab-line-breaks-in-strings.html</id><summary type="html">&lt;p&gt;Wrap strings with &lt;code&gt;sprintf&lt;/code&gt; to allow the &lt;code&gt;\n&lt;/code&gt; to be escaped correctly.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;disp&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hello\nworld&amp;#39;&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;hello&lt;/span&gt;\&lt;span class="nv"&gt;nworld&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;disp&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hello …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Wrap strings with &lt;code&gt;sprintf&lt;/code&gt; to allow the &lt;code&gt;\n&lt;/code&gt; to be escaped correctly.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;disp&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hello\nworld&amp;#39;&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;hello&lt;/span&gt;\&lt;span class="nv"&gt;nworld&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;disp&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sprintf&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hello\nworld&amp;#39;&lt;/span&gt;&lt;span class="ss"&gt;))&lt;/span&gt;
&lt;span class="nv"&gt;hello&lt;/span&gt;
&lt;span class="nv"&gt;world&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Matlab: Listing field name values of a struct"</title><link href="http://lizard-spock.co.uk/matlab-listing-field-name-values-of-a-struct.html" rel="alternate"></link><published>2014-05-28T19:05:01+01:00</published><updated>2014-05-28T19:05:01+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-05-28:/matlab-listing-field-name-values-of-a-struct.html</id><summary type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;s = struct ;
s(1).dat =‘a&amp;#39; ;
s(1).freq=11 ;
s(2).dat =‘b&amp;#39; ;
s(2).freq=22 ;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Where:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;s …&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;s = struct ;
s(1).dat =‘a&amp;#39; ;
s(1).freq=11 ;
s(2).dat =‘b&amp;#39; ;
s(2).freq=22 ;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Where:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;s(1)

ans =

     dat: &amp;#39;a&amp;#39;
    freq: 11
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;How do you access [‘a’, ‘b’] and [11, 22]?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[s.dat] , [s.freq]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;[]&lt;/code&gt; are really important here.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[s.freq]&lt;/span&gt;

&lt;span class="na"&gt;ans&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="na"&gt;11    22&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="http://blogs.mathworks.com/loren/2007/04/19/vectorizing-access-to-an-array-of-structures/"&gt;Solution found on a Loren Post&lt;/a&gt;.&lt;/p&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"F-Stop ICU Strobies"</title><link href="http://lizard-spock.co.uk/f-stop-icu-strobies.html" rel="alternate"></link><published>2014-05-28T18:44:55+01:00</published><updated>2014-05-28T18:44:55+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-05-28:/f-stop-icu-strobies.html</id><summary type="html">&lt;p&gt;My large ICU loaded with my &lt;a href="http://www.wexphotographic.com/buy-interfit-strobies-portrait-kit/p1031888"&gt;Strobies portrait kit&lt;/a&gt; and Canon 580EX MKII.&lt;/p&gt;
&lt;p&gt;&lt;img alt="F Stop" src="/images/Photography/fstop_icu_large_lighting/morganp-20140517-FStop-_MG_8927.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The collapsed soft box is folded into …&lt;/p&gt;</summary><content type="html">&lt;p&gt;My large ICU loaded with my &lt;a href="http://www.wexphotographic.com/buy-interfit-strobies-portrait-kit/p1031888"&gt;Strobies portrait kit&lt;/a&gt; and Canon 580EX MKII.&lt;/p&gt;
&lt;p&gt;&lt;img alt="F Stop" src="/images/Photography/fstop_icu_large_lighting/morganp-20140517-FStop-_MG_8927.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The collapsed soft box is folded into the right hand side. Additional accessories are a &lt;a href="https://www.amazon.co.uk/dp/B0007DDK7A?tag=morgue-21&amp;amp;camp=2902&amp;amp;creative=19466&amp;amp;linkCode=as4&amp;amp;creativeASIN=B0007DDK7A&amp;amp;adid=1VSQ11QZRMHHASH7FHN9&amp;amp;"&gt;3M Lastolite off camera cord&lt;/a&gt;, &lt;a href="https://www.amazon.co.uk/dp/B002D4AHT0?tag=morgue-21&amp;amp;camp=2902&amp;amp;creative=19466&amp;amp;linkCode=as4&amp;amp;creativeASIN=B002D4AHT0&amp;amp;adid=0PB41F04SGBY01WKVJYB&amp;amp;"&gt;Colorvision SpyderCube&lt;/a&gt; and a &lt;a href="https://www.amazon.co.uk/dp/B0007DDK7A?tag=morgue-21&amp;amp;camp=2902&amp;amp;creative=19466&amp;amp;linkCode=as4&amp;amp;creativeASIN=B0007DDK7A&amp;amp;adid=1VSQ11QZRMHHASH7FHN9&amp;amp;"&gt;Stofen&lt;/a&gt;.&lt;/p&gt;</content><category term="Photography"></category><category term="fstop"></category><category term="Canon"></category></entry><entry><title>"Kettlebell Rack"</title><link href="http://lizard-spock.co.uk/kettlebell-rack.html" rel="alternate"></link><published>2014-05-28T18:32:43+01:00</published><updated>2014-05-28T18:32:43+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-05-28:/kettlebell-rack.html</id><content type="html">&lt;p&gt;&lt;img alt="DIY" src="/images/Home/KettlebellRack/morganp-20140518-diy-_MG_8954.jpg"&gt;
Kettlebell rack with 24kg, 16kg, 8kg, 12kg, 16kg, 20kg.&lt;/p&gt;
&lt;p&gt;&lt;img alt="DIY" src="/images/Home/KettlebellRack/morganp-20140518-diy-_MG_8960.jpg"&gt;
End detail showing bracing.&lt;/p&gt;
&lt;p&gt;&lt;img alt="DIY" src="/images/Home/KettlebellRack/morganp-20140518-diy-_MG_8968.jpg"&gt;
Underside of rack.&lt;/p&gt;</content><category term="Home &amp; Garden"></category><category term="Kettlebell"></category><category term="Woodwork"></category></entry><entry><title>"Matlab toolboxes with absolute path setup"</title><link href="http://lizard-spock.co.uk/matlab-toolboxes-with-absolute-path-setup.html" rel="alternate"></link><published>2014-05-07T18:22:48+01:00</published><updated>2014-05-07T18:22:48+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-05-07:/matlab-toolboxes-with-absolute-path-setup.html</id><summary type="html">&lt;p&gt;When a script or function is called with &lt;code&gt;run(./relative/path/script)&lt;/code&gt; the working directory is changed to the &lt;code&gt;./relative …&lt;/code&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;When a script or function is called with &lt;code&gt;run(./relative/path/script)&lt;/code&gt; the working directory is changed to the &lt;code&gt;./relative/path&lt;/code&gt;. This means &lt;code&gt;pwd&lt;/code&gt; it can be used to specify absolute paths:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;./&lt;/span&gt;&lt;span class="n"&gt;libs&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;example_toolbox&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;load_toolbox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which contains :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;addpath([pwd, &amp;#39;/function&amp;#39;]);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now  The path will contain &lt;code&gt;C:/ ... /libs/example_toolbox/function&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;As shown in the example this is useful for toolboxes etc which could be distributed with a top level script which adds the toolbox functions on to the path.&lt;/p&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Matlab: Array content check"</title><link href="http://lizard-spock.co.uk/matlab-array-content-check.html" rel="alternate"></link><published>2014-05-07T18:13:24+01:00</published><updated>2014-05-07T18:13:24+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-05-07:/matlab-array-content-check.html</id><summary type="html">&lt;p&gt;Checking if an Array contains a number:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;input = [1,2,3,4];
check = 4;
any(input==4)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Check if a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Checking if an Array contains a number:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;input = [1,2,3,4];
check = 4;
any(input==4)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Check if a number is contained in an array:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;input = 32;
check = [32,64,128];
any( check==input )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry><entry><title>"Matlab: Split Odd &amp; Even Array Elements"</title><link href="http://lizard-spock.co.uk/matlab-split-odd-even-array-elements.html" rel="alternate"></link><published>2014-05-07T17:58:33+01:00</published><updated>2014-05-07T17:58:33+01:00</updated><author><name>morganp</name></author><id>tag:lizard-spock.co.uk,2014-05-07:/matlab-split-odd-even-array-elements.html</id><summary type="html">&lt;p&gt;Using Matlab to splitting data into odd and even samples.&lt;/p&gt;
&lt;p&gt;A for loop approach:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;data_odd&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="n"&gt;data_even&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;length …&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;Using Matlab to splitting data into odd and even samples.&lt;/p&gt;
&lt;p&gt;A for loop approach:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;data_odd&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="n"&gt;data_even&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c"&gt;%% disp(&amp;#39;odd&amp;#39;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;data_odd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;data_odd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c"&gt;%% disp(&amp;#39;even&amp;#39;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;data_even&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;data_even&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Matlab approach using ranges to remap values:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;data_odd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;end&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;data_even&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;data&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;end&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ranges are composed of &lt;code&gt;start_index:step_size:end_index&lt;/code&gt;. If step_size is omitted, 1 is assumed.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;end&lt;/code&gt; has a special meaning when used inside an array, it is the position of the last element.
To append to an array you could use &lt;code&gt;data(end+1) = append_value&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;No error or warning is triggered if the &lt;code&gt;end_index&lt;/code&gt; can not be reached with the given step size, which is why this works with &lt;code&gt;end&lt;/code&gt; as the stop point of both sides.&lt;/p&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;[&lt;span class="mi"&gt;1&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;]&lt;span class="c1"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;odd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;:&lt;span class="mi"&gt;2&lt;/span&gt;:&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;even&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;:&lt;span class="mi"&gt;2&lt;/span&gt;:&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;odd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="nv"&gt;even&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="Engineering"></category><category term="Matlab"></category></entry></feed>