Barcelona Abroad · Week 1 · Day 1+2 (pt 2)

Data Types, Vectors & Operators

CRAFT cycle · Mon 5/25 · merged D1+D2 session — Part 2 of 2

HDL for Digital System Design · UCF ECE · Barcelona Summer 2026

CRAFT

Today at a Glance

PhaseTimeActivity
🌍 Contextualize10 minBinary data in the city — metro card, baggage tag, BCN airport
⚠️ Reframe15 minwire ≠ variable · reg ≠ register · operators as gates
🛠 Assemble70 min2:1 mux → 4:1 mux → ripple-carry adder → 7-seg decoder
🛡 Fortify45 minSim every block · width-mismatch hunt · structural variant
🔗 Transfer10 minDebrief · Tue catch-up · preview Day 3 + Sagrada Família
Merged session: this is the back half of Monday. The combined Day 1+2 lab finishes in Tuesday's catch-up block (5/26) — today is about getting the vocabulary and starting the builds.

▸ Phase 1 of 5  ·  ~10 min

🌍 Contextualize

Binary data is in everything around you in Barcelona

The City Runs on Vectors

  • T-Casual metro card — RFID payload is a few bytes of binary
  • BCN airport baggage tag — 10 decimal digits, encoded as a barcode of bits
  • Camp Nou turnstile — gate logic on a binary "valid ticket?" signal
  • Sagrada Família 3D printer — every layer is a packed bit-pattern

Today's job

Learn how HDL represents binary data — single bits, bus-width vectors, slices, concatenations — and the operators that move them around.

Every system you've seen since landing in Barcelona uses these primitives. Today you learn the syntax.

▸ Phase 2 of 5  ·  ~15 min

⚠️ Reframe

Sharper lens on the pre-class videos (V1 + V2, watched before arrival)

⚠️ wire ≠ Variable. reg ≠ Register.

wire is a physical connection with no storage; reg only means the simulator remembers the value between events — it may synthesize to a register or to pure combinational logic depending on where it is assigned

❌ Wrong Model

"Variables are storage boxes I put values into. wire stores a value; reg is a register."

✓ Right Model

wire is a physical connection — no storage. reg means "the simulator needs to remember this between events" — it might be a register, or it might be combinational. SystemVerilog fixes this with logic.

Naming was a 1985 mistake. The hardware doesn't care what you call it — what matters is where you assign it.

The Mux is Everywhere

assign y = sel ? a : b;       // 2:1 mux — one wire from two
assign y = s[1] ? (s[0] ? d : c)
                : (s[0] ? b : a);   // 4:1 mux nested

