Interviews

Architecture Interview Questions

Practise the question, then the follow-ups an interviewer asks next.

Start with a Question TreeAI Mock Interview

14
Question trees
64
Follow-ups
88
Wrong answers explained
38
Runnable on a simulator
Question tree The interviewer asksWhat hazards does a five-stage in-order pipeline have, and how does forwarding help? WhyWhy Forwarding Cannot Hide a Load-Use HazardCompareRAW, WAR and WAW HazardsScale ItWhat a Deeper Pipeline Does to HazardsWhat IfBranches and the Control Hazard Open this tree

Flagship Questions · With follow-ups

Question Trees

Each question opens into the follow-ups an interviewer asks next, the wrong answers people give, and what a fresher's and a senior's answer sound like.

Quick revision · One flat list

Question Bank

All 66 Architecture questions, main and follow-up. Open a track, then a topic. Answer out loud first, then open the short answer.

Jump to a Track
66 questions · 14 topicsArchitecture
Pipeline Hazards and Forwarding5
What hazards does a five-stage in-order pipeline have, and how does forwarding help? L1L2

A data hazard (read after write) happens when an instruction needs a result that is still in the pipeline. A structural hazard is two instructions needing one resource, and a control hazard is a branch that changes which instructions follow. Forwarding sends a result from a later stage straight to the next instruction's EX input. That removes most data stalls, but a load followed by a use still costs one bubble.

QuestionPractise Pipeline Hazards and Forwarding →
Why can forwarding hide an ALU-to-ALU dependency but not a load followed by a use? L1L2

An ALU result exists at the end of EX, just in time for the next instruction's EX. A load's data exists only at the end of MEM, one stage later. Forwarding cannot send data back in time, so the dependent instruction waits one cycle.

Follow-upPractise Why Forwarding Cannot Hide a Load-Use Hazard →
Compare RAW, WAR and WAW hazards. Which ones can a simple in-order five-stage pipeline have? L1L2

RAW: a read must see an earlier write. WAR: a later write must not land before an earlier read. WAW: two writes must land in program order. In a simple in-order pipeline, reads happen in ID and writes in WB, both in order, so only RAW occurs. WAR and WAW appear with out-of-order issue or units of different latency.

Follow-upPractise RAW, WAR and WAW Hazards →
Scale it: the team doubles the pipeline depth to raise the clock. What happens to hazards and performance? L2L3

Each stage does less work, so the clock rises. But results take more stages to appear, so dependent instructions wait more cycles. Branches resolve later and flush more instructions, and forwarding paths multiply. Performance grows only if the clock gain beats the extra stall cycles, so measure it on real code.

Follow-upPractise What a Deeper Pipeline Does to Hazards →
What if a taken branch goes through this pipeline? What happens to the instructions behind it? L1L2

The pipeline has already fetched the next instructions on the wrong path. When the branch resolves, they must be flushed, and each flushed slot is a lost cycle. Resolving earlier or predicting the branch cuts the penalty. A flushed instruction must never write a register or memory.

Follow-upPractise Branches and the Control Hazard →
Splitting an Address into Tag, Index and Offset5
A 4 KB direct-mapped cache has 16-byte lines and 32-bit addresses. Split address 0x1234_5678 into tag, index and offset. L1L2

A 16-byte line needs 4 offset bits. 4 KB divided by 16 bytes is 256 lines, so 8 index bits. The other 20 bits are the tag. For 0x1234_5678: offset 8, index 0x67, tag 0x12345.

QuestionPractise Splitting an Address into Tag, Index and Offset →
What changes if the same 4 KB cache is 2-way set associative? L1L2

There are now 128 sets of two lines, so the index drops to 7 bits and the tag grows to 21. A lookup compares two tags in parallel and picks the matching way. On a miss, a replacement rule such as LRU (least recently used) chooses the victim. More ways cut conflict misses, but add comparators and a slower hit path.

Follow-upPractise The Same Cache, Two Ways →
Compare the three kinds of cache miss. Which one does more associativity fix? L1L2

A compulsory miss is the first touch of a line, which no cache avoids. A capacity miss happens when the working set is bigger than the cache. A conflict miss happens when lines that would fit compete for one set. More ways fix conflict misses; only a bigger cache fixes capacity misses.

Follow-upPractise Compulsory, Capacity and Conflict Misses →
Break it: this cache has no valid bits, and its tag RAM clears to zero at reset. What happens on the first access? L1

