Learn digital logic design from Boolean minimization to VHDL, FPGA synthesis and embedded systems, with 7 hands-on FPGA lab assignments included.

Digital Logic & System Design: VHDL, FPGA & Embedded Guide

Digital Logic & System Design Concepts: Complete Course Guide

EDUNXT TECH LEARNING · Digital Logic & System Design Course Guide

Digital Logic & System Design Concepts

A complete four-part curriculum — from Boolean minimization and sequential circuits to VHDL, FPGA synthesis, embedded systems, and seven hands-on FPGA laboratory assignments.

Course: Digital Logic & System Design Concepts Level: Undergraduate / Bridge to VLSI & Embedded Systems

Course Overview: Why Digital Logic Is Still the Foundation of Everything

Every processor, sensor node, and AI accelerator built today still obeys the same rules a first-year digital logic student learns in week one: two voltage levels, a clock edge, and Boolean algebra. Digital Logic & System Design Concepts is built to take a student from that first principle all the way to a working circuit on real FPGA hardware, without skipping the reasoning in between.

This guide is organized as a four-part curriculum, and it is written the way to teach it in the Electronics & Computer Science Dept. at Science & Tech University: bottom-up, with every abstraction earned before it is used. Part 1 builds the combinational and sequential circuit foundations — minimization, flip-flops, finite state machines, and the RTL building blocks that every larger design is assembled from. Part 2 moves from schematics to an industrial design flow: VHDL as a hardware description language, FPGA architecture as the implementation target, the synthesis pipeline that turns RTL into a working chip configuration, and the testing techniques that prove a design actually works. Part 3 steps back and asks a harder question — what happens when software becomes inseparable from the hardware it runs on, as it has in nearly every modern embedded device. Part 4 closes the loop with seven laboratory assignments that require students to design, code, simulate, synthesize, and validate real sub-systems on FPGA development kits.

The intended audience is undergraduate students in Electronics, Computer Science, Computer Engineering, and related programs, along with self-directed engineers who want a structured path into digital hardware design. A working knowledge of basic electronics and introductory Boolean algebra is helpful but not mandatory — Part 1 rebuilds those foundations from first principles before anything else is introduced. Treat this as a reference you return to: skim it once end-to-end to understand the shape of the course, then work through each part in depth alongside the lab assignments in Part 4, which are designed to be attempted only after the corresponding theory sections have been covered.

Assessment across the course is intentionally weighted toward demonstrable, working artifacts rather than theory alone: minimized expressions must be provably equivalent to their unminimized source, state machines must be validated against a written state table before coding begins, and every VHDL design carried into Part 4 must clear both a self-checking simulation testbench and a live hardware demonstration before it is considered complete. This mirrors how digital design teams actually operate in industry, where a circuit that “looks right” on paper but has never been simulated or tested on silicon is not considered done.

Prerequisites & Recommended Tools

Students should be comfortable with basic algebra and introductory electronics (voltage, current, and the idea of a digital “1” and “0” as two distinct voltage ranges); no prior programming or hardware experience is assumed. To follow the course and attempt the Part 4 labs, the following toolchain is recommended:

  • A VHDL simulator for functional simulation and testbench-driven verification (any IEEE-1076-compliant simulator is suitable for the coursework in this guide).
  • An FPGA vendor’s synthesis and implementation toolchain, matched to whichever development board is used, for the synthesis pipeline described in Section 2.4.
  • An entry-level FPGA development board with on-board switches, push-buttons, LEDs, a 7-segment display, and a USB-JTAG programming interface — the specific hardware target for all seven labs in Part 4.
  • A waveform viewer for inspecting simulation results, and, where the toolchain supports it, an on-chip logic analyzer core for observing internal signals on real hardware (used in Lab 6).
PART 01

Foundations of Digital Circuit Design

Circuit minimization, sequential circuit design, and the RTL building blocks that every digital system is constructed from.

Part 1 exists to build fluency, not just familiarity. Students who can recite what a flip-flop is but cannot design a correctly-clocked finite state machine, or who can draw a K-map but never use one to actually reduce gate count, will struggle the moment Part 2 asks them to write synthesizable VHDL. Everything here is chosen because it reappears, unchanged in principle, inside every larger digital system covered later in the course.

1.1 The Language Circuits Speak: Number Systems, Codes & Boolean Algebra

Digital systems represent information using binary digits, but engineers rarely think in raw binary once a design grows past a few bits. Hexadecimal and octal notations exist purely for human convenience when reading bus values and memory addresses. Binary-Coded Decimal (BCD) matters wherever a digital system must display or accept decimal values directly, such as the 7-segment display counters students build in the Part 4 labs. Gray code, where only one bit changes between successive values, is essential in two places students will meet later in this course: Karnaugh map layout (Section 1.2) and rotary/position encoders in embedded systems (Part 3), where it eliminates the glitches that ordinary binary counting would cause during a transition.

Two’s complement representation deserves particular attention because it is the representation every ALU, processor, and DSP block actually uses internally for signed arithmetic — it lets addition and subtraction share the same adder hardware, a design decision students will re-encounter when they build a 4-bit ALU in Lab 2.

Underneath all of this sits Boolean algebra: the commutative, associative, and distributive laws, and — most practically useful of all — De Morgan’s theorems, which let a designer convert freely between AND/OR-based logic and NAND/NOR-based logic. This conversion matters because real chip libraries are built almost entirely from NAND and NOR gates, since both are functionally complete (any Boolean function can be built from either gate alone) and both are more efficient to fabricate in CMOS than AND or OR gates directly. Every Boolean function can also be written in two canonical forms — Sum of Products (SOP) and Product of Sums (POS) — derived directly from a truth table, and these canonical forms are the starting point for the minimization techniques in the next section.

