-
Notifications
You must be signed in to change notification settings - Fork 0
Building and Synthesis
-
GHDL (version 0.35+): VHDL simulator and analyzer
- Windows: https://github.com/ghdl/ghdl/releases
- Linux:
sudo apt-get install ghdl - macOS:
brew install ghdl
-
GNU Make: Build automation
- Windows: MinGW-w64 or equivalent
- Linux/macOS: Usually pre-installed
-
Python 3.6+: ROM conversion utility
- Windows/Linux/macOS: https://www.python.org/downloads/
For actual FPGA implementation, you'll need vendor tools:
- Xilinx Vivado (Xilinx FPGA targets)
- Intel Quartus (Intel Altera FPGA targets)
- Lattice Diamond (Lattice FPGA targets)
- GowinEDA / GOWIN FPGA Designer (Tang Primer 20K / GW2A targets)
- Open Source: Project Trellis, nextpnr (for open source flows)
Windows:
- Download GHDL installer from GitHub releases
- Run installer and follow prompts
- Add GHDL to system PATH
Linux:
sudo apt-get install ghdl ghdl-mcodemacOS:
brew install ghdlghdl --versionShould output something like:
GHDL 0.35 (tarball) [Dunoon edition]
Navigate to the FPGA directory:
cd fpga/
make testThis will:
- Compile all VHDL modules
- Elaborate testbenches
- Run each test simulation
- Report pass/fail status
If you want to build individual components:
# Analyze only (check syntax)
ghdl -a --std=08 --ieee=synopsys rtl/sbc_pkg.vhd
ghdl -a --std=08 --ieee=synopsys rtl/bus_decode.vhd
# Elaborate (link)
ghdl -e --std=08 --ieee=synopsys tb_bus_decode
# Run simulation
ghdl -r --std=08 --ieee=synopsys tb_bus_decode --ieee-asserts=disable-at-0Convert binary ROM files to VHDL hex format:
python tools/bin_to_vhdl_hex.py [OPTIONS] [ROM_FILES]--size SIZE ROM size in bytes (hex, e.g., 0x4000)
--output FILE Output hex file path
ROM_FILE[@OFFSET] ROM file with optional offset
Single ROM file:
python tools/bin_to_vhdl_hex.py --size 0x4000 \
--output rom.hex \
../roms/chess.romMultiple ROM files at different offsets:
python tools/bin_to_vhdl_hex.py --size 0x4000 \
--output rom.hex \
../roms/kernel.rom@0x0000 \
../roms/msbasic.rom@0x1000Kernel + EhBASIC system image:
python tools/bin_to_vhdl_hex.py --size 0x4000 \
--output rom.hex \
../roms/kernel.rom@0x0000 \
../roms/ehbasic.rom@0x1000Output format (text file, space-separated):
0000 A9
0001 42
0002 8D
0003 02
0004 00
- Input: Raw binary files
- Output: Text format (offset byte, both hex)
- Composition: Multiple files combined at different offsets
- Size: Padded with 0xEA (NOP) up to specified size
- Endianness: Big-endian in output (matches 6502 reset vector convention)
The project includes a Makefile with standard targets:
make test # Run all tests (default)
make clean # Remove generated files
make help # Show available targetsOverride variables when running make:
make test GHDL=/path/to/ghdl # Specify GHDL path
make clean # Clean working directoryThe project uses these GHDL flags:
--std=08 IEEE 1076-2008 standard (modern VHDL)
--ieee=synopsys Enable Synopsys extensions (std_logic_unsigned, etc.)
The --ieee=synopsys flag is required for the T65 CPU core compatibility.
-
RTL Preparation
# Copy all RTL files to synthesis project cp -r rtl/ /path/to/vivado/project/ -
Testbench Integration (optional)
- Some vendors support RTL simulation
- Use GHDL for pre-synthesis verification
- Keep testbenches separate from synthesis
-
Constraints File
- Check
constraints/directory for board-specific files - Map port names to physical FPGA pins
- Define timing constraints (clock period, setup/hold)
- Check
-
Synthesis & Implementation
- Follow vendor-specific flow
- Target block RAM for sram_i and rom_i
- Ensure synchronous design constraints
-
Timing Analysis
- Verify clock frequency meets requirements (50-100 MHz typical)
- Check setup/hold margins
- Ensure no critical timing paths
PIX16 Spartan-6 / Xilinx ISE:
- Use the Xilinx ISE tools, not Vivado, for the Spartan-6 board.
- Create the SD-boot project from an ISE Command Prompt if
xtclshis not in PATH:cd fpga xtclsh scripts/create_sd_boot_ise_project.tcl - Create the SD card image with:
cd fpga make sd-boot-image - Program the FPGA bitstream once, then update ROM contents by rewriting
sim/generated/sbc_ehbasic_sd.imgto the SD card.
Tang Primer 20K / GowinEDA:
- Open
fpga/boards/tang_primer_20k/project/tang_sbc.gprjin GowinEDA. - The active top is
tang20k_sbc_top. - The project targets
GW2A-18C/GW2A-LV18PG256C8/I7, matching the Sipeed Tang Primer 20K examples. - The current bring-up path uses HDMI boot/status output, CH340 UART at
230400 8N1, KEY1 for the FPGA monitor, and the on-board microSD/SDIO slot in SPI mode onN10/N11/R14/M8. - The SDIO slot uses dual-purpose pins. In
Project > Configuration, enable the correspondingSSPIoption so pins such assd_miso=M8can be used as regular IO. The checked-in generated implementation config also enablesMSPI, matching Sipeed's working example projects for the dock. - If Gowin regenerates
impl/pnr/device.cfgwithSSPI regular_io = false, run this after Synthesis and before Place & Route:powershell -ExecutionPolicy Bypass -File fpga/boards/tang_primer_20k/scripts/fix_gowin_dual_purpose.ps1
- If place-and-route reports stale object errors from
project/impl/gwsynthesis/tang_sbc.vg, force a full resynthesis or clean the generated implementation directory. The.vgfile is a generated netlist from the previous synthesis run.
Xilinx Vivado:
- Block RAM configured for:
- Synchronous reads (default sync_ram mode)
- Asynchronous reads (optional ASYNC_READ mode)
- Create IP core for ROM initialization from hex
- Use
INIT_FILEgeneric to specify hex file path
Intel Quartus:
- Use ALTERA_RAM_EMBEDDED_FIFO primitive
- Configure with synchronous mode
- Use MIF (Memory Initialization File) format for ROM
Lattice:
- Use ECP5 or MachXO primitives
- Memory configuration differs by family
- Refer to Lattice design guides
Error: ghdl: command not found
Solution:
- Verify GHDL installation:
ghdl --version - Check PATH environment variable includes GHDL bin directory
- On Windows, ensure installer added to PATH during installation
Error: unknown option '-fsynopsys'
Solution: Use --ieee=synopsys flag instead:
ghdl -a --std=08 --ieee=synopsys rtl/sbc_pkg.vhdError: could not open ROM init file: sim/generated/chess_rom.hex
Solution:
- Verify ROM file exists:
ls -la sim/generated/ - Run ROM generation:
make test(generates ROM files automatically) - Check file permissions
Cause: Unbounded loops, missing wait statements
Solution:
- Set timeout in GHDL:
ghdl -r ... --stop-time=10ms - Check for
wait;without timeout in testbenches - Look for loops without
waitstatements inside
Run full test suite before committing:
cd fpga/
make testAll tests should PASS.
Create .github/workflows/ghdl-test.yml:
name: GHDL Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install GHDL
run: sudo apt-get install ghdl
- name: Run tests
run: cd fpga && make test- Synchronous reads: Faster simulation (pipelined with CPU)
- Asynchronous reads: Slower but required for T65 core
- Reduce verbosity: Remove
reportstatements in loops
- Incremental build: Reuse previous results when possible
-
Parallel compilation: Use
-jflag (if supported) - Block RAM optimization: Vendor tools optimize automatically
- GHDL uses ~100-200 MB for full system simulation
- Increase available memory if simulations crash
- Reduce stimulus size for memory-constrained systems
Estimated resource usage:
| Resource | Count | Notes |
|---|---|---|
| Block RAM | 48KB | 32KB SRAM + 16KB ROM |
| LUTs | 5K-10K | CPU adapter + peripherals |
| Registers | 5K | State and data registers |
| Clock Freq | 50-100 MHz | Target frequency |
See Also:
- Testing Guide - Running individual tests
- Architecture - System design
- Development Guide - Contributing code
Generated from 6502-sbc-fpga Markdown documentation. Part of the 6502 SBC emulator project (emulator Wiki).