Any address whose tag is 0 hits on an empty cache and returns garbage data. Each line needs a valid bit, cleared at reset and set when the line is filled. Clearing only the valid bits is cheaper than clearing a whole tag RAM.

Follow-upPractise The Cache That Hit Before Anything Was Loaded →
Scale it: how would you verify a cache like this? L2L3

Treat the cache as invisible: a reference model is just a flat memory, and every read must match it. At the end, flush the cache and compare the final memory images. Aim stimulus at aliasing addresses, evictions of dirty lines, and reads right after writes. Add assertions on internal rules, because a final-image mismatch is hard to trace back.

Follow-upPractise Verifying a Cache →
Write-Through vs Write-Back Caches5
Compare write-through and write-back caches. What does each mean for memory traffic and for other agents that read memory? L2

Write-through sends every store to memory, so memory always has the latest data, but traffic is high. Write-back updates only the cache and marks the line dirty, and memory is written when the line is evicted. That saves traffic, but memory can be stale. Any other reader of memory, such as a DMA engine, then needs coherence hardware or software cleaning.

QuestionPractise Write-Through vs Write-Back Caches →
Compare write-allocate with no-write-allocate on a store miss. L2

Write-allocate fetches the line on a store miss and then writes into the cache. It helps when nearby data is used again soon. No-write-allocate sends the store straight to memory and leaves the cache alone. It suits streaming writes that are never read back. Write-back caches usually allocate; write-through caches often do not.

Follow-upPractise Write-Allocate vs No-Write-Allocate →
Why does a write-back cache keep a dirty bit per line? L1L2

The dirty bit records that the line differs from memory. On eviction, a clean line can simply be dropped, while a dirty one must be written back first. Without the bit, the cache would write back every evicted line and lose much of its saving.

Follow-upPractise Why a Write-Back Cache Needs a Dirty Bit →
What if the DMA writes memory and then the CPU reads the same address? L2L3

If the CPU still caches that line, it hits its own old copy and never sees the DMA data. Without coherence hardware, software must invalidate the line before reading. Before a DMA reads memory, software must clean dirty lines instead.

Follow-upPractise A DMA Write Behind the Cache →
Scale it: two CPUs each have a write-back cache over shared memory. What new problem appears, and how is it verified? L3

Both caches can hold the same line, and one CPU's write leaves the other's copy stale. A coherence protocol such as MESI tracks each line's state and snoops or invalidates the other copy. Verification runs both CPUs at once on the same lines, including different bytes of one line. A memory reference model then checks every read.

Follow-upPractise Two CPUs with Write-Back Caches →
The Forwarding Bug That Passed Back-to-Back Tests5
Every directed hazard test passes, but a random program fails against the instruction set simulator. Here is the log. What is the bug, and how should the tests have caught it? L2L3

Instruction 2 reads r1, written two instructions earlier, so it needs the MEM/WB forwarding path. The design has only the EX/MEM path for distance 1, so it read the stale r1. The directed tests used only back-to-back dependencies. Coverage should cross the producer type with the distance, 1 to 3, for each source operand. Then an empty bin would have shown the missing case.

QuestionPractise The Forwarding Bug That Passed Back-to-Back Tests →
Why should hazard coverage cross the producer type with the dependency distance? L2

Each forwarding path serves one distance and one kind of producer. A load at distance 1 stalls, an ALU result at distance 2 uses MEM/WB, and distance 3 goes through the register file. Crossing type, distance and operand gives one bin per path. Then an untested path shows up as an empty bin.

Follow-upPractise Crossing Producer Type with Distance →
What if a branch flush or an interrupt lands while a wrong-path instruction is in EX with a result to forward? L2L3

The flushed instruction must not forward, and must not write the register file. If the forward select ignores the flush, the next correct instruction can take a wrong-path value. Test it by placing dependent instructions right after a mispredicted branch and right at an interrupt. Cover those as their own bins.

Follow-upPractise Forwarding from an Instruction That Is Being Flushed →
Compare checking the pipeline against an ISS with writing assertions on the forwarding unit. L2L3

An ISS compare checks architectural results end to end, so it catches any wrong result. But it reports far from the cause. An assertion checks a local rule, such as "when EX reads the register MEM/WB is writing, the forward select picks MEM/WB". It fires at the cycle of the bug. Use both: the ISS for completeness, assertions to localize.

Follow-upPractise ISS Compare vs Assertions on the Forwarding Unit →
Scale it: what would make you sign off the pipeline for tape-out? L3L4