This section also introduces parity and simple error-detecting codes — a single parity bit computed with a chain of XOR gates lets a receiver detect (though not correct) a single-bit transmission or storage error, and is the simplest possible bridge between pure combinational logic and the reliability concerns that reappear later in the course when Section 2.5 discusses manufacturing test and Section 3.5 discusses secure, reliable embedded communication. Students implement a parity generator and checker as a short warm-up exercise before moving into full minimization in Section 1.2.

AND OR NOT NAND NOR XOR
Figure 1. The six gate types every combinational circuit reduces to. NAND and NOR (functionally complete on their own) are what standard-cell and FPGA libraries actually build every larger function from.

1.2 Circuit Minimization: Karnaugh Maps & the Quine–McCluskey Method

A truth table written straight into Sum-of-Products form is always correct and almost never efficient — it typically produces far more gates, more silicon area, more propagation delay, and more power draw than necessary. Minimization is the discipline of finding a logically equivalent expression that costs less to build, and it is the first place students see a direct, measurable link between an abstract algebra exercise and a real engineering cost.

For functions of up to about five or six variables, the Karnaugh map (K-map) is still the fastest manual technique. Cells are arranged in Gray-code order so that any two adjacent cells (including wraparound edges) differ in exactly one variable, which means any rectangular group of 1s sized as a power of two (1, 2, 4, 8…) can be collapsed into a single product term. Larger groups produce shorter, cheaper terms; the designer’s job is to cover every required minterm using the fewest, largest groups possible, using don’t-care conditions (input combinations that never occur, or whose output truly does not matter) to enlarge groups wherever they help.

AB\CD 00011110 00011110 1111 0110 0110 1001 A’B’ BD AB’D’ (wraps around) F(A,B,C,D) = A’B’ + BD + AB’D’
Figure 2. A worked 4-variable K-map: minterms Σ(0,1,2,3,5,7,8,10,13,15) minimize from ten product terms down to just three, using one quad, one wraparound quad, and one wraparound pair.

K-maps stop being practical past five or six variables — the geometry becomes impossible to visualize reliably. This is exactly the gap the Quine–McCluskey method fills: an algorithmic, tabular minimization procedure that systematically combines minterms differing in one bit, then solves a prime implicant coverage problem to find a minimal set of terms. Because it is a well-defined algorithm rather than a visual pattern-matching exercise, Quine–McCluskey is exactly what commercial logic synthesis tools implement (in more advanced, scalable forms such as Espresso-style heuristic minimization) when they minimize logic automatically across designs with thousands of variables — a preview of the automated synthesis flow covered in Part 2.

It is worth making the “cost” in circuit minimization concrete rather than abstract. Fewer literals and fewer product terms translate directly into fewer physical gates, which reduces silicon area, shortens the longest signal path (and therefore raises the maximum usable clock frequency), and — because every gate that switches draws dynamic power proportional to its switching activity — lowers energy consumption as well. A design with twice as many redundant gates does not just cost more to fabricate; it runs measurably hotter and drains a battery measurably faster, which is precisely why minimization, first taught here as a paper-and-pencil exercise, is also the very first optimization stage every commercial synthesis tool performs, as Section 2.4 will show.

1.3 Combinational Logic Design & RTL Building Blocks

Once minimization is understood, the next skill is composition: building useful, reusable blocks out of minimized gate-level logic, and recognizing that these blocks recur, unchanged, across almost every digital system. This course treats the following as the essential combinational vocabulary:

  • Adders — the half adder and full adder as atomic building blocks; ripple-carry adders chained from full adders (simple, but with delay that grows linearly with width); carry-look-ahead adders, which compute carry signals in parallel to cut delay at the cost of extra gates — a direct, concrete illustration of the area-versus-speed trade-off students will make repeatedly in later design decisions.
  • Multiplexers and demultiplexers — the universal “data selector” and “data router,” and, less obviously, a functionally complete building block: any Boolean function can be implemented using multiplexers alone by wiring inputs and constants to the select and data lines.
  • Decoders and encoders — decoders convert an n-bit code into one of 2ⁿ active outputs (address decoding, instruction decoding); priority encoders do the reverse, and appear constantly in interrupt controllers and resource-arbitration logic.
  • Comparators — magnitude and equality comparison logic, built directly from XOR/XNOR gates and cascaded for wider operands.
  • The Arithmetic Logic Unit (ALU) — the point where all of the above combine: a multiplexer-selected bank of arithmetic and logic operations sharing a common adder core, exactly the block students implement in Lab 2.

The phrase “RTL building block” is introduced deliberately at this stage rather than in Part 2. Register-Transfer Level design is, at its core, the practice of describing a system as data moving between registers through combinational blocks like these — so learning to recognize an adder, a mux, and a decoder as reusable, off-the-shelf components (rather than one-off gate networks) is what makes RTL thinking, and eventually VHDL, feel natural rather than arbitrary.

No combinational block is instantaneous — every gate introduces propagation delay, and chaining gates chains that delay. This section also covers static and dynamic hazards: brief, unwanted glitches that occur when different signal paths through a circuit have different delays, causing an output to momentarily flicker to the wrong value even though its final, settled value is correct. Hazards rarely matter for a purely combinational output feeding another combinational block, but they matter a great deal the moment that output feeds a clock, an asynchronous reset, or another sequential element directly — which is exactly the boundary Section 1.4 covers next, and one more reason synchronous design disciplines exist in the first place.

1.4 Sequential Circuit Design: Memory, Clocking & State

Combinational logic has no memory — its output depends only on its current inputs. Every digital system that needs to remember anything (a counter’s current value, a state machine’s current state, a processor’s register contents) needs sequential logic, and everything sequential is ultimately built from the same primitive: a bistable element that can hold one bit.