assign d = a + b;             // adder (synth produces real gates)
assign m = {nibble, 4'b0};    // concat — pad with zeros
assign r = {4{1'b1}};         // replication — 4'b1111
Every if/else, every case, every conditional in HDL eventually becomes muxes. Internalise that mental picture now — it pays off on Day 3.

▸ Phase 3 of 5  ·  ~70 min  ·  You build

🛠 Assemble

Four blocks. Each one ends with bits on the board.

Build Plan

  1. Ex 1 · 20 min  2:1 then 4:1 mux — use the ? : operator. Buttons for select & data, LED for output.
  2. Ex 2 · 25 min  4-bit ripple-carry adder — write one full_adder module, instantiate four times. First taste of hierarchy.
  3. Ex 3 · 25 min  Hex → 7-segment decoder — 16-entry case statement, lights both displays on the Go Board.
Stretch (Ex 4): Re-implement the 4:1 mux structurally from three 2:1 instances. Compare LUT counts.

2:1 Mux — Starter

module mux_2to1 (
    input  wire a, b,
    input  wire sel,
    output wire y
);
    assign y = sel ? a : b;
endmodule

Map to the Go Board:

  • sel ← Button 0  ·  a ← Button 1  ·  b ← Button 2
  • y → LED 0

Widen to 4-bit inputs ([3:0]) once the 1-bit version is solid.

Ripple Adder — Hierarchy in Practice

module full_adder (
    input  wire a, b, cin,
    output wire sum, cout
);
    assign sum  = a ^ b ^ cin;
    assign cout = (a & b) | (cin & (a ^ b));
endmodule

module adder4 (
    input  wire [3:0] a, b,
    input  wire       cin,
    output wire [3:0] sum,
    output wire       cout
);
    wire [3:0] c;
    full_adder fa0 (.a(a[0]), .b(b[0]), .cin(cin),  .sum(sum[0]), .cout(c[0]));
    full_adder fa1 (.a(a[1]), .b(b[1]), .cin(c[0]), .sum(sum[1]), .cout(c[1]));
    full_adder fa2 (.a(a[2]), .b(b[2]), .cin(c[1]), .sum(sum[2]), .cout(c[2]));
    full_adder fa3 (.a(a[3]), .b(b[3]), .cin(c[2]), .sum(sum[3]), .cout(cout));
endmodule

Four instances of the same module. This is what HDL hierarchy looks like.

Hex → 7-Segment Pattern

Seven-segment display with segments labeled a,b,c,d,e,f,g — the bit order the decoder's 7-bit output must drive
module hex_to_7seg (
    input  wire [3:0] hex,
    output reg  [6:0] seg   // {a,b,c,d,e,f,g}
);
    always @(*) begin
        case (hex)
            4'h0: seg = 7'b1111110;
            4'h1: seg = 7'b0110000;
            4'h2: seg = 7'b1101101;
            // ... fill in 3 through F
            default: seg = 7'b0000000;
        endcase
    end
endmodule
Build the truth table on the whiteboard together. Use a default clause — always — to avoid latch inference (we'll dive into that tomorrow).

▸ Phase 4 of 5  ·  ~45 min  ·  Verify · test · harden

🛡 Fortify

Make every block earn its place

Sim Before Solder — Three TBs Today

# Provided testbenches — run each one
cd labs/week1_day02/ex2_mux_hierarchy/starter && make sim
cd labs/week1_day02/ex3_adder/starter         && make sim
cd labs/week1_day02/ex4_seven_seg/starter     && make sim

What the TBs do

  • Mux: every sel × inputs combination
  • Adder: known-answer + carry edge cases
  • 7-seg: all 16 hex digits checked against golden pattern

Discipline reminder

Don't program the board until all three TBs print "0 failed." Yesterday's Day-1 workflow, applied four times today.

The Width-Mismatch Hunt

wire [3:0] sum;
wire [3:0] a, b;
assign sum = a + b + 1'b1;   // ⚠ Yosys may warn — width inference
                              //   The literal 1'b1 is 1-bit; adder
                              //   result is 5-bit (with carry).
  • Run synthesis and read the log. Yosys prints width warnings — don't bury them.
  • Common fixes: use 4'd1 for sized literals, declare sum as [4:0], or $signed when intent is signed.
  • Why this matters: on Day 10 we measure timing; on Day 14 we hunt PPA wins. A 5-bit adder costs more LUTs than a 4-bit one. Width is hardware.

Hardware Verification

  • 2:1 mux: hold sel low → LED reflects b; flip sel → LED reflects a.
  • 4:1 mux: all four (s[1], s[0]) combinations route the correct input.
  • Adder: use two pairs of buttons as 2-bit inputs (with the upper bits tied off in .pcf); read sum on LEDs.
  • 7-seg: cycle 0000 → 1111 on the input switches — both displays must light correctly. Phone-camera a 0–F sweep.
Stretch debrief: Compare LUT counts for the behavioural 4:1 mux vs the structural 3×2:1 mux. They should be identical — that's the synthesizer's job.

▸ Phase 5 of 5  ·  ~10 min

🔗 Transfer

What carries forward

What Generalizes

Vectors are universal. Every bus on every chip — AXI, UART, AHB — is a Verilog vector.

Muxes are the substrate of choice. Every conditional becomes one.

Hierarchy is how big designs stay sane. Today: a 4-bit adder from 4 full-adders. Week 4: a UART from 4 sub-blocks.

Read the synthesis log. Warnings = future bugs.

Tuesday Catch-up, then → Combinational Logic

Tue 5/26 is a catch-up block: finish board bring-up and the combined Day 1+2 lab. No new material — instructor-supported time to get everyone level.

Wed 5/27 (Day 3) brings always @(*), if/else, case — and the #1 beginner synthesis bug: latch inference. You'll build a 4-bit ALU and use yosys show to see if/else vs case.

Wed PM: Sagrada Família

Gaudí's structural models were essentially combinational: load in → shape out, no memory of sequence. Notice the branching geometry — it's a physical if/else tree. We open Day 3 with your photos.

Tue evening: Day 3 pre-class video (~45 min) + quiz.

🔗 End of Day 1+2 · Disfruta Barcelona

Three blocks, one workflow.

You now have the vocabulary to describe any combinational circuit.
Day 3 puts it inside always blocks — and shows you what can go wrong.

CRAFT