The plan comes first: every hazard, flush and exception case written as a coverage item. Sign-off needs those items closed, millions of random instructions with zero ISS mismatches, and assertions on the pipeline control that never fire. Formal proofs on the forwarding and stall logic help where tests are thin. Watch the bug-find rate fall to near zero over several weeks.

Follow-upPractise CPU Pipeline Sign-Off →
Latency Versus Throughput in a Pipeline4
You add a register stage in the middle of a slow datapath. What happens to latency, throughput and the clock frequency? L0L1

Latency in cycles goes up by one, because every result passes one more register. Throughput stays at one result per cycle, but each cycle can now be shorter. So results per second go up if the cut really shortens the slowest stage. The register also costs flops and power. The clock is set by the slowest stage, not the average.

QuestionPractise Latency Versus Throughput in a Pipeline →
Why did the cut in the dot product save only 6 levels of logic, not half of them? L1

The clock must fit the slowest stage. The products are still made in one stage, and one 8-bit multiplier is about 31 levels deep. The adder that moved out was short. To go faster, the cut has to go inside the multiplier itself.

Follow-upPractise The Slowest Stage Sets the Clock →
Compare pipelining a unit with building two copies of it that work in parallel. L1L2

Pipelining keeps one copy of the logic and adds registers, so it costs little area but adds latency. Two copies double the area and keep latency the same. But you need logic to split the work and merge the results in order. Pipelining needs the logic to be cut; parallel copies need the work to be independent.

Follow-upPractise Pipelining Versus Parallel Copies →
You pipelined the datapath by one stage. What breaks if the valid signal is not delayed too? L1L2

The valid bit now arrives one cycle before its data. The next block accepts a result that is still the previous one, and the last result has no valid at all. Every control bit that describes the data must pass through the same number of registers.

Follow-upPractise The Valid Bit That Did Not Follow the Data →
Registering Ready with a Skid Buffer4
Your valid/ready pipeline fails timing on the ready path, which runs combinationally through ten stages. Write a stage whose in_ready comes straight from a flop and never loses a beat. L2

Use a skid buffer: an output register plus one spare entry. in_ready is simply "the spare entry is empty", which is a flop. When the sink stalls, the beat already in flight lands in the spare entry. When the sink is ready again, the spare drains first. Two entries are needed, because ready reaches the source one cycle late.

QuestionPractise Registering Ready with a Skid Buffer →
Why does a skid buffer need exactly two entries, not one? L2

When the sink drops ready, the stage only tells the source at the next edge. In that cycle the source may already send one more beat. The output register holds the stalled beat and the spare holds the one in flight. With one entry, the stage must stall every other cycle to stay safe.

Follow-upPractise Why a Skid Buffer Needs Two Entries →
What if ready reaches the source two cycles late, for example across a long wire with two register stages? L2L3

Then up to two beats can be in flight when the sink stalls. The buffer needs room for all of them. In general, the spare space must cover the round-trip delay of the ready signal. This is the same arithmetic as a credit scheme or a FIFO almost-full threshold.

Follow-upPractise Ready That Arrives Two Cycles Late →
Compare a skid buffer with a two-entry FIFO in the same place. L2

Both store two beats and both can drive ready from a flop. A skid buffer keeps the output register at the output, so out_data comes straight from a flop and needs no read mux. A FIFO has pointers and a read mux, which costs more logic. It scales to any depth with the same code.

Follow-upPractise Skid Buffer Versus a Small FIFO →
Retiming a Datapath by Hand5
A two-stage block computes (a + b) * c, but both registers sit after all the logic. What is retiming, and how would you apply it here? L2L3

Retiming moves registers through logic without changing what appears at the outputs, or when. Here the second register buys nothing, so move it back across the multiply. It must go on every path that crosses the cut: the sum and also c. The flop count stays at 34, and the measured depth drops from 42 to 31 levels.

QuestionPractise Retiming a Datapath by Hand →
Why must a retimed register be placed on every path that crosses the cut? L2

The output combines values that entered together. If one input crosses one register fewer, it meets the other inputs a cycle early. Then the output mixes data from two different cycles. Counting registers on each input-to-output path is the check.

Follow-upPractise Every Path Must Cross the Same Number of Registers →
How would retiming break an accumulator, acc <= acc + x? L3

A loop has a fixed number of registers. Moving one more register into it makes the loop take two cycles to go round. The result is then two interleaved sums, not one. Speeding up a loop needs a different algorithm or a faster adder, not a moved register.