Students first distinguish latches (level-sensitive, transparent while enabled) from flip-flops (edge-triggered, capturing input only at a clock transition), and this course treats that distinction as non-negotiable: virtually all synchronous digital design uses edge-triggered flip-flops specifically because they eliminate the race conditions and unpredictable feedback loops that level-sensitive latches introduce in larger systems. From there, the four classic flip-flop behaviors — SR, D, JK, and T — are studied both as standalone elements and as characteristic-equation-driven building blocks for counter design. Setup time, hold time, and clock-to-Q delay are introduced here as hard physical constraints, along with metastability — what happens when those constraints are violated, particularly at asynchronous clock-domain boundaries — because these are not academic footnotes; they are the reason real hardware fails intermittently in the field.

The centerpiece of this section is the Finite State Machine (FSM). Students learn to derive a state diagram from a specification, minimize the number of states where possible, choose a state encoding (binary, one-hot, or Gray), and implement the result as next-state and output logic driving a register — distinguishing Moore machines (outputs depend only on current state) from Mealy machines (outputs also depend on current inputs, typically producing a faster but glitch-sensitive response). Counters and shift registers are then taught as specialized FSMs: a counter is a state machine whose states are simply an ordered numeric sequence, and a shift register is a chain of flip-flops whose “state transition” is literally shifting a bit one position.

Two further practical design decisions are covered here because they consistently determine whether a design works reliably on real hardware, not just in simulation: whether a flip-flop’s reset is synchronous (only takes effect on a clock edge, keeping the design fully synchronous but requiring at least one clock pulse to initialize) or asynchronous (takes effect immediately, useful for guaranteeing a known power-up state but capable of introducing its own timing hazards if it is de-asserted at an arbitrary moment relative to the clock); and how a signal is safely passed between two independent clock domains, typically using a multi-stage synchronizer, to control the metastability risk introduced earlier in this section rather than eliminate it outright — no synchronizer makes metastability impossible, only statistically negligible.

S0 S1 S2 S3 Z=1 0 1 1 0 0 1 1 0
Figure 3. A Moore-machine overlap detector for the bit pattern “101.” The double circle marks the accepting state (output Z=1); overlap is handled by returning to S1 or S2 — rather than S0 — after a match, so consecutive matches sharing bits are still detected.

1.5 From Gates to Systems: The Datapath / Control Paradigm

Part 1 closes by assembling combinational building blocks (Section 1.3) and sequential building blocks (Section 1.4) into the organizing pattern used for every non-trivial digital system: a split between a datapath — registers, an ALU, multiplexers, and buses that move and transform data — and a control unit, which is itself a finite state machine that generates the select signals, enable lines, and register-load pulses that drive the datapath through a sequence of operations.

Students are introduced to registers and register files as arrays of flip-flops with shared control, basic ROM and RAM concepts as addressed memory arrays, and tri-state buffers and shared buses as the mechanism that lets many devices share a single set of wires without contention. A simple worked example — a small calculator datapath driven by a control FSM — is used to show, concretely, that a “processor” at this level of abstraction is nothing more than the Part 1 building blocks wired together and sequenced by a state machine. That single idea is the bridge into Part 2, where the same datapath/control structure is described formally in a hardware description language instead of a schematic, and pushed through an industrial design flow toward silicon or an FPGA.

Finally, Part 1 closes with a brief look at handshaking signaling — simple valid/ready or request/acknowledge protocols that let two independently clocked or independently timed blocks exchange data reliably without either side needing to know exactly how long the other takes. This is deliberately introduced as a forward-looking concept rather than developed in depth: it is the same underlying idea that reappears, formalized, in the UART framing protocol students implement in the Part 4 capstone lab, and in almost every on-chip communication bus used in real System-on-Chip designs.

PART 02

ASIC-Style System Design: VHDL, FPGA & Test

Introducing VHDL, FPGA as an implementation technology, the synthesis pipeline, and the testing techniques used to verify real hardware.

Part 2 reframes everything from Part 1 in the vocabulary and workflow of industrial digital design. The building blocks do not change — an ALU is still an ALU — but the medium does: instead of drawing schematics by hand, students describe hardware in text using a Hardware Description Language, and instead of wiring gates manually, an automated toolchain converts that description into a working chip configuration. This is, in miniature, the same flow used to design production ASICs and to program commercial FPGAs.

2.1 From Schematic to Silicon: The ASIC & FPGA Design Flow

Two implementation paths exist for a finished digital design, and every serious digital engineer needs to understand both, because the choice between them is a real engineering and business decision, not just a technical one.

An Application-Specific Integrated Circuit (ASIC) is fabricated from a custom mask set on silicon, using a library of pre-characterized standard cells. ASICs deliver the best possible speed, power, and area for a given design, but the non-recurring engineering (NRE) cost — photomask sets, fabrication runs, verification effort — runs into the millions of dollars and the process takes months, with essentially zero tolerance for post-fabrication bugs. An FPGA (Field-Programmable Gate Array), by contrast, is a pre-fabricated chip full of reconfigurable logic that is “programmed” electrically, in seconds, to implement any digital circuit within its capacity. FPGAs cost more per unit in high volume and are somewhat slower and more power-hungry than an equivalent ASIC, but they let a design be tested, debugged, and re-implemented an unlimited number of times on real hardware — which is exactly why this course, and nearly every digital design course worldwide, uses FPGAs as the implementation and prototyping platform for its laboratory work.

