A comprehensive collection of reusable VHDL IP cores for digital design, including memory modules, synchronisers, clock generators, and utility packages.
- Single Port RAM - Configurable single-port memory with enable and reset functionality
- Dual Port RAM - True dual-port memory for concurrent read/write operations
- Dual Clock RAM - Asynchronous dual-port memory for clock domain crossing
- Synchronous FIFO - First-in-first-out buffer for single clock domain
- Asynchronous FIFO - FIFO with separate read/write clocks and gray code pointers
- ROM - Read-only memory with initialisation file support
- FF Synchroniser - Multi-stage flip-flop synchroniser for CDC
- FF Synchroniser Vector - Vector version of flip-flop synchroniser
- Clock Generator - Configurable clock generation module
- Reset on Startup - Power-on reset generation
- Clock Enable - Clock enable generator for clock division
- SPI Interface - Complete SPI communication interface with configurable modes
- SPI TX - SPI transmit module
- SPI RX - SPI receive module
- SPI Package - SPI related constants and types
- Debouncer - Button/switch debouncing with configurable timing
- utils_pkg - General-purpose utility functions for VHDL design and verification (see
ip/vhdl_utils/README.md
for full list) - tb_utils - Testbench utilities for clock generation, reset, and simulation support (see
ip/vhdl_utils/README.md
for details) - memories_pkg - Memory-related constants and types
- MIT Licensed - Permissive licensing for commercial and open-source use
- VHDL-2008 Compatible - Modern VHDL standard support
- Comprehensive Testing - Full VUnit test coverage for all modules
- FPGA Optimised - Designed for efficient synthesis on Xilinx and Intel FPGAs
- Instance-Based Naming - Clear port naming conventions (
write_data
/read_data
) - Enhanced Interfaces - Proper enable, reset, and control signal support
ip/
├── pll/ # Clock generation modules
├── clock_enable/ # Clock enable generator
├── debouncer/ # Input debouncing
├── ff_synchroniser/ # Clock domain crossing synchronizers
├── communication/ # Communication interfaces
│ └── spi/ # SPI interface modules
├── memories/ # Memory IP cores
│ ├── fifo/ # FIFO implementations
│ ├── ram/ # RAM modules (single/dual port)
│ └── rom/ # ROM modules
├── reset_on_startup/ # Reset generation
└── utils/ # Utility packages and testbench helpers
-- Single Port RAM instantiation
ram_inst: entity work.single_port_ram
port map (
sys_clk => clk,
sys_rst_n => rst_n,
en => ram_enable,
write_and_not_read => write_mode,
address => ram_addr,
write_data => data_to_write,
read_data => data_from_ram
);
-- Dual Port RAM instantiation
dual_ram_inst: entity work.dual_port_ram
port map (
sys_clk => clk,
sys_rst_n => rst_n,
en => ram_enable,
write_enable => wr_en,
read_enable => rd_en,
write_address => wr_addr,
read_address => rd_addr,
write_data => wr_data,
read_data => rd_data
);
-- SPI Interface instantiation
spi_inst: entity work.spi_interface
port map (
sys_clk => clk,
sys_rst_n => rst_n,
-- SPI signals
spi_sck => spi_clk,
spi_mosi => mosi,
spi_miso => miso,
spi_cs_n => cs_n,
-- Control interface
tx_data => data_to_send,
tx_valid => tx_valid,
tx_ready => tx_ready,
rx_data => received_data,
rx_valid => rx_valid
);
-- Clock Enable instantiation
clk_en_inst: entity work.clock_enable
generic map (
DIV_FACTOR => 4 -- Divide clock by 4
)
port map (
sys_clk => clk,
sys_rst_n => rst_n,
clk_en_out => clk_en
);
The VHDL codes are tested with VUnit framework's checks, OSVVM random features and simulated with EDA Playground and/or ModelSim.
- OS: (Anything that can run the following)
- IDE:
VSCode latest
with following plugins:
- VHDL Simulator: (Anything that supports VHDL-2008)
- Script execution environment:
Python 3.11.4
to automatise testing via VUnit
- IDE:
- Open terminal
- Run
git clone git@github.com:nselvara/HDL-Core-Lib.git
- Run
cd HDL-Core-Lib
- Run
code .
to open VSCode in the current directory
- Open VSCode
- Press
CTRL + Shift + P
- Search for
Python: Create Environment
command - Select
Venv
- Select the latest Python version
- Select
requirements.txt
file - Wait till it creates and activates it automatically
- Open VSCode
- Press
CTRL + J
if it's Windows orCTRL+`
for Linux to open the terminal - Run
python -m venv .venv
in Windows Terminal (CMD) orpython3 -m venv .venv
in Linux Terminal - Run
.\.venv\Scripts\activate
on Windows orsource .venv/bin/activate
on Linux - Run
pip install -r requirements.txt
to install all of the dependencies - Click on
Yes
when the prompt appears in the right bottom corner
For more info see page: Python environments in VS Code
You can simulate this project on EDA Playground without installing anything locally. Use the following settings:
- Testbench + Design:
VHDL
- Top entity:
tb_test_entity
(or whatever your testbench entity is called) - ✅ Enable
VUnit
(required to use VUnit checks likecheck_equal
)
Warning
Enabling VUnit will automatically create a testbench.py
file.
Do not delete this file, as it is required for:
- Initializing the VUnit test runner
- Loading
vunit_lib
correctly - Enabling procedures such as
check_equal
,check_true
, etc.
Warning
However, EDA Playground will not create any VHDL testbench for you. Therefore, you need to manually create your own VHDL testbench file:
- Click the ➕ symbol next to the file list
- Name it
tb.vhd
(or your own testbench name) - Paste your testbench VHDL code into it
- ✅ Select
OSVVM
under Libraries if your testbench uses OSVVM features - Tools & Simulators:
Aldec Riviera Pro 2022.04
or newer - Compile Options:
-2008
- ✅ Check
Open EPWave after run
- ✅ Check
Use run.do Tcl file
orUse run.bash shell script
for more control (optional)
These settings ensure compatibility with your VUnit-based testbenches and allow waveform viewing through EPWave.
Make sure the environment variable for ModelSim or QuestaSim is set, if not:
Note
Don't forget to write the correct path to the ModelSim/QuestaSim folder
Open terminal and run either of the following commands:
echo "export VUNIT_MODELSIM_PATH=/opt/modelsim/modelsim_dlx/linuxpe" >> ~/.bashrc
# $questa_fe is the path to the folder where QuestaSim is installed
echo "export VUNIT_MODELSIM_PATH=\"$questa_fe/21.4/questa_fe/win64/\"" >> ~/.bashrc
Then restart the terminal or run source ~/.bashrc
command.
Open PowerShell and run either of the following commands:
setx /m VUNIT_MODELSIM_PATH C:\modelsim_dlx64_2020.4\win64pe\
setx /m VUNIT_MODELSIM_PATH C:\intelFPGA_pro\21.4\questa_fe\win64\
This project uses VUnit for automated VHDL testbench simulation.
The script test_runner.py
acts as a wrapper, so you don't need to deal with VUnit internals.
-
Open VSCode (or any editor/terminal).
-
To run all testbenches, simply execute:
./.venv/Scripts/python.exe ./ip/test_runner.py
- Uses
run_all_testbenches_lib
internally.- This hides the VUnit implementation
- Looks for testbenches in the
./ip/
folder. - Runs all files matching
tb_*.vhd
(recursive pattern**
). - GUI can be enabled via
gui=True
intest_runner.py
.
You can change the following arguments in test_runner.py
:
run_all_testbenches_lib(
path="./ip/", # Path where the HDL & tb files are located
tb_pattern="**", # Match all testbenches
timeout_ms=1.0, # Timeout in milliseconds
gui=False, # Set to True to open ModelSim/QuestaSim GUI
compile_only=False, # Only compile, don't run simulations
clean=False, # Clean before building
debug=False, # Enable debug logging
use_xilinx_libs=False, # Add Xilinx simulation libraries
use_intel_altera_libs=False, # Add Intel/Altera simulation libraries
excluded_list=[], # List of testbenches to exclude
xunit_xml="./test/res.xml" # Output file for test results
)
Most IP cores in this library support multiple implementations:
- Xilinx: Optimised for Vivado/ISE, using Xilinx simulation libraries (e.g., XPM, UNISIM, UNIMACRO)
- Intel/Altera: Optimised for Quartus, using Intel/Altera simulation libraries (e.g., altera_mf)
- Own/Behavioral: Technology-independent VHDL-2008 behavioural implementation if possible
IP Core | Xilinx Implementation | Intel/Altera Implementation | Own/Behavioral Implementation |
---|---|---|---|
Single Port RAM | Yes | Yes | Yes |
Dual Port RAM | Yes | Yes | Yes |
Dual Clock RAM | Yes | Yes | Yes |
Synchronous FIFO | Yes | Yes | Yes |
Asynchronous FIFO | Yes | Yes | Yes |
ROM | Yes | Yes | Yes |
FF Synchroniser | Yes | Yes | Yes |
FF Synchroniser Vector | Yes | Yes | Yes |
Clock Generator (PLL) | Yes (Xilinx PLL) | Yes (Intel PLL) | No |
Clock Enable | Yes | Yes | Yes |
SPI Interface | Yes | Yes | Yes |
Debouncer | Yes | Yes | Yes |
Reset on Startup | Yes | Yes | Yes |
Note
- Xilinx simulation libraries (XPM, UNISIM, UNIMACRO) must be installed and available at:
/opt/xilinx/vivado/data/vhdl/src/
(Linux CI)C:\Xilinx\Vivado\<version>\data\vhdl\src\
(Windows)- XPM VHDL:
/opt/Xilinx/Vivado/<version>/data/ip/xpm/
orC:\Xilinx\Vivado\<version>\data\ip\xpm\
- Intel/Altera simulation libraries (altera_mf, lpm, etc.) must be available at:
/opt/intelFPGA/<version>/quartus/eda/sim_lib/
(Linux CI)C:/intelFPGA_pro/<version>/quartus/eda/sim_lib/
(Windows)
- The technology-independent (own/behavioral) implementation is always available and does not require vendor libraries.
- PLL modules are vendor-specific and do not have a pure behavioral implementation.
Contributions are welcome! Please ensure:
- All new modules include comprehensive VUnit testbenches
- Code follows the established naming conventions
- Documentation is updated accordingly
- All tests pass before submitting
This project is licensed under the MIT License - see the LICENSE file for details.