Follow-upPractise Retiming into a Feedback Loop →
What if you accept the two interleaved sums? Can that still give a faster accumulator? L3

Yes. Two partial sums, one for even inputs and one for odd, each get two cycles for their adder. At the end, one more add combines them. This is a real technique, but it changes the design: an extra cycle and an extra adder at the end.

Follow-upPractise Two Interleaved Accumulators →
Compare retiming with pipelining. L2

Pipelining adds registers, so latency grows and the rest of the system must accept it. Retiming only moves existing registers, so latency and the interface stay the same. Retiming is the first thing to try when a stage is badly balanced. Pipelining is for when every stage is already full.

Follow-upPractise Retiming Versus Pipelining →
Doubling Throughput: A Micro-Architecture Call4
Your packet-processing block meets timing at 1 GHz but must now handle twice the traffic. Walk through your options and how you would choose. L3L4

Start with questions: is the limit the clock, the datapath width, or dependencies between packets? Then compare three options. A deeper pipeline adds latency and hazards. Two lanes double area and need ordering at the merge. A wider datapath processes two units per cycle, but needs alignment logic. Choose by area, power, latency budget and verification effort, and prototype the risky part first.

QuestionPractise Doubling Throughput: A Micro-Architecture Call →
Compare doubling the datapath width with building two independent lanes. L3

A wider datapath keeps one control path and one ordering, but packets rarely fill whole words. So it needs alignment and partial-word handling. Two lanes keep the narrow logic, but each lane needs control and the merge must restore order. Short packets favour lanes; long streaming data favours width.

Follow-upPractise A Wider Datapath Versus Two Lanes →
How does each option change the verification plan, and how should that affect the choice? L3L4

A deeper pipeline adds hazard and stall scenarios, which need directed tests and coverage of back-to-back dependencies. Two lanes add ordering checks at the merge and tests that make the lanes finish out of order. A wider datapath adds alignment corners. Count that work in weeks and put it next to the area and power numbers.

Follow-upPractise The Verification Cost of an Architecture Choice →
What if each packet updates a counter table that the next packet may read? L3

Then a deeper pipeline creates a read-after-write hazard. The next packet may read the table before the earlier update has been written back. You need forwarding of the in-flight update, or a stall when the same entry is used. Both add logic and rare cases that the verification plan must cover.

Follow-upPractise When Packets Depend on Each Other →
Why a Clock Gate Needs a Latch5
A designer gates a clock with assign gclk = clk & en_q;, where en_q comes from a flop on clk. Draw what goes wrong, and fix it. L1L2

The flop changes en_q just after the rising edge, while clk is still high. So the AND output rises in the middle of a high phase, and the gated flops see an extra edge. A clock-gating cell puts a latch in front of the AND. The latch is open while clk is low and holds while it is high. So the enable can only change the gated clock between pulses.

QuestionPractise Why a Clock Gate Needs a Latch →
Why is the latch open while the clock is low, and not while it is high? L1L2

While the clock is low, the AND output is 0 whatever the enable does. So the enable may change freely then. When the clock rises, the latch closes and holds the enable for the whole high phase. The gated clock then shows either a full pulse or none.

Follow-upPractise Why the ICG Latch Is Open While the Clock Is Low →
Compare writing the latch and AND in RTL with using the library clock-gating cell. L2

The library cell carries setup and hold checks on its enable pin, so STA checks the enable against the clock. Clock-tree tools also know it is a gate in the clock path. Loose gates get none of that. Synthesis can insert the cell for you from ordinary enables, if the flow has a gating step and a library.

Follow-upPractise The Library ICG Cell vs a Latch and an AND in RTL →
Scale it: on a large block, do you put one gate at the clock root? Or many small ones near the registers? L3

A gate near the root stops the most clock tree when the whole block is idle, but only then. Small gates near registers catch more idle cycles, but each costs a cell and timing on its enable. Decide from measured activity: which groups are idle together, and how often. Check the result with power analysis on realistic traffic.

Follow-upPractise Where to Put the Clock Gates →
What happens to a gated register during scan test, when the functional enable is not driven? L2

In scan mode the flops must shift on every clock, whatever the functional enable says. So the scan version of the ICG cell has an extra scan-enable input, ORed with the enable. Test logic holds it high, so the gated clock runs.

Follow-upPractise Clock Gates During Scan Test →
An Enable vs a Gated Clock4
A register should keep its value most of the time. Do you add an enable or gate its clock? What is the difference? L0L1