Specification RTL Design (VHDL) Functional Simulation Logic Synthesis FPGA: Place & Route → Bitstream ASIC: Place & Route → Tapeout
Figure 4. Both paths share the same front end — RTL capture and functional simulation — and only diverge at the point of physical implementation. This course walks the FPGA branch through hardware in Part 4.
Table 1 — ASIC vs. FPGA at a glance
CriterionASICFPGA
NRE costVery high (mask sets, fabrication)None — reprogrammable
Unit cost at high volumeLowHigher per chip
Speed / power / areaOptimal for the designGood, but overhead from reconfigurable fabric
Turnaround to working hardwareMonthsMinutes (re-program in-circuit)
Best fitHigh-volume productionPrototyping, low/mid volume, this course’s labs

Both flows also rely heavily on Intellectual Property (IP) reuse: rather than re-deriving a UART, a memory controller, or a floating-point unit from first principles on every project, design teams license or reuse pre-verified IP cores and integrate them the same way students integrate a reusable adder or ALU component in Section 2.2 — as a black-box entity with a known interface and known timing behavior. Understanding how to write and package a clean, reusable RTL component in this course is directly preparatory for working with IP cores in industry.

2.2 Introducing VHDL: Describing Hardware, Not Writing Software

VHDL (VHSIC Hardware Description Language) is the language this course standardizes on for RTL capture. The single most important mental shift for students — especially those arriving with a programming background — is that VHDL does not describe a sequence of instructions executed over time; it describes structure and concurrent behavior. Every statement outside a process runs simultaneously, all the time, exactly like real gates and wires do, because that is precisely what it is compiled into.

A VHDL design unit splits into an entity, which declares the block’s interface (its input and output ports), and one or more architectures, which describe its internal behavior or structure. Inside an architecture, code is either concurrent (signal assignments and component instantiations that execute continuously) or sequential, written inside a process block that is sensitive to a specified list of signals — most commonly a clock, which is how synchronous sequential logic from Section 1.4 gets expressed in code. Understanding the difference between a signal (which behaves like a real wire, updating after a delta-cycle) and a variable (which updates immediately, but only within a process) is one of the most common sources of simulation-versus-synthesis mismatches for new VHDL programmers, and is emphasized heavily in this course.

-- A synchronous D flip-flop with active-high synchronous reset
entity d_flip_flop is
  port (
    clk   : in  std_logic;
    reset : in  std_logic;
    d     : in  std_logic;
    q     : out std_logic
  );
end entity d_flip_flop;

architecture rtl of d_flip_flop is
begin
  process (clk)
  begin
    if rising_edge(clk) then
      if reset = '1' then
        q <= '0';
      else
        q <= d;
      end if;
    end if;
  end process;
end architecture rtl;

Larger designs are built by component instantiation and generics — generics act as compile-time parameters (bus width, for example), letting a single ALU or register-file description be reused at multiple widths without rewriting code, directly mirroring the reusable “RTL building block” mindset introduced in Section 1.3.

Students also learn to recognize three overlapping modeling styles within VHDL, since real codebases mix them freely: structural modeling, which wires together component instances much like a schematic (used when composing the RTL building blocks from Part 1 into a larger system); dataflow modeling, which describes a block purely through concurrent signal assignments and Boolean or arithmetic expressions (a natural fit for the minimized combinational logic from Section 1.2); and behavioral modeling, which uses sequential statements inside a process to describe what a block does algorithmically — the style used for the flip-flop and FSM examples in Section 1.4. Knowing which style fits a given problem, rather than defaulting to one everywhere, is one of the clearest signs of a student who has internalized RTL thinking rather than just memorized syntax.

2.3 FPGA Architecture as an Implementation Technology

An FPGA is, at its core, a regular grid of small, reconfigurable logic elements connected by a programmable routing fabric, and understanding this internal architecture is what lets a designer write RTL that maps onto it efficiently.

  • Look-Up Tables (LUTs) — small memories (commonly 4- to 6-input) that implement arbitrary combinational logic by storing a truth table directly; any Boolean function of that many inputs can be realized simply by loading the correct configuration bits.
  • Configurable Logic Blocks (CLBs) / slices — each pairs one or more LUTs with flip-flops and fast carry-chain logic, giving a single reconfigurable unit that can implement both the combinational and sequential building blocks from Part 1.
  • Programmable routing / switch matrix — a dense mesh of wires and programmable switches connecting CLBs together and to I/O; routing delay, not logic delay, is very often the dominant factor limiting maximum clock frequency on an FPGA.
  • I/O Blocks (IOBs) — configurable pin drivers around the chip’s perimeter supporting multiple voltage and signaling standards.
  • Dedicated hard blocks — modern FPGAs also embed hardened DSP slices (fast multiply-accumulate units), Block RAM (BRAM) for on-chip memory, and clock management tiles / PLLs for generating and distributing multiple clock frequencies — all far more efficient than building the same function from general-purpose LUTs.

Modern devices push this further still with heterogeneous SoC FPGAs, which embed a hardened processor core (commonly an Arm-based application processor) directly alongside the reconfigurable fabric on the same die. This lets a designer implement timing-critical or highly parallel functions as custom logic using exactly the techniques in this course, while running an operating system, a network stack, or general application code on the hardened processor beside it — a direct, physical instance of the hardware/software co-design trade-off that Part 3 examines in depth.

LUT+FF
Figure 5. A simplified FPGA floorplan: a regular grid of CLBs (copper), a programmable routing mesh between them, and I/O blocks (blue) around the perimeter. Real devices also scatter dedicated DSP and BRAM columns through this fabric.

2.4 Synthesis Steps: RTL to Gate-Level and Beyond

