Mark Sui

← All projects

UC San Diego · ECE 111 Final Project · Digital Design

SystemVerilog
Viterbi Decoder

Recovering a bitstream through a noisy channel, one survivor path at a time. An 8-state decoder built around branch metrics, add-compare-select logic, and banked traceback memory.

Implemented a recursive systematic convolutional encoder and modular decoder, then evaluated recovery under periodic, randomized, and burst error injection.

Implementation
SystemVerilog RTL
Code rate / states
1/2 · 8 states
Documented experiments
22 error cases
Periodic cases 2a1–2a5
0 output errors

01 / Architecture

From received symbols to recovered bits

The encoder produces two bits per input bit: the original bit and a parity bit derived from the current input and encoder state. The channel wrapper injects errors before the decoder scores candidate paths.

  1. Received symbol2 channel bits
  2. BMCHamming distance
  3. ACS8 survivor decisions
  4. Survivor memory4 × 1024 × 8 bits
  5. TracebackRecovered bitstream

Score each branch

BMC blocks compare the received pair with each expected pair. The resulting 2-bit Hamming distance becomes the local cost for a candidate transition.

Inspect BMC RTL →

Keep the survivor

Eight ACS instances add branch costs to 8-bit path metrics. Validity flags gate candidates; the lower-cost valid path survives. Equal costs select path 0.

Inspect ACS RTL →

Reconstruct the sequence

Four memory banks retain the eight survivor decisions per step. Two traceback units traverse decisions, with display memories staging decoded output.

Inspect decoder integration →

A concrete ACS decision

Input: both paths valid; prior costs 5, 7; branch costs 2, 1.
Output: path_cost = 7, selection = 0, valid_o = 1.
Why: candidate costs are 5 + 2 = 7 and 7 + 1 = 8, so path 0 survives. This illustrates the combinational rule in ACS.sv.

02 / Design decisions

The integration work behind the datapath

Match encoder and trellis

The final project uses a recursive systematic encoder. Its symbol mapping must match the decoder’s branch metrics; substituting the nonrecursive homework encoder changes that mapping.

Encoder source →

Bound the path metrics

The decoder checks the high bit of all eight stored path costs. When all are set, it masks the next ACS costs to seven bits as part of the metric update.

Metric update and bank control →

Align memory and traceback

Synchronous memory reads and delayed bank-selection signals coordinate writes, reverse reads, and traceback. Output history is captured after the testbench’s startup delay.

Traceback source →

03 / Verification & results

Recovery succeeds—and has a boundary

The end-to-end testbench keeps input and output histories and compares 256 decoded bits after a startup delay. The Part 2 report records 22 experiments spanning periodic errors (2a), randomized errors (2b), and increasingly dense patterns (2c–2e).

Selected results transcribed from the Part 2 report, page 1.
CasePatternInjected errorsOutput errors
2a101310
2a6010101013230
2b210373
2c3010101480
2c010101016481
2e111111116444

Engineering takeaway: error placement matters alongside error count. These experiments include both complete recovery and patterns that drive the decoder onto an incorrect path. Injected channel-bit errors and decoded output-bit errors are separate measurements.

These are recorded coursework simulation results, not a new benchmark run or a general error-rate guarantee. The published evidence covers RTL and simulation; FPGA utilization, timing closure, and board measurements are not reported here.

04 / Project evidence

Go directly to the implementation

Course repository

Final-part-1 and Final-part-2 contain this project. The homework folders are separate exercises.

Open GitHub repository →

Put the project in context.

Explore my background or get in touch about RTL, ASIC, FPGA, and software engineering opportunities.