An enable keeps the clock running. When en is low, an enabled flop or a feedback mux keeps the old value. The output holds, but every clock edge still reaches the flops. A gated clock stops the edges themselves, so the clock pins and that branch of the clock tree stop switching. Gating saves more power but needs an ICG cell and more care in timing.

QuestionPractise An Enable vs a Gated Clock →
Why is the clock network such a large part of dynamic power? L0L1

Dynamic power grows with how often a node switches, its capacitance, the square of the supply and the frequency. The clock switches twice every cycle, more than any data signal. It also drives every flop's clock pin and a large buffered tree. So stopping it where it is not needed saves a lot.

Follow-upPractise Why the Clock Network Burns Power →
Compare writing clock gates by hand with letting synthesis turn your enables into gates. L1L2

If the RTL uses plain enables, a synthesis gating step can group flops that share an enable behind one library ICG. The RTL stays simple and simulates like any enabled register. Hand-placed gates give control, for example to gate a whole block from one signal, but must use the library cell.

Follow-upPractise Letting Synthesis Insert Clock Gates →
What if the enable is computed by deep logic and arrives late in the cycle? L1L2

With an enable flop, en is one more input to the D path, so it must meet the flop's setup time. With an ICG, en must meet the gate's own setup check before the clock rises. That check can be tighter, because the gate sits early in the clock tree. A late enable can stop you from gating.

Follow-upPractise When the Enable Arrives Late →
Choosing a Low-Power Strategy6
You must cut a subsystem's power in half. What techniques do you weigh, and what does each cost? L3L4

First split the budget into dynamic power and leakage, measured on real use cases. Clock gating and operand isolation cut switching, and DVFS lowers voltage and frequency when the load allows. Multi-Vt cells and power gating cut leakage. Power gating needs isolation cells, retention for any state that must survive, and a controller to sequence them. Every step adds verification: UPF-aware simulation and low-power structural checks.

QuestionPractise Choosing a Low-Power Strategy →
Why switch a domain's power off, when stopping its clock already stops the switching? L2L3

Stopping the clock removes dynamic power only. Transistors still leak while the supply is on. In small process nodes, leakage can be a large part of the total. Only removing the supply removes it, at the cost of losing state and a wake-up time.

Follow-upPractise Power Gating vs Stopping the Clock →
What if the isolation is turned on a cycle after the power goes off? L2L3

For that cycle the domain's outputs are unknown, and always-on logic samples them. Power-down must go in order: isolate, save state into retention, then switch off. Power-up goes the other way: switch on, restore, then release isolation.

Follow-upPractise The Order of Isolation, Save and Power-Off →
Compare DVFS with power gating. When would you choose each? L3

DVFS keeps the block running at a lower voltage and frequency, so it keeps its state and cuts dynamic power steeply. It suits work that can run slower. Power gating removes leakage completely, but loses state unless retained, and takes time to wake. It suits blocks that sit idle for long periods.

Follow-upPractise DVFS vs Power Gating →
Scale it: how do you verify the power intent of an SoC with many switched domains? L3L4

Write the intent in UPF: domains, supplies, power states, isolation and retention. Run simulation that reads the UPF, so off domains really corrupt their outputs, and test every power-state change. Add structural checks that isolation cells and level shifters sit where the states need them. Then check the netlist with its power cells against the RTL with low-power equivalence.

Follow-upPractise Verifying the Power Intent →
Break it: which bug escapes if only plain RTL simulation is run on a power-gated design? L3

A register that needs retention but was left out of the retention list. In plain RTL it never loses its value, so wake-up looks perfect. In silicon it comes back random after power-up. Only power-aware simulation, which corrupts non-retained state at power-off, shows it.

Follow-upPractise The Register That Forgot Its State →
Logic Gates from a 2:1 Mux4
You have only 2:1 multiplexers and the constants 0 and 1. Build NOT, AND, OR and XOR. L0

Write the mux as y = s ? b : a and put one input on the select. NOT a is a ? 0 : 1. AND is a ? b : 0, and OR is a ? 1 : b. XOR is a ? ~b : b, so it needs a second mux to make ~b. Five muxes cover all four gates.

QuestionPractise Logic Gates from a 2:1 Mux →
What if you have only NAND gates? Build a 2:1 mux. L0

Four NANDs are enough. One NAND with its inputs tied makes ~s. Two NANDs gate a with ~s and b with s. A last NAND combines them, because NAND of two NANDs is an OR of two ANDs.

Follow-upPractise A 2:1 Mux from NAND Gates →
Compare building gates from 2:1 muxes with using one 4:1 mux. How can a 4:1 mux make any 2-input function? L0L1