Logic synthesis is the automated process that turns VHDL RTL into a gate-level (or FPGA primitive-level) implementation, and understanding its stages demystifies what the tools are actually doing:

  1. Elaboration / RTL analysis — the tool parses the VHDL, resolves generics and component hierarchy, and builds an internal representation of the design.
  2. Technology-independent optimization — Boolean logic is minimized (the same principles as Section 1.2, applied algorithmically and at massive scale), redundant logic is removed, and the design is restructured for the target’s cost function.
  3. Technology mapping — the optimized logic is mapped onto the target’s actual primitives: standard cells for an ASIC, or LUTs, flip-flops, and dedicated DSP/BRAM blocks for an FPGA.
  4. Constraint-driven optimization — designers supply timing constraints (target clock frequency, input/output delays) typically in an SDC-style constraints file; the synthesis engine restructures logic to try to meet them, trading area or power against speed as needed.
  5. Place & Route — gates or CLBs are assigned physical locations, and the routing fabric is configured to connect them, after which Static Timing Analysis (STA) verifies that every path in the design meets setup and hold requirements at the target clock frequency.
  6. Bitstream generation (FPGA) or GDSII tapeout (ASIC) — the final output that actually configures the physical device.

Students should leave this section with one core habit: writing VHDL that is not just functionally correct in simulation, but synthesizable and structured in a way that maps predictably onto real hardware — avoiding constructs that simulate fine but either fail to synthesize or synthesize into something wildly different (and usually much larger or slower) than intended.

Synthesis tools generally expose an explicit choice between optimizing for area (fewer LUTs/gates, favored in resource-constrained or cost-sensitive designs) and optimizing for speed (favoring pipelining and parallel structures that raise maximum clock frequency at the cost of extra logic) — the same fundamental trade-off first seen between ripple-carry and carry-look-ahead adders in Section 1.3, now exposed as a tool setting applied across an entire design rather than one block at a time. Reading a synthesis or implementation report and understanding which resources are being spent where — and why — is a skill every lab in Part 4 specifically requires students to demonstrate, not just describe.

2.5 Testing Techniques: Verifying & Validating Digital Hardware

A design that has never been tested is not a design — it is a guess. This course treats verification as inseparable from design, not an afterthought performed once coding is “done.”

  • Functional simulation and testbenches — a VHDL testbench instantiates the design under test, drives it with stimulus, and checks its responses, ideally as a self-checking testbench that automatically flags mismatches against expected results rather than requiring a human to eyeball waveforms. This is the primary verification method used before any design reaches Lab 5 or Lab 6.
  • Assertions and formal methods — lightweight assertions embedded in RTL or testbenches catch illegal conditions the moment they occur during simulation; formal verification tools, introduced conceptually, mathematically prove properties about a design rather than sampling specific test vectors, which matters for design classes where exhaustive simulation is infeasible.
  • Design for Testability (DFT) — scan chains reconfigure a design’s flip-flops into a long shift register during test mode, letting external test equipment control and observe internal state directly; Automatic Test Pattern Generation (ATPG) tools then generate the minimal vector set needed to detect manufacturing defects (typically modeled as stuck-at faults) with high fault coverage.
  • Boundary scan (JTAG / IEEE 1149.1) — a standardized scan architecture around a chip’s I/O pins, used both for board-level manufacturing test and, very practically for this course’s labs, as the interface used to program and debug the FPGA itself.
  • Built-In Self-Test (BIST) — dedicated on-chip hardware that tests memories or logic autonomously, common in memory-heavy or safety-critical designs.
  • Hardware validation — the final step, closing the loop from Section 2.1: downloading a bitstream to real FPGA hardware and confirming behavior with switches, LEDs, and — for deeper visibility into signals that aren’t brought out to a pin — an embedded logic analyzer core instantiated directly inside the FPGA fabric, which students use in Lab 6.

A question every verification engineer eventually has to answer is simply: how do we know when we have tested enough? This course introduces coverage metrics as the practical answer — code coverage reports which lines, branches, and states in the RTL were actually exercised during simulation, while functional coverage tracks whether specific, meaningful scenarios the designer cares about (every opcode of the Lab 2 ALU, every transition in the Lab 3 state machine) were actually tested, not merely whether every line of code happened to execute. A testbench that reaches 100% code coverage while missing an important functional scenario has still failed at its actual job, which is why this course grades lab testbenches on the scenarios they demonstrably exercise, not on line counts alone.

Course principle: No design in this course is considered complete until it has passed a self-checking testbench in simulation and been validated on physical FPGA hardware. Simulation proves logical correctness; hardware validation proves the design actually works under real timing, real I/O, and real electrical conditions.
PART 03

Embedded System Design Challenges

Where software becomes integral to every device, and hardware design decisions can no longer be made in isolation from firmware.

Nearly every digital circuit built today does not stand alone — it is wrapped in software the moment it includes a processor core, and almost every modern device does. Part 3 exists to make students uncomfortable with a clean split between “hardware people” and “software people,” because that split does not survive contact with real embedded product design.

3.1 Hardware/Software Co-Design

An embedded system’s functionality can almost always be implemented in more than one way: as dedicated logic (fast, power-efficient, inflexible once fabricated) or as software running on a processor core (flexible, field-updatable, but slower and more power-hungry per operation). Hardware/software co-design is the discipline of partitioning a system’s requirements across this boundary deliberately, rather than by default or habit — deciding, for example, that a sensor’s signal-conditioning filter belongs in a dedicated hardware block driven by the FSM techniques from Part 1, while its calibration and communication logic belongs in software. The RTL building blocks and FPGA skills from Parts 1 and 2 are precisely what let an engineer implement the “hardware” side of that decision competently, rather than treating it as a black box supplied by someone else.

