Project workflow¶
1. Write the specification¶
For each block, record:
- Purpose.
- Ports, widths, polarities, and units.
- Clock domain.
- Reset behavior.
- Latency and throughput.
- Legal input sequences.
- Boundary/error behavior.
- Verification acceptance criteria.
Example:
When enable is high at a rising edge, the 8-bit count increases modulo 256. Synchronous active-high reset has priority and sets the count to zero. When enable is low, the count holds.
This paragraph almost writes both RTL and testbench.
2. Plan hierarchy¶
Separate:
- Board wrapper.
- Clock/reset/CDC boundary.
- Control FSM.
- Datapath.
- Peripheral/interface blocks.
- Shared packages.
Prefer small interfaces and explicit handshakes.
3. Implement one vertical slice¶
Build the smallest useful path from input through core logic to output. Compile immediately. Do not write the entire system before the first simulation.
4. Verify from the bottom up¶
Test leaf components first:
- Pure functions.
- Combinational blocks.
- Counters/timers.
- Interfaces.
- FSM/control.
- Integrated core.
- Board wrapper smoke test.
Unit tests localize failures. Integration tests verify contracts between blocks.
5. Automate immediately¶
As soon as a test works:
- Put it in the regression runner.
- Add a timeout.
- Make pass/fail machine-readable.
- Store failing seeds/vectors.
- Run all tests after each meaningful change.
6. Add physical constraints¶
Treat XDC as reviewed source code:
- Pin assignments from board documentation.
- Clock periods.
- External interface delays.
- Narrowly justified exceptions.
Keep board constraints separate from reusable core RTL.
7. Inspect synthesis¶
Ask:
- Did the intended RAM, DSP, or carry chain infer?
- Are there unintended latches?
- Was important logic removed?
- Are widths and resource counts plausible?
- Are clocks and enables mapped correctly?
8. Inspect implementation¶
Require:
- DRC acceptance.
- Correct clocks.
- No unintended unconstrained paths.
- Setup and hold success.
- CDC review.
9. Hardware validation¶
Plan observability:
- LEDs for state/error codes.
- Seven-segment status.
- UART diagnostic output.
- Integrated Logic Analyzer for internal signals when needed.
The Integrated Logic Analyzer consumes FPGA resources and samples real hardware, but it does not replace a testbench.
10. Preserve reproducibility¶
Track with Git:
.vhdsource..xdcconstraints.- Test vectors/generators.
- Simulation/build scripts.
- Documentation.
- Small important reports.
Ignore generated simulation/build caches and recreate them.
Review checklist¶
Requirements¶
- Behavior is unambiguous.
- Clock/reset/latency are documented.
- Corner cases are defined.
RTL¶
- Numeric types express meaning.
- Width changes are explicit.
- Combinational assignments are complete.
- Registers have clear ownership.
- CDC is explicit.
Verification¶
- Normal and boundary cases run automatically.
- Reference model is independent.
- Timeout exists.
- Regression returns non-zero on failure.
Physical implementation¶
- Pins and I/O standards are correct.
- Every clock is constrained.
- Timing and CDC reports are clean or justified.
- Resource usage is plausible.
Handoff¶
- Another person can build and test from the README.
- Tool/board versions are recorded.
- No essential source exists only inside a generated project folder.