Drive the two inputs onto the select and tie the four data inputs to the truth table. The select then picks the output row directly. Changing the four constants changes the function, with no new wiring. This is how an FPGA look-up table works.

Follow-upPractise A 4:1 Mux as a Look-Up Table →
Why can a 2:1 mux build any logic function? L0L1

With constants it makes NOT and AND, and NOT plus AND can express every Boolean function. A mux also splits a function on one variable: f = x ? f(x=1) : f(x=0). Repeat the split on each variable and you get a tree of muxes for any truth table.

Follow-upPractise Why a 2:1 Mux Is a Universal Gate →
A 1011 Sequence Detector with Overlap5
Design an FSM that raises match for every 1011 on a serial input, including overlapping ones. L0L1

Name each state by the longest prefix of 1011 seen so far: none, 1, 10 and 101. In 101, an input of 1 completes the pattern, so match goes high. The next state is 1, because that last 1 can start the next pattern. An input of 0 in 101 goes to 10, not to the start. This Mealy version needs four states.

QuestionPractise A 1011 Sequence Detector with Overlap →
Compare a Moore version of the 1011 detector with the Mealy one. What changes? L0L1

The Moore version needs a fifth state, "1011 seen", and match comes from that state alone. So it rises one cycle later, after the edge that enters the state. The Mealy output rises in the cycle of the last bit. But it can also glitch with the input.

Follow-upPractise Moore vs Mealy for the Same Detector →
A detector passes the stream 1011 but misses the mark in 11011. Which transition is wrong? L1

In state 1, another 1 still leaves a 1 as the newest bit. So the machine must stay in S1. Going to S0 throws away a valid start, and 11011 never reaches S101.

Follow-upPractise The Detector That Missed 1011 Inside 11011 →
What if you skip the FSM and keep the last bits in a shift register? L1

Keep the last three bits and compare them, with the current bit, against 1011. Overlap needs no extra logic, because every window is checked. It costs one flop per pattern bit, while the FSM needs only enough flops to count its states. For long patterns, the FSM is smaller.

Follow-upPractise A Shift Register Instead of an FSM →
What if the pattern is only two bits long? Detect a rising edge on a signal already in the clock domain. L0

Register the signal once and compare old with new: rise = sig & ~sig_q. It is a detector for the sequence 01. The pulse lasts one clock. If sig comes from another clock domain, synchronize it first.

Follow-upPractise The Smallest Sequence Detector: A Rising Edge →
Is This Number a Power of Two5
Write a one-line check that an 8-bit unsigned x is a power of two. L0

Use x != 0 && (x & (x - 1)) == 0. A power of two has exactly one bit set. Subtracting 1 clears that bit and sets all the bits below it, so the AND is zero. The x != 0 part matters, because zero also gives a zero AND. In hardware it is a subtractor, an AND and two zero checks.

QuestionPractise Is This Number a Power of Two →
The input is now an 8-bit signed value, kept in 8 bits. Which input breaks the check? L0L1

-128 breaks it. Its pattern is 1000_0000, one bit set. In 8 bits, -128 - 1 wraps to 127, so the AND is zero. Check x > 0 instead of x != 0.

Follow-upPractise The Signed Input That Passed as a Power of Two →
Count the set bits in a byte. Compare a bit-by-bit loop with the x & (x - 1) trick. L0L1

The loop looks at all 8 bits every time. The trick clears one 1 per step, so it takes as many steps as there are ones. In software, that saves time for sparse words. In hardware, the fixed 8-step loop unrolls to a popcount tree. The clear-lowest loop must be bounded to 8 steps before synthesis; it then gives similar logic, not fewer steps.

Follow-upPractise Counting the Ones in a Word →
Why does x & (x - 1) clear the lowest set bit? L0

Subtracting 1 borrows from the lowest 1. That bit becomes 0 and every 0 below it becomes 1. Bits above it do not change. ANDing with x keeps the upper bits and zeroes the rest.

Follow-upPractise Why x & (x - 1) Clears the Lowest One →
What if the next puzzle is Gray code? Convert binary to Gray and back. L0L1

Binary to Gray is g = b ^ (b >> 1). The way back is not the same formula. Each binary bit is the XOR of all the Gray bits at and above it. Consecutive Gray values differ in one bit, including the wrap from 15 to 0.

Follow-upPractise Binary to Gray Code and Back →

Your Review Queue

Saved review reminders are coming soon.