This partitioning decision is rarely made once and left alone. As a product matures, functions frequently migrate across the hardware/software boundary in both directions: a software routine that turns out to be a system bottleneck may be re-implemented as a dedicated hardware accelerator using the exact RTL techniques from Part 1, while a rigid hardware block that turns out to need frequent behavior changes may be replaced with a more flexible software routine running on an embedded core. Recognizing that this boundary is a design variable, not a fixed wall, is the central habit of mind Part 3 is trying to build.

3.2 Real-Time Constraints & Determinism

Many embedded systems must respond within a bounded time, not just eventually. A hard real-time constraint means missing a deadline is a system failure (an airbag controller, an anti-lock braking system); a soft real-time constraint means a missed deadline degrades quality but does not cause failure (a video decoder dropping an occasional frame). Meeting these constraints requires understanding interrupt latency (the delay between an event and the processor beginning to service it) and Worst-Case Execution Time (WCET) analysis for critical code paths, along with scheduling strategies — covered practically in Section 3.4 — that guarantee, not just usually achieve, timing behavior.

Two classic scheduling algorithms are introduced conceptually here because they underpin how an RTOS scheduler, covered next in Section 3.4, actually makes its guarantees: Rate-Monotonic Scheduling (RMS), a fixed-priority scheme where tasks with shorter periods simply run at higher priority, and Earliest-Deadline-First (EDF), a dynamic-priority scheme that always runs whichever ready task has the closest deadline. Both come with well-established mathematical tests for whether a given task set is even schedulable at all before a single line of code is written — turning “will this system meet its deadlines?” from a hopeful guess into a question with a provable answer, the same shift in mindset that formal verification brought to Section 2.5.

3.3 Resource, Power & Cost Constraints

Unlike a desktop system, an embedded design is almost always fighting three constraints simultaneously: memory footprint (often kilobytes, not gigabytes), power budget (frequently battery-powered, sometimes energy-harvested), and unit cost, which at high production volumes makes even a few extra cents per chip a significant decision. Low-power design techniques introduced here — clock gating (disabling the clock to idle logic blocks), power domains and sleep/deep-sleep modes, and dynamic voltage and frequency scaling — are the direct embedded-systems continuation of the “cost of a gate” thinking first introduced through circuit minimization in Section 1.2: every constraint eventually traces back to how much silicon activity is actually necessary to do the job.

These constraints also compound with each other in ways students are asked to reason about quantitatively, not just qualitatively: a battery-powered sensor node’s usable lifetime is a direct function of average current draw across its duty cycle, meaning a device that sleeps 99% of the time can often run for years on a small cell battery even if its active-mode power draw looks unimpressive on a datasheet. Similarly, thermal design matters even in “low power” embedded systems, because a densely packaged enclosure with no active cooling can trap heat that a bare development board never would, shifting a design that was thermally fine on the lab bench into one that throttles or fails in its actual enclosure — a reminder that Part 4’s lab boards are a convenient, open testbed, not a substitute for validating a final product’s real thermal and power envelope.

3.4 Embedded Software Architecture: Bare-Metal, RTOS & Beyond

The simplest embedded software architecture is a bare-metal superloop or purely interrupt-driven program with no operating system at all — appropriate for small, simple, or extremely resource-constrained designs. As complexity grows, a Real-Time Operating System (RTOS) introduces tasks (independently schedulable units of work), a preemptive scheduler that guarantees higher-priority tasks run when they need to, and inter-task communication primitives such as semaphores, mutexes, and message queues that let hardware-triggered events and background processing coexist safely. Above this sits the practical toolchain reality of embedded development: device drivers that abstract raw hardware registers, a Board Support Package (BSP) tying drivers to a specific board, cross-compilation (building code on a development machine for a different target architecture), and JTAG-based hardware debugging — the same boundary-scan technology introduced in Section 2.5, reused here as the standard way to load and debug firmware on real hardware.

Between the raw device drivers and the application sits a Hardware Abstraction Layer (HAL) and, often, additional middleware — networking stacks, file systems, or graphics libraries — that let application code be written against a stable, portable interface rather than against a specific chip’s register map. This layering is a direct software analogue of the component-and-interface discipline taught in Section 2.2: just as a VHDL entity hides its internal architecture behind a fixed port interface, a well-designed HAL hides a specific microcontroller’s register-level quirks behind a fixed function interface, letting the same application code move to new hardware with minimal change.

3.5 The Expanding Frontier: IoT, Security & Software-Defined Hardware

Two forces are accelerating how much software now sits on top of fixed silicon. First, connectivity: most new embedded designs assume some IoT protocol stack (Wi-Fi, BLE, or low-power wide-area networking) and must therefore also assume a much larger attack surface, making secure boot, encrypted firmware updates, and hardware roots of trust first-class design requirements rather than optional extras. Second, a broader industry shift toward software-defined hardware: increasingly, a single System-on-Chip is manufactured once and then differentiated, updated, and even repurposed almost entirely through the software and firmware loaded onto it after the fact. This is precisely why the hardware foundations built in Parts 1 and 2 of this course remain essential even for students headed toward embedded software careers — the software boundary keeps moving, but it always moves on top of the same underlying digital logic.

A closely related trend worth naming explicitly is edge AI: machine learning inference moving out of the cloud and onto the embedded device itself, driven by latency, privacy, and connectivity constraints. This shift has, if anything, increased demand for exactly the skill combination this course builds — engineers who can design a dedicated hardware accelerator block using the RTL and FPGA techniques from Parts 1 and 2, then integrate it correctly beneath a software and driver stack using the embedded design discipline from this Part, rather than engineers who are fluent in only one half of that stack.

MCU / SoC Core RTOS / Bare-metal + Drivers Sensors Actuators Memory (Flash/RAM) Comms (UART/SPI/BLE)
Figure 6. The embedded system boundary: fixed silicon (MCU, memory, I/O) wrapped in a software stack that increasingly defines the product’s actual behavior and can be updated long after the hardware ships.
PART 04

FPGA Laboratory Assignments

Seven hands-on assignments requiring students to design, code, simulate, synthesize, and implement circuits and sub-systems on real FPGA development kits.

Every lab below follows the same rhythm the industrial flow in Part 2 established: design → code in VHDL → simulate with a self-checking testbench → synthesize and implement → validate on physical hardware. Labs assume a standard entry-level FPGA development board (for example, a Xilinx Artix-7-class board such as a Basys3/Nexys-A7, or an Intel/Altera Cyclone-class board such as a DE10-Lite) with on-board switches, push-buttons, LEDs, 7-segment displays, and a USB-JTAG programming interface, alongside a VHDL simulator and the vendor’s synthesis/implementation toolchain. Each lab report should include the VHDL source, the testbench used, simulation waveforms, the post-implementation utilization and timing summary, and a short written analysis of any discrepancy between expected and observed behavior.

LAB 01 Boolean Minimization & Logic Verification

Maps to Section 1.2 — K-map minimization

Given a 4-variable truth table, minimize the function by hand using a K-map, then implement the minimized expression directly in VHDL as pure concurrent signal assignments (no process block). Map inputs to on-board switches and the output to an LED. Students must submit both the unminimized SOP circuit and the minimized circuit, compare LUT utilization for each after synthesis, and explain the difference numerically.

LAB 02 A 4-Bit ALU: Combinational RTL Building Blocks

Maps to Section 1.3 — adders, multiplexers, ALU design

Design and implement a 4-bit ALU in VHDL supporting addition, subtraction (via two’s complement), AND, OR, and XOR, selected by a 3-bit opcode. Operands are set via on-board switches; the result and a zero/overflow flag are displayed on the 7-segment display and LEDs. Students implement the adder/subtractor as a reusable component and instantiate it once, reinforcing the reusable-block philosophy from Section 1.3.

LAB 03 FSM-Based Sequence Detector

Maps to Section 1.4 — Moore/Mealy finite state machines

Implement the overlap-detecting Moore machine from Figure 3 (or an assigned variant pattern) in VHDL as an explicit state register plus next-state/output logic. Input bits are supplied one at a time via a debounced push-button; a detected match pulses an LED. Students must submit their own state diagram and state table before coding, and the lab report must show a simulation waveform proving correct overlap detection.

LAB 04 BCD Counter & 7-Segment Stopwatch

Maps to Section 1.4/1.5 — counters, clock division, datapath control

Using the FPGA board’s on-board oscillator, design a clock divider to generate a 1 Hz tick, then build a two-digit BCD up-counter driving a multiplexed 7-segment display, with debounced start/stop and reset push-buttons. This lab is students’ first exercise in combining a datapath (the BCD counter) with a small control FSM (start/stop/reset logic) as described in Section 1.5.

LAB 05 Self-Checking Testbenches & Simulation-Based Verification

Maps to Section 2.5 — functional simulation, self-checking testbenches

Select a design from Labs 2 or 3 and write a self-checking VHDL testbench that applies a directed stimulus set, compares actual against expected outputs automatically, and reports a pass/fail count rather than requiring manual waveform inspection. Students must intentionally introduce one bug into a copy of their design and demonstrate that their testbench catches it, directly practicing the “no design is complete without a passing self-checking testbench” principle from Part 2.

LAB 06 Synthesis, Timing Closure & On-Board Validation

Maps to Section 2.4 — synthesis pipeline, static timing analysis

Take a verified design from an earlier lab through the full synthesis-to-bitstream flow: write a pin-constraints file mapping ports to the board’s physical switches/LEDs/clock pin, add a timing constraint for the target clock frequency, run synthesis and implementation, and analyze the resulting utilization and static timing reports. Students who have timing violations must identify the critical path and propose a fix (pipelining or restructuring logic). Where the board’s toolchain supports it, students instantiate an embedded logic analyzer (ILA) core to observe an internal signal that isn’t connected to any pin.

LAB 07 · CAPSTONE UART-Controlled Traffic-Light Sub-System

Integrates Parts 1–3 — datapath/control, VHDL, FPGA, and embedded-style I/O

Design and implement a complete sub-system combining a UART receiver (to accept single-character commands from a PC terminal), a controller FSM implementing standard traffic-light sequencing with a pedestrian-crossing override input, and multiplexed LED/7-segment outputs showing both light state and a countdown timer. This capstone requires a written design document (block diagram, state diagram, and timing budget), full VHDL source with a self-checking testbench, synthesis and timing reports, and a short recorded demonstration on physical hardware — deliberately mirroring, at small scale, the specification-to-hardware-validation flow used throughout Part 2 and the hardware/software boundary thinking introduced in Part 3.

Lab safety & academic integrity note: All labs are performed on low-voltage FPGA development boards powered via USB and present no electrical hazard beyond standard ESD precautions for handling electronic components. Simulation waveforms and synthesis reports submitted with each lab must be generated from the student’s own design; designs are expected to be original work, and testbenches in particular should be written independently to genuinely exercise the student’s own understanding of correct behavior rather than copied from a reference solution.

Learning Outcomes & Where This Course Leads

By the end of Digital Logic & System Design Concepts, students should be able to move confidently through the entire chain this guide has walked: from a truth table to a minimized circuit, from a minimized circuit to a correctly clocked sequential system, from a sequential system to synthesizable VHDL, from VHDL to a working FPGA bitstream, and from a working bitstream to an honest understanding of what changes once that circuit has to share silicon with software in a real embedded product.

✓

Minimize combinational logic using Karnaugh maps and describe how algorithmic methods like Quine–McCluskey scale that process to automated synthesis.

✓

Design synchronous sequential circuits — counters, shift registers, and Moore/Mealy finite state machines — from a specification through to a verified state diagram.

✓

Compose reusable RTL building blocks (adders, multiplexers, decoders, ALUs) into a datapath driven by a control FSM.

✓

Write synthesizable VHDL and explain the difference between concurrent and sequential code, and between signals and variables.

✓

Explain FPGA architecture (LUTs, CLBs, routing, DSP/BRAM) and the full synthesis-to-bitstream pipeline, contrasted against the ASIC flow.

✓

Verify a design with self-checking testbenches and describe DFT techniques — scan chains, ATPG, boundary scan — used in production hardware test.

✓

Reason about hardware/software partitioning, real-time constraints, and power/resource trade-offs in embedded system design.

✓

Implement and validate original circuits and sub-systems on physical FPGA development hardware, end to end.

This course is deliberately positioned as a bridge: students headed toward VLSI and physical design will recognize Part 2 as the first half of a flow they will deepen in later ASIC-focused coursework; students headed toward embedded software and firmware will leave Part 3 understanding the hardware their code actually runs on, rather than treating it as an opaque black box. Either direction starts from the same place — the ability to look at a digital system, however complex, and still see the gates, the clock, and the state underneath it.

Frequently Asked Questions

What is the difference between digital logic design and digital system design?

Digital logic design refers to the circuit-level discipline covered in Part 1 of this guide — Boolean minimization, gate-level and RTL building blocks, and sequential circuits like flip-flops, counters, and finite state machines. Digital system design is the broader discipline built on top of it, covered in Parts 2 and 3: taking those circuit-level building blocks, describing them in a hardware description language like VHDL, implementing them on real silicon (an ASIC or an FPGA), verifying them with formal test techniques, and integrating them with the software that increasingly runs alongside them in a finished embedded product.

Do I need to know VHDL before starting this course?

No. This guide is deliberately sequenced so that VHDL is introduced in Part 2, Section 2.2, only after the combinational and sequential circuit concepts it will be used to describe have already been built in Part 1. Students who understand what a flip-flop, a multiplexer, and a finite state machine are supposed to do find VHDL syntax straightforward to learn, because the language is simply a precise, textual way of describing structures they can already reason about on paper.

Why does this course use FPGAs instead of ASICs for the lab assignments?

As Section 2.1 explains, FPGAs can be reprogrammed in seconds and cost nothing per redesign beyond the development board itself, while an ASIC requires a custom fabrication run costing well into the millions of dollars with no tolerance for post-fabrication errors. That makes FPGAs the only realistic platform for a university lab sequence where students are expected to make mistakes, debug them, and re-implement a corrected design many times over a semester — while still learning a design flow, covered in Part 2, that is structurally identical to the one used to develop production ASICs.

What FPGA development board is recommended for the labs in Part 4?

Any entry-level board from a major FPGA vendor with on-board switches, push-buttons, LEDs, a 7-segment display, and a USB-JTAG programming interface is suitable — for example, a Xilinx Artix-7-class board such as a Basys3 or Nexys-A7, or an Intel/Altera Cyclone-class board such as a DE10-Lite. The seven labs in Part 4 are written to be board-agnostic; only the pin-constraints file referenced in Lab 6 needs to change between boards.

How is a Moore machine different from a Mealy machine?

Both are finite state machines, the core sequential-design tool covered in Section 1.4. A Moore machine’s output depends only on its current state, which makes its output glitch-free and easy to reason about, but it can take one extra clock cycle to respond to an input change. A Mealy machine’s output depends on both its current state and its current inputs, which lets it respond within the same clock cycle, at the cost of being more sensitive to input glitches. The sequence detector in Figure 3 is implemented as a Moore machine specifically because its output pulse needs to be clean and directly tied to a stable, entered state.

Can this course lead into a VLSI or embedded systems career track?

Yes — that is exactly how it is positioned in the Learning Outcomes section above. Part 2’s synthesis and ASIC-flow coverage is a natural on-ramp into further VLSI and physical-design coursework, while Part 3’s embedded design challenges, combined with hands-on FPGA work in Part 4, are a natural on-ramp into embedded software and firmware engineering roles. Because the course builds both halves on the same underlying digital logic foundation, students are not forced to choose a direction before they have enough information to choose well.

Quick Glossary of Key Terms

Table 2 — Core vocabulary used throughout this guide
TermDefinition
RTL (Register-Transfer Level)A design abstraction describing a system as data moving between registers through combinational logic each clock cycle.
K-map (Karnaugh map)A grid-based manual technique for minimizing Boolean expressions by grouping adjacent 1s in Gray-code order.
FSM (Finite State Machine)A sequential circuit whose behavior is defined by a fixed set of states and the transitions between them.
VHDLA hardware description language used to specify digital circuit structure and behavior in text form, at the RTL and gate level.
LUT (Look-Up Table)A small memory inside an FPGA’s logic fabric that implements combinational logic by storing a truth table directly.
SynthesisThe automated process of converting RTL code into a gate-level or FPGA-primitive-level implementation.
TestbenchA simulation-only VHDL module that applies stimulus to a design and checks its responses against expected behavior.
DFT (Design for Testability)Design techniques — scan chains, ATPG, BIST — added specifically to make manufacturing defects easier to detect.
RTOSA Real-Time Operating System that schedules embedded software tasks with guaranteed, bounded timing behavior.
WCETWorst-Case Execution Time — the longest possible time a piece of code can take to run, used to prove real-time deadlines are met.