Compare commits

...

16 Commits

Author SHA1 Message Date
81524edd18 feat(vscode): add custom color theme settings 2025-07-18 19:19:57 +02:00
40df0e3e65 refactor(module): improve naming consistency in pipeline components 2025-07-18 19:19:23 +02:00
30d00812c1 chore(devcontainer): updates image and configuration
- Updates the devcontainer image to a newer version.
- Modifies the GPG agent path for consistency.
- Adds the WakaTime extension for tracking development time.
- Updates the postStartCommand to install hdlbuild from a
  private package repository.
2025-07-15 14:58:21 +00:00
a143e8a1aa refactor: Simplifies ready signal logic in buffer controller
- Removes redundant signal and assigns directly to output.
- Simplifies the state update logic for the ready signal.
2025-07-11 10:52:06 +00:00
506f2edabb fix: Corrects ready signal and data buffering logic
- Corrects the ready signal to properly reflect buffer status.
- Modifies data buffering logic to ensure proper data handling.
- Updates the ready signal to high when buffer is not full.
2025-07-11 10:17:37 +00:00
5e1a3c2161 refactor: adjusts pipeline parameters for performance
- Changes clock frequency to 280 MHz.
- Reduces pipeline module count to improve performance.
2025-07-11 10:15:49 +00:00
88753b62f4 feat: implements pipelined module chaining for performance
- Introduces a pipelined module and top-level wrapper for
  performance benchmarking.
- Chains multiple pipeline modules in series to increase throughput.
- Adds generics to control pipeline depth, data width, and
  register balancing.
- Includes optional CE/RST enables and pipeline buffer.
2025-07-11 10:05:02 +00:00
96833c0f77 test: Updates waveform configuration for testbench
- Corrects signal names in the waveform configuration file.
- Adds individual bit signals for output data.
2025-07-11 10:03:32 +00:00
caff24255d Refactor: Reduces maximum fanout for nets
- Reduces the maximum allowed fanout value to improve timing
  closure.
- This change aims to optimize resource utilization.
2025-07-11 10:03:18 +00:00
c51815cb51 Updates devcontainer.json to add volume mapping for GPG agent and formats the configuration for clarity 2025-04-27 19:01:34 +00:00
d847fe3dc8 Updates .gitignore to include build directories for improved project management 2025-04-27 19:01:24 +00:00
cb5259c284 Refactors project.yml to clarify dependencies and improve tool options formatting 2025-04-27 19:01:08 +00:00
c74b34f610 Adds devcontainer configuration and updates project structure to hdlbuild 2025-04-27 17:46:05 +00:00
454172e91c Standardizes formatting and adds output signal
Adjusts entity and architecture formatting for consistency, aligning spacing and indentation across declarations and constants.

Adds `O_MUX_Select` output signal to indicate routing decision, improving functionality and clarity of the module.
2025-04-24 18:29:53 +00:00
3a588948a6 Adds PipelineSwitch entity and testbench
Introduces the PipelineSwitch component with configurable routing behavior based on input comparison modes. Implements modes such as "none", "or", "and", "xor", "equal", and others. Adds a comprehensive testbench to validate functionality across all supported modes.
2025-04-19 20:39:29 +00:00
286ae5a12c Adds pipeline buffer and controller with testbench
Implements a pipeline buffer component supporting passthrough and register modes, controlled via a dedicated controller.
Adds AXI-like handshake signals for data flow management.
Includes a testbench to validate functionality with randomized delays.

Addresses robust data buffering and flow control.
2025-04-19 20:39:13 +00:00
17 changed files with 1795 additions and 413 deletions

View File

@@ -0,0 +1,31 @@
{
"name": "Xilinx ISE 14.7",
"image": "git.0xmax42.io/simdev/xilinx-ise:latest",
"runArgs": [
"--privileged",
"--cap-add=SYS_ADMIN",
"--shm-size=2g",
"-v",
"/run/user/1000/gnupg/S.gpg-agent:/home/xilinx/.gnupg/S.gpg-agent"
],
"customizations": {
"vscode": {
"extensions": [
"/home/xilinx/vsxirepo/vhdl-by-hgb.vsix",
"eamodio.gitlens",
"WakaTime.vscode-wakatime"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
}
}
},
"remoteUser": "xilinx",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {},
"forwardPorts": [
10000
],
"postStartCommand": "git config --global user.signingkey 87C8A5DD5C14DF55DBE1DB4199AC216D447E61C0 && git config --global gpg.format openpgp && git config --global commit.gpgsign true && git config --global tag.forceSignAnnotated true && pip install --upgrade --index-url https://git.0xmax42.io/api/packages/maxp/pypi/simple/ --extra-index-url https://pypi.org/simple/ hdlbuild"
}

5
.gitignore vendored
View File

@@ -1,3 +1,6 @@
build/working
.hdlbuild_deps/
.working/
reports/
output/
.locale/
vhdl_ls.toml

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "build"]
path = build
url = https://github.com/PxaMMaxP/Xilinx-ISE-Makefile.git

12
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,12 @@
{
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#9ed8bc",
"activityBar.background": "#9ed8bc",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#a177c8",
"activityBarBadge.foreground": "#15202b"
},
"peacock.color": "#7ac9a3",
"peacock.remoteColor": "#e67338"
}

1
build

Submodule build deleted from a8ed470e7d

View File

View File

@@ -1,306 +0,0 @@
## Main settings.. ##
# Project name
# @remark The name of the project is used as default name for the top module and the ucf file
PROJECT = Pipeline
# Target device
# @example xc3s1200e-4-fg320 | xc5vlx50t-1-ff1136
TARGET_PART = xc3s1200e-4-fg320
# Path to the Xilinx ISE installation
XILINX = /opt/Xilinx/14.7/ISE_DS/ISE
# Optional the name of the top module (default is the project name)
TOPLEVEL = PipelineFilter
# Optional the name of the ucf file (default is the project name)
CONSTRAINTS = src/Pipeline_pb.ucf
## ## ## ## ## ## ## ##
# ---------------------
## Source files settings.. ##
# The source files to be compiled
# @example `VSOURCE += src/main.v` (add a single Verilog file per line)
# @example `VHDSOURCE += src/main.vhd` (add a single VHDL file per line)
VHDSOURCE += src/Pipeline_pb.vhd
VHDSOURCE += src/PipelineController.vhd
VHDSOURCE += src/PipelineRegister.vhd
VHDSOURCE += src/PipelineFilter.vhd
# VHDTEST += tests/Pipeline_tb.vhd
VHDTEST += tests/PipelineFilter_tb.vhd
## ## ## ## ## ## ## ##
# ---------------------
## ISE executable settings.. ##
# General command line options to be passed to all ISE executables (default is `-intstyle xflow`)
# COMMON_OPTS =
# Options for the XST synthesizer
#### Synthese Options (XST) #####
# Optimization goal: prioritize speed or area.
# Values: Speed | Area
XST_OPTS += -opt_mode Speed
# Optimization level: more aggressive optimizations at level 2.
# Values: 1 | 2
XST_OPTS += -opt_level 2
# Use the new XST parser (recommended for modern designs).
# Values: yes | no
XST_OPTS += -use_new_parser yes
# Preserve design hierarchy or allow flattening for optimization.
# Values: Yes | No | Soft
XST_OPTS += -keep_hierarchy No
# Determines how hierarchy is preserved in the netlist.
# Values: As_Optimized | Rebuilt
XST_OPTS += -netlist_hierarchy As_Optimized
# Global optimization strategy for nets.
# Values: AllClockNets | Offset_In_Before | Offset_Out_After | Inpad_To_Outpad | Max_Delay
XST_OPTS += -glob_opt AllClockNets
## Misc ##
# Enable reading of IP cores.
# Values: YES | NO
XST_OPTS += -read_cores YES
# Do not write timing constraints into synthesis report.
# Values: YES | NO
XST_OPTS += -write_timing_constraints NO
# Analyze paths across different clock domains.
# Values: YES | NO
XST_OPTS += -cross_clock_analysis NO
# Character used to separate hierarchy levels in instance names.
# Default: /
XST_OPTS += -hierarchy_separator /
# Delimiters used for bus signals.
# Values: <> | [] | () | {}
XST_OPTS += -bus_delimiter <>
# Maintain original case of identifiers.
# Values: Maintain | Upper | Lower
XST_OPTS += -case Maintain
# Target maximum utilization ratio for slices.
# Values: 1–100
XST_OPTS += -slice_utilization_ratio 100
# Target maximum utilization ratio for BRAMs.
# Values: 1–100
XST_OPTS += -bram_utilization_ratio 100
# Use Verilog 2001 syntax features.
# Values: YES | NO
XST_OPTS += -verilog2001 YES
#### HDL Options ####
## FSM ##
# Extract FSMs (Finite State Machines) from HDL code.
# Values: YES | NO
XST_OPTS += -fsm_extract YES
# Encoding strategy for FSMs.
# Values: Auto | Gray | One-Hot | Johnson | Compact | Sequential | Speed1 | User
XST_OPTS += -fsm_encoding Auto
# Add safe logic for undefined FSM states.
# Values: Yes | No
XST_OPTS += -safe_implementation No
# Structure used to implement FSMs.
# Values: LUT | BRAM
XST_OPTS += -fsm_style LUT
## RAM/ROM ##
# Extract RAM inference from HDL.
# Values: Yes | No
XST_OPTS += -ram_extract Yes
# Style used to implement RAM.
# Values: Auto | Block | Distributed
XST_OPTS += -ram_style Auto
# Extract ROM inference from HDL.
# Values: Yes | No
XST_OPTS += -rom_extract Yes
# Style used for implementing ROM.
# Values: Auto | Distributed | Block
XST_OPTS += -rom_style Auto
# Enable or disable automatic BRAM packing.
# Values: YES | NO
XST_OPTS += -auto_bram_packing NO
## MUX/Decoder/Shift Register ##
# Extract multiplexers where possible.
# Values: Yes | No | Force
XST_OPTS += -mux_extract Yes
# Style used for implementing MUX logic.
# Values: Auto | MUXCY | MUXF
XST_OPTS += -mux_style Auto
# Extract decoder logic from behavioral code.
# Values: YES | NO
XST_OPTS += -decoder_extract YES
# Extract and optimize priority encoder structures.
# Values: Yes | No | Force
XST_OPTS += -priority_extract Yes
# Extract shift register logic.
# Values: YES | NO
XST_OPTS += -shreg_extract YES
# Extract simple shift operations into dedicated hardware.
# Values: YES | NO
XST_OPTS += -shift_extract YES
## Multiplier ##
# Style for implementing multipliers.
# Values: Auto | LUT | Pipe_LUT | Pipe_Block | Block
XST_OPTS += -mult_style Auto
## Misc ##
# Collapse XOR trees where beneficial.
# Values: YES | NO
XST_OPTS += -xor_collapse YES
# Share resources like adders or multipliers between logic blocks.
# Values: YES | NO | Force
XST_OPTS += -resource_sharing YES
# Convert asynchronous resets to synchronous where possible.
# Values: YES | NO
XST_OPTS += -async_to_sync NO
#### Xilinx Specific Options ####
## Optimization ##
# Enable removal of logically equivalent registers.
# Values: YES | NO
XST_OPTS += -equivalent_register_removal YES
# Duplicate registers to reduce fanout or improve timing.
# Values: YES | NO
XST_OPTS += -register_duplication YES
# Move registers across logic to balance timing.
# Values: Yes | No
XST_OPTS += -register_balancing No
# Use clock enable signals where possible.
# Values: Auto | Yes | No
XST_OPTS += -use_clock_enable Yes
# Use synchronous set (preset) signals when available.
# Values: Auto | Yes | No
XST_OPTS += -use_sync_set Yes
# Use synchronous reset signals where possible.
# Values: Auto | Yes | No
XST_OPTS += -use_sync_reset Yes
## I/O ##
# Insert IO buffers for top-level ports.
# Values: YES | NO
XST_OPTS += -iobuf YES
# Placement strategy for IOB registers (Auto = let tools decide).
# Values: Auto | YES | NO
XST_OPTS += -iob Auto
## Misc ##
# Maximum allowed fanout for a net.
# Values: integer (e.g., 500)
XST_OPTS += -max_fanout 500
# Maximum number of BUFGs (global buffers) to use.
# Values: 0–32 (device-dependent)
XST_OPTS += -bufg 24
# Enable logic packing into slices.
# Values: YES | NO
XST_OPTS += -slice_packing YES
# Try to reduce the number of primitive instances used.
# Values: YES | NO
XST_OPTS += -optimize_primitives NO
# Margin in percent beyond the target slice utilization.
# Values: 0–100
XST_OPTS += -slice_utilization_ratio_maxmargin 5
# Options for the NGDBuild tool
# NGDBUILD_OPTS =
# Options for the MAP tool
# @example -mt 2 (multi-threading with 2 threads)
MAP_OPTS = -cm speed -ol high -detail -timing
# Options for the PAR tool
# @example -mt 2 (multi-threading with 2 threads)
PAR_OPTS = -ol high
# Options for the BitGen tool
# @example -g Compress (compress bitstream)
# @example -g StartupClk:Cclk (specify the startup clock to onboard clock)
# @example -g StartupClk:JtagClk (specify the startup clock to JTAG clock)
# BITGEN_OPTS =
# Options for the Trace tool
# TRACE_OPTS =
# Options for the Fuse tool
# FUSE_OPTS =
# ISIM_CMD =
## ## ## ## ## ## ## ##
# ---------------------
## Programmer settings.. ##
# The programmer to use
# @example impact | digilent | xc3sprog
# @remark impact is the default Xilinx programmer and you must create a impact.cmd file in the root directory..
PROGRAMMER =
## Digilent JTAG cable settings
# @remark Use the `djtgcfg enum` command to list all available devices
# DJTG_DEVICE = DOnbUsb
# The index of the JTAG device for the `prog` target
# DJTG_INDEX = 0
# The index of the flash device for the `flash` target
# DJTG_FLASH_INDEX = 1
## ## ## ## ## ## ## ##
# ---------------------

268
project.yml Normal file
View File

@@ -0,0 +1,268 @@
name: Pipeline-AXI-Handshake
topmodule: Pipeline_pb
target_device: xc3s1200e-4-fg320
xilinx_path: /opt/Xilinx/14.7/ISE_DS/ISE
sources:
vhdl:
- path: src/*.vhd
library: work
constraints: src/Pipeline_pb.ucf
testbenches:
vhdl:
- path: tests/*.vhd
library: work
dependencies:
# - git: "https://git.0xmax42.io/maxp/Asynchronous-FIFO-AXI-Handshake.git"
# rev: "hdlbuild"
build:
build_dir: working
report_dir: reports
copy_target_dir: output
# Tool Optionen
tool_options:
common:
- "-intstyle"
- "xflow"
ngdbuild: []
map:
- "-detail"
- "-timing"
- "-ol"
- "high"
par: []
bitgen:
- "-g"
- "StartupClk:JtagClk"
trace:
- "-v"
- "3"
- "-n"
- "3"
fuse:
- "-incremental"
isim:
- "-gui"
xst:
# Optimization goal: prioritize speed or area.
# Values: Speed | Area
- "-opt_mode Speed"
# Optimization level: more aggressive optimizations at level 2.
# Values: 1 | 2
- "-opt_level 2"
# Use the new XST parser (recommended for modern designs).
# Values: yes | no
- "-use_new_parser yes"
# Preserve design hierarchy or allow flattening for optimization.
# Values: Yes | No | Soft
- "-keep_hierarchy No"
# Determines how hierarchy is preserved in the netlist.
# Values: As_Optimized | Rebuilt
- "-netlist_hierarchy As_Optimized"
# Global optimization strategy for nets.
# Values: AllClockNets | Offset_In_Before | Offset_Out_After | Inpad_To_Outpad | Max_Delay
- "-glob_opt AllClockNets"
## Misc ##
# Enable reading of IP cores.
# Values: YES | NO
- "-read_cores YES"
# Do not write timing constraints into synthesis report.
# Values: YES | NO
- "-write_timing_constraints NO"
# Analyze paths across different clock domains.
# Values: YES | NO
- "-cross_clock_analysis NO"
# Character used to separate hierarchy levels in instance names.
# Default: /
- "-hierarchy_separator /"
# Delimiters used for bus signals.
# Values: <> | [] | () | {}
- "-bus_delimiter <>"
# Maintain original case of identifiers.
# Values: Maintain | Upper | Lower
- "-case Maintain"
# Target maximum utilization ratio for slices.
# Values: 1–100
- "-slice_utilization_ratio 100"
# Target maximum utilization ratio for BRAMs.
# Values: 1–100
- "-bram_utilization_ratio 100"
# Use Verilog 2001 syntax features.
# Values: YES | NO
- "-verilog2001 YES"
#### HDL Options ####
## FSM ##
# Extract FSMs (Finite State Machines) from HDL code.
# Values: YES | NO
- "-fsm_extract YES"
# Encoding strategy for FSMs.
# Values: Auto | Gray | One-Hot | Johnson | Compact | Sequential | Speed1 | User
- "-fsm_encoding Auto"
# Add safe logic for undefined FSM states.
# Values: Yes | No
- "-safe_implementation No"
# Structure used to implement FSMs.
# Values: LUT | BRAM
- "-fsm_style LUT"
## RAM/ROM ##
# Extract RAM inference from HDL.
# Values: Yes | No
- "-ram_extract Yes"
# Style used to implement RAM.
# Values: Auto | Block | Distributed
- "-ram_style Auto"
# Extract ROM inference from HDL.
# Values: Yes | No
- "-rom_extract Yes"
# Style used for implementing ROM.
# Values: Auto | Distributed | Block
- "-rom_style Auto"
# Enable or disable automatic BRAM packing.
# Values: YES | NO
- "-auto_bram_packing NO"
## MUX/Decoder/Shift Register ##
# Extract multiplexers where possible.
# Values: Yes | No | Force
- "-mux_extract Yes"
# Style used for implementing MUX logic.
# Values: Auto | MUXCY | MUXF
- "-mux_style Auto"
# Extract decoder logic from behavioral code.
# Values: YES | NO
- "-decoder_extract YES"
# Extract and optimize priority encoder structures.
# Values: Yes | No | Force
- "-priority_extract Yes"
# Extract shift register logic.
# Values: YES | NO
- "-shreg_extract YES"
# Extract simple shift operations into dedicated hardware.
# Values: YES | NO
- "-shift_extract YES"
## Multiplier ##
# Style for implementing multipliers.
# Values: Auto | LUT | Pipe_LUT | Pipe_Block | Block
- "-mult_style Auto"
## Misc ##
# Collapse XOR trees where beneficial.
# Values: YES | NO
- "-xor_collapse YES"
# Share resources like adders or multipliers between logic blocks.
# Values: YES | NO | Force
- "-resource_sharing YES"
# Convert asynchronous resets to synchronous where possible.
# Values: YES | NO
- "-async_to_sync NO"
#### Xilinx Specific Options ####
## Optimization ##
# Enable removal of logically equivalent registers.
# Values: YES | NO
- "-equivalent_register_removal YES"
# Duplicate registers to reduce fanout or improve timing.
# Values: YES | NO
- "-register_duplication YES"
# Move registers across logic to balance timing.
# Values: Yes | No | Forward | Backward
- "-register_balancing No"
# Use clock enable signals where possible.
# Values: Auto | Yes | No
- "-use_clock_enable Yes"
# Use synchronous set (preset) signals when available.
# Values: Auto | Yes | No
- "-use_sync_set Yes"
# Use synchronous reset signals where possible.
# Values: Auto | Yes | No
- "-use_sync_reset Yes"
## I/O ##
# Insert IO buffers for top-level ports.
# Values: YES | NO
- "-iobuf YES"
# Placement strategy for IOB registers (Auto = let tools decide).
# Values: Auto | YES | NO
- "-iob Auto"
## Misc ##
# Maximum allowed fanout for a net.
# Values: integer (e.g., 500)
- "-max_fanout 50"
# Maximum number of BUFGs (global buffers) to use.
# Values: 0–32 (device-dependent)
- "-bufg 24"
# Enable logic packing into slices.
# Values: YES | NO
- "-slice_packing YES"
# Try to reduce the number of primitive instances used.
# Values: YES | NO
- "-optimize_primitives NO"
# Margin in percent beyond the target slice utilization.
# Values: 0–100
- "-slice_utilization_ratio_maxmargin 5"

52
src/PipelineBuffer.vhd Normal file
View File

@@ -0,0 +1,52 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity PipelineBuffer is
generic (
--@ Data width
G_Width : integer := 32
);
port (
--@ Clock signal; (**Rising edge** triggered)
I_CLK : in std_logic := '0';
--@ Enable input from **Pipeline Buffer Controller**
--@ [1]: If low, data is passed through, else data is registered
--@ [0]: Enable for register
I_Enable : in std_logic_vector(1 downto 0) := (others => '0');
--@ Data input
I_Data : in std_logic_vector(G_Width - 1 downto 0) := (others => '0');
--@ Data output
O_Data : out std_logic_vector(G_Width - 1 downto 0) := (others => '0')
);
end entity PipelineBuffer;
architecture RTL of PipelineBuffer is
signal C_MUX : std_logic := '0';
signal C_Enable : std_logic := '0';
signal R_Data : std_logic_vector(G_Width - 1 downto 0) := (others => '0');
begin
C_MUX <= I_Enable(1);
C_Enable <= I_Enable(0);
P_MUX : process (C_MUX, I_Data, R_Data)
begin
if C_MUX = '0' then -- Passthrough mode
O_Data <= I_Data;
else -- Register mode
O_Data <= R_Data;
end if;
end process;
P_Register : process (I_CLK)
begin
if rising_edge(I_CLK) then
if C_Enable = '1' then
R_Data <= I_Data;
end if;
end if;
end process;
end architecture;

View File

@@ -0,0 +1,74 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity PipelineBufferController is
generic (
--@ Reset active at this level
G_ResetActiveAt : std_logic := '1'
);
port (
--@ Clock signal; (**Rising edge** triggered)
I_CLK : in std_logic := '0';
--@ Reset; (**Synchronous**, **Active at `G_ResetActiveAt`**)
I_RST : in std_logic := '0';
--@ Chip enable; (**Synchronous**, **Active high**)
I_CE : in std_logic := '1';
--@ [1]: If low, data is passed through, else data is registered
--@ [0]: Enable for register
O_Enable : out std_logic_vector(1 downto 0) := (others => '0');
--@ @virtualbus AXI-Flags-In @dir In Input interface for AXI-like handshake
--@ AXI like valid; (**Synchronous**, **Active high**)
I_Valid : in std_logic := '0';
--@ AXI like ready; (**Synchronous**, **Active high**)
O_Ready : out std_logic := '0';
--@ @end
--@ @virtualbus AXI-Flags-Out @dir Out Output interface for AXI-like handshake
--@ AXI like valid; (**Synchronous**, **Active high**)
O_Valid : out std_logic := '0';
--@ AXI like ready; (**Synchronous**, **Active high**)
I_Ready : in std_logic := '0'
--@ @end
);
end entity PipelineBufferController;
architecture RTL of PipelineBufferController is
signal C_MUX : std_logic := '0';
signal C_Enable : std_logic := '0';
signal R_IsBuffered : std_logic := '0';
begin
--@ Set mux to buffered mode if data is available in the buffer.
C_MUX <= R_IsBuffered;
--@ Enable the buffer register if not buffered and chip enable is high.
C_Enable <= I_CE and not R_IsBuffered;
--@ Set the valid signal to high if data is available in the buffer or if data is valid.
O_Valid <= R_IsBuffered or I_Valid;
process (I_CLK)
begin
if rising_edge(I_CLK) then
if I_RST = G_ResetActiveAt then
R_IsBuffered <= '0';
O_Ready <= '1';
elsif I_CE = '1' then
if R_IsBuffered = '0' and I_Valid = '1' then
R_IsBuffered <= '1';
O_Ready <= '0';
elsif I_Ready = '1' and (R_IsBuffered or I_Valid) = '1' then
R_IsBuffered <= '0';
O_Ready <= '1';
end if;
end if;
end if;
end process;
O_Enable(1) <= C_MUX;
O_Enable(0) <= C_Enable;
end architecture;

197
src/PipelineSwitch.vhd Normal file
View File

@@ -0,0 +1,197 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity PipelineSwitch is
generic (
--@ Width of the comparison input and mask.
--@ This defines the bit width of `I_Match` and `G_Mask`.
G_MaskWidth : integer := 4;
--@ Comparison mask or reference value used to control routing.
--@ Its width must match `G_MaskWidth`.
G_Mask : std_logic_vector := "1010";
--@ Comparison mode that determines to which output the data is routed.
--@ Available modes:
--@ - `"none"`: Always route to `Default`.
--@ - `"or"`: Route to `Selected` if **any** bit in `I_Match` matches a set bit in `G_Mask`.
--@ - `"and"`: Route to `Selected` if **all** bits set in `G_Mask` are also set in `I_Match`.
--@ - `"xor"`: Route to `Selected` if **any** bit differs between `I_Match` and `G_Mask`.
--@ - `"equal"`: Route to `Selected` if `I_Match` is **bitwise equal** to `G_Mask`.
--@ - `"not_equal"`: Route to `Selected` if `I_Match` is **not equal** to `G_Mask`.
--@ - `"gt"`: Route to `Selected` if `I_Match` **>** `G_Mask` (unsigned).
--@ - `"ge"`: Route to `Selected` if `I_Match` **≥** `G_Mask`.
--@ - `"lt"`: Route to `Selected` if `I_Match` **<** `G_Mask`.
--@ - `"le"`: Route to `Selected` if `I_Match` **≤** `G_Mask`.
G_MaskMode : string := "equal"
);
port (
--@ Input value to be compared against `G_Mask` to determine routing.
I_Match : in std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
--@ @virtualbus AXI-Flags-In @dir In Input interface for AXI-like handshake
--@ AXI-like valid; (**Synchronous**, **Active high**)
I_Valid : in std_logic := '0';
--@ AXI-like ready; (**Synchronous**, **Active high**)
O_Ready : out std_logic := '0';
--@ @end
--@ If `1`, route to `Selected` output; if `0`, route to `Default` output.
O_MUX_Select : out std_logic := '0';
--@ @virtualbus AXI-Flags-Out @dir Out Output interface for unmatched routing
--@ Activated when the comparison **fails**.
--@ AXI-like valid; (**Synchronous**, **Active high**)
O_Default_Valid : out std_logic := '0';
--@ AXI-like ready; (**Synchronous**, **Active high**)
I_Default_Ready : in std_logic := '0';
--@ @end
--@ @virtualbus AXI-Flags-Out @dir Out Output interface for matched routing
--@ Activated when the comparison **succeeds**.
--@ AXI-like valid; (**Synchronous**, **Active high**)
O_Selected_Valid : out std_logic := '0';
--@ AXI-like ready; (**Synchronous**, **Active high**)
I_Selected_Ready : in std_logic := '0'
--@ @end
);
end entity PipelineSwitch;
architecture RTL of PipelineSwitch is
function strings_equal(A, B : string) return boolean is
begin
if A'length /= B'length then
return false;
end if;
for i in A'range loop
if A(i) /= B(i) then
return false;
end if;
end loop;
return true;
end function;
constant K_Mode_None : string := "none";
constant K_Mode_OR : string := "or";
constant K_Mode_XOR : string := "xor";
constant K_Mode_AND : string := "and";
constant K_Mode_Equal : string := "equal";
constant K_Mode_NotEqual : string := "not_equal";
constant K_Mode_GT : string := "gt";
constant K_Mode_GE : string := "ge";
constant K_Mode_LT : string := "lt";
constant K_Mode_LE : string := "le";
signal C_ShouldRouteToSelected : std_logic := '0';
begin
assert G_Mask'length = G_MaskWidth
report "G_Mask length does not match G_MaskWidth" severity failure;
process (I_Match)
begin
if strings_equal(G_MaskMode, K_Mode_None) then
--@ No condition: Always route to Default
C_ShouldRouteToSelected <= '0';
elsif strings_equal(G_MaskMode, K_Mode_OR) then
--@ Route to Selected if any bit in I_Match is also set in G_Mask
if (I_Match and G_Mask) /= (G_MaskWidth - 1 downto 0 => '0') then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
elsif strings_equal(G_MaskMode, K_Mode_XOR) then
--@ Route to Selected if any bit differs between I_Match and G_Mask
if (I_Match xor G_Mask) /= (G_MaskWidth - 1 downto 0 => '0') then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
elsif strings_equal(G_MaskMode, K_Mode_AND) then
--@ Route to Selected if all bits set in G_Mask are also set in I_Match
if (I_Match and G_Mask) = G_Mask then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
elsif strings_equal(G_MaskMode, K_Mode_Equal) then
--@ Route to Selected if I_Match is exactly equal to G_Mask
if I_Match = G_Mask then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
elsif strings_equal(G_MaskMode, K_Mode_NotEqual) then
--@ Route to Selected if I_Match is not equal to G_Mask
if I_Match /= G_Mask then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
elsif strings_equal(G_MaskMode, K_Mode_GT) then
--@ Route to Selected if I_Match > G_Mask (interpreted as unsigned)
if unsigned(I_Match) > unsigned(G_Mask) then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
elsif strings_equal(G_MaskMode, K_Mode_GE) then
--@ Route to Selected if I_Match >= G_Mask (unsigned)
if unsigned(I_Match) >= unsigned(G_Mask) then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
elsif strings_equal(G_MaskMode, K_Mode_LT) then
--@ Route to Selected if I_Match < G_Mask (unsigned)
if unsigned(I_Match) < unsigned(G_Mask) then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
elsif strings_equal(G_MaskMode, K_Mode_LE) then
--@ Route to Selected if I_Match <= G_Mask (unsigned)
if unsigned(I_Match) <= unsigned(G_Mask) then
C_ShouldRouteToSelected <= '1';
else
C_ShouldRouteToSelected <= '0';
end if;
else
--@ Unknown comparison mode: fallback to Default
C_ShouldRouteToSelected <= '0';
end if;
end process;
process (I_Valid, I_Default_Ready, I_Selected_Ready, C_ShouldRouteToSelected)
begin
if C_ShouldRouteToSelected = '1' then
-- Route to Selected
O_Selected_Valid <= I_Valid;
O_Default_Valid <= '0';
O_Ready <= I_Selected_Ready;
else
-- Route to Default
O_Selected_Valid <= '0';
O_Default_Valid <= I_Valid;
O_Ready <= I_Default_Ready;
end if;
end process;
O_MUX_Select <= C_ShouldRouteToSelected;
end architecture;

View File

@@ -1,4 +1,4 @@
#NET I_CLK LOC = AG18;
NET I_CLK LOC = B8;
NET I_CLK TNM_NET = CLOCK;
TIMESPEC TS_CLOCK = PERIOD CLOCK 250 MHz HIGH 50 %;
TIMESPEC TS_CLOCK = PERIOD CLOCK 280 MHz HIGH 50 %;

View File

@@ -11,24 +11,36 @@ use ieee.math_real.all;
entity Pipeline_pb is
generic (
--@ Number of pipeline stages
G_PipelineStages : integer := 10;
--@ Number of pipeline stages inside each module
G_PipelineStages : integer := 2;
--@ Data width
G_Width : integer := 32;
G_Width : integer := 8;
--@ Register balancing attribute<br>
--@ - "no" : No register balancing <br>
--@ - "yes": Register balancing in both directions <br>
--@ - "forward": Moves a set of FFs at the inputs of a LUT to a single FF at its output. <br>
--@ - "backward": Moves a single FF at the output of a LUT to a set of FFs at its inputs.
G_RegisterBalancing : string := "yes"
G_RegisterBalancing : string := "yes";
--@ Enable pipeline buffer
--@ - true : Use pipeline buffer
--@ - false : Direct connection (bypass)
G_EnablePipelineBuffer : boolean := true;
--@ How many Pipeline modules shall be chained?
G_PipelineModules : integer := 20;
--@ Enable chip enable signal
G_Enable_CE : boolean := false;
--@ Enable reset signal
G_Enable_RST : boolean := false
);
port (
I_CLK : in std_logic;
I_RST : in std_logic;
I_CE : in std_logic;
---
I_Data : in std_logic_vector(G_Width - 1 downto 0);
I_Valid : in std_logic;
O_Ready : out std_logic;
---
O_Data : out std_logic_vector(G_Width - 1 downto 0);
O_Valid : out std_logic;
I_Ready : in std_logic
@@ -36,119 +48,116 @@ entity Pipeline_pb is
end entity Pipeline_pb;
architecture RTL of Pipeline_pb is
-- Keep attribute: Prevents the synthesis tool from removing the entity if is "true".
---------------------------------------------------------------------------
-- Attribute helpers
---------------------------------------------------------------------------
attribute keep : string;
-- IOB attribute: Attaches the FF to the IOB if is "true".
attribute IOB : string;
-- General Interace
signal R_RST : std_logic;
signal R_CE : std_logic;
-- Attribute
---------------------------------------------------------------------------
-- Bench‐wrapper FFs (synchronous IO)
---------------------------------------------------------------------------
signal R_RST : std_logic := '0';
signal R_CE : std_logic := '1';
attribute keep of R_RST, R_CE : signal is "true";
attribute IOB of R_RST, R_CE : signal is "false";
-- Input Interface
signal R_DataIn : std_logic_vector(G_Width-1 downto 0);
signal R_ValidIn : std_logic;
signal R_ReadyOut : std_logic;
-- Attribute
attribute keep of R_DataIn, R_ValidIn, R_ReadyOut : signal is "true";
attribute IOB of R_DataIn, R_ValidIn, R_ReadyOut : signal is "false";
attribute keep of R_DataIn, R_ValidIn : signal is "true";
attribute IOB of R_DataIn, R_ValidIn : signal is "false";
-- Output Interface
signal R_DataOut : std_logic_vector(G_Width-1 downto 0);
signal R_ValidOut : std_logic;
signal R_ReadyIn : std_logic;
-- Attribute
attribute keep of R_DataOut, R_ValidOut, R_ReadyIn : signal is "true";
attribute IOB of R_DataOut, R_ValidOut, R_ReadyIn : signal is "false";
signal C_Pipeline0Enable : std_logic;
signal C_Pipeline1Enable : std_logic;
---------------------------------------------------------------------------
-- Chaining arrays (sentinel element @0 and @G_PipelineModules)
---------------------------------------------------------------------------
type T_DataArray is array(0 to G_PipelineModules) of std_logic_vector(G_Width-1 downto 0);
signal S_Data : T_DataArray;
signal S_Valid : std_logic_vector(0 to G_PipelineModules);
signal S_Ready : std_logic_vector(0 to G_PipelineModules);
signal R_Valid : std_logic;
signal R_Ready : std_logic;
signal R_Data : std_logic_vector(G_Width - 1 downto 0);
begin
BenchmarkEnvironmentFFs : process (I_CLK)
GEN_Enable_CE : if G_Enable_CE = true generate
process(I_CLK)
begin
if rising_edge(I_CLK) then
-- General Interace
R_RST <= I_RST;
R_CE <= I_CE;
end if;
end process;
end generate GEN_Enable_CE;
-- Input Interface
GEN_Enable_RST : if G_Enable_RST = true generate
process(I_CLK)
begin
if rising_edge(I_CLK) then
R_RST <= I_RST;
end if;
end process;
end generate GEN_Enable_RST;
-----------------------------------------------------------------------
-- Wrapper FFs: register all top‑level ports once for fair timing
-----------------------------------------------------------------------
BenchFF : process(I_CLK)
begin
if rising_edge(I_CLK) then
--- Register inputs
R_DataIn <= I_Data;
R_ValidIn <= I_Valid;
O_Ready <= R_ReadyOut;
-- Output Interface
O_Data <= R_DataOut;
O_Valid <= R_ValidOut;
O_Ready <= S_Ready(0);
--- Register outputs
R_DataOut <= S_Data (G_PipelineModules);
R_ValidOut <= S_Valid(G_PipelineModules);
R_ReadyIn <= I_Ready;
end if;
end process;
PipelineControllerIn : entity work.PipelineController
O_Data <= R_DataOut;
O_Valid <= R_ValidOut;
-----------------------------------------------------------------------
-- Bind sentinel 0 with registered inputs
-----------------------------------------------------------------------
S_Data (0) <= R_DataIn;
S_Valid(0) <= R_ValidIn;
-----------------------------------------------------------------------
-- Bind last sentinel with registered outputs
-----------------------------------------------------------------------
S_Ready(G_PipelineModules) <= R_ReadyIn;
-----------------------------------------------------------------------
-- Generate N pipeline modules in series
-----------------------------------------------------------------------
gen_modules : for i in 0 to G_PipelineModules-1 generate
P_MOD : entity work.Pipeline_pb_Module
generic map(
G_PipelineStages => G_PipelineStages,
G_ResetActiveAt => '1'
G_Width => G_Width,
G_RegisterBalancing => G_RegisterBalancing,
G_EnablePipelineBuffer => G_EnablePipelineBuffer
)
port map(
I_CLK => I_CLK,
I_RST => R_RST,
I_CE => R_CE,
O_Enable => C_Pipeline0Enable,
I_Valid => R_ValidIn,
O_Ready => R_ReadyOut,
O_Valid => R_Valid,
I_Ready => R_Ready
-- Up‑stream side
I_Data => S_Data (i),
I_Valid => S_Valid(i),
O_Ready => S_Ready(i),
-- Down‑stream side
O_Data => S_Data (i+1),
O_Valid => S_Valid(i+1),
I_Ready => S_Ready(i+1)
);
PipelineRegisterIn : entity work.PipelineRegister
generic map(
G_PipelineStages => G_PipelineStages,
G_Width => G_Width,
G_RegisterBalancing => G_RegisterBalancing
)
port map(
I_CLK => I_CLK,
I_Enable => C_Pipeline0Enable,
I_Data => R_DataIn,
O_Data => R_Data
);
---------
PipelineControllerOut : entity work.PipelineController
generic map(
G_PipelineStages => G_PipelineStages,
G_ResetActiveAt => '1'
)
port map(
I_CLK => I_CLK,
I_RST => R_RST,
I_CE => R_CE,
O_Enable => C_Pipeline1Enable,
I_Valid => R_Valid,
O_Ready => R_Ready,
O_Valid => R_ValidOut,
I_Ready => R_ReadyIn
);
PipelineRegisterOut : entity work.PipelineRegister
generic map(
G_PipelineStages => G_PipelineStages,
G_Width => G_Width,
G_RegisterBalancing => G_RegisterBalancing
)
port map(
I_CLK => I_CLK,
I_Enable => C_Pipeline1Enable,
I_Data => R_Data,
O_Data => R_DataOut
);
end generate gen_modules;
end architecture RTL;

124
src/Pipeline_pb_Module.vhd Normal file
View File

@@ -0,0 +1,124 @@
--@ Performance Benchmarking Environment
--@ This file is a wrapper for the module which is to be tested
--@ and capsulates the module with flip-flops to create a synchronous
--@ interface for the module. This is necessary to test the synthesis
--@ results of the module.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity Pipeline_pb_Module is
generic (
--@ Number of pipeline stages
G_PipelineStages : integer := 10;
--@ Data width
G_Width : integer := 32;
--@ Register balancing attribute<br>
--@ - "no" : No register balancing <br>
--@ - "yes": Register balancing in both directions <br>
--@ - "forward": Moves a set of FFs at the inputs of a LUT to a single FF at its output. <br>
--@ - "backward": Moves a single FF at the output of a LUT to a set of FFs at its inputs.
G_RegisterBalancing : string := "no";
--@ Enable pipeline buffer
--@ - true : Use pipeline buffer
--@ - false : Direct connection (bypass)
G_EnablePipelineBuffer : boolean := false
);
port (
I_CLK : in std_logic;
I_RST : in std_logic;
I_CE : in std_logic;
---
I_Data : in std_logic_vector(G_Width - 1 downto 0);
I_Valid : in std_logic;
O_Ready : out std_logic;
---
O_Data : out std_logic_vector(G_Width - 1 downto 0);
O_Valid : out std_logic;
I_Ready : in std_logic
);
end entity Pipeline_pb_Module;
architecture RTL of Pipeline_pb_Module is
signal C_PipelineEnable : std_logic;
signal C_PipelineBufferEnable : std_logic_vector(1 downto 0) := (others => '0');
signal R_Valid : std_logic;
signal R_Ready : std_logic;
signal R_Data : std_logic_vector(G_Width - 1 downto 0);
signal C_Data : std_logic_vector(G_Width - 1 downto 0);
begin
INST_PipelineControllerIn : entity work.PipelineController
generic map(
G_PipelineStages => G_PipelineStages,
G_ResetActiveAt => '1'
)
port map(
I_CLK => I_CLK,
I_RST => I_RST,
I_CE => I_CE,
O_Enable => C_PipelineEnable,
I_Valid => I_Valid,
O_Ready => O_Ready,
O_Valid => R_Valid,
I_Ready => R_Ready
);
INST_PipelineRegisterIn : entity work.PipelineRegister
generic map(
G_PipelineStages => G_PipelineStages,
G_Width => G_Width,
G_RegisterBalancing => G_RegisterBalancing
)
port map(
I_CLK => I_CLK,
I_Enable => C_PipelineEnable,
I_Data => I_Data,
O_Data => R_Data
);
---------
C_Data <= std_logic_vector(unsigned(R_Data) + 3); -- Example operation, can be replaced with actual logic
---------
-- Pipeline Buffer Generation based on G_EnablePipelineBuffer
GEN_PipelineBuffer : if G_EnablePipelineBuffer generate
INST_PipelineBufferController : entity work.PipelineBufferController
generic map(
G_ResetActiveAt => '1'
)
port map(
I_CLK => I_CLK,
I_RST => I_RST,
I_CE => I_CE,
O_Enable => C_PipelineBufferEnable,
I_Valid => R_Valid,
O_Ready => R_Ready,
O_Valid => O_Valid,
I_Ready => I_Ready
);
INST_PipelineBuffer : entity work.PipelineBuffer
generic map(
G_Width => G_Width
)
port map(
I_CLK => I_CLK,
I_Enable => C_PipelineBufferEnable,
I_Data => C_Data,
O_Data => O_Data
);
end generate GEN_PipelineBuffer;
-- Direct connection when pipeline buffer is disabled
GEN_PassthroughWithoutBuffer : if not G_EnablePipelineBuffer generate
O_Valid <= R_Valid;
O_Data <= R_Data;
R_Ready <= I_Ready;
end generate GEN_PassthroughWithoutBuffer;
end architecture RTL;

169
tests/PipelineBuffer_tb.vhd Normal file
View File

@@ -0,0 +1,169 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use std.env.stop;
entity PipelineBuffer_tb is
end entity PipelineBuffer_tb;
architecture RTL of PipelineBuffer_tb is
-- Clock signal period
constant K_Period : time := 20 ns;
-- Zufallsverzögerungen
constant K_WriteDelay : natural := 40;
constant K_ReadDelay : natural := 60;
-- Konstanten
constant G_ResetActiveAt : std_logic := '1';
constant G_Width : integer := 32;
-- Zufalls-Seed
shared variable seed1 : integer := 42;
shared variable seed2 : integer := 1337;
-- Randomfunktion
impure function rand_int(min_val, max_val : integer) return integer is
variable r : real;
begin
uniform(seed1, seed2, r);
return integer(round(r * real(max_val - min_val + 1) + real(min_val) - 0.5));
end function;
-- Signale
signal I_CLK : std_logic := '0';
signal I_RST : std_logic := '1';
signal I_CE : std_logic := '1';
signal O_Enable : std_logic_vector(1 downto 0) := (others => '0');
signal I_Valid : std_logic := '0';
signal O_Ready : std_logic := '0';
signal O_Valid : std_logic := '0';
signal I_Ready : std_logic := '0';
signal I_Data : std_logic_vector(G_Width - 1 downto 0) := (others => 'U');
signal O_Data : std_logic_vector(G_Width - 1 downto 0) := (others => 'U');
begin
-- Clock
Clocking : process
begin
while true loop
I_CLK <= '0';
wait for (K_Period / 2);
I_CLK <= '1';
wait for (K_Period / 2);
end loop;
end process;
-- Reset
I_RST <= G_ResetActiveAt, not G_ResetActiveAt after 100 ns;
-- DUT: Controller
i_PipelineBufferController : entity work.PipelineBufferController
generic map(
G_ResetActiveAt => G_ResetActiveAt
)
port map(
I_CLK => I_CLK,
I_RST => I_RST,
I_CE => I_CE,
O_Enable => O_Enable,
I_Valid => I_Valid,
O_Ready => O_Ready,
O_Valid => O_Valid,
I_Ready => I_Ready
);
-- DUT: Register
i_PipelineBuffer : entity work.PipelineBuffer
generic map(
G_Width => G_Width
)
port map(
I_CLK => I_CLK,
I_Enable => O_Enable,
I_Data => I_Data,
O_Data => O_Data
);
-- Write Stimulus
Stim_Write : process
variable delay : integer := 0;
variable i : integer := 1;
variable pending : boolean := false;
begin
I_Valid <= '0';
I_Data <= (others => 'U');
wait until I_RST = '0';
while true loop
wait until rising_edge(I_CLK);
-- Neues Paket vorbereiten
if not pending and delay = 0 then
I_Data <= std_logic_vector(to_unsigned(i, G_Width));
I_Valid <= '1';
pending := true;
report "Sende Paket #" & integer'image(i) severity note;
end if;
-- Handshake erfolgt
if O_Ready = '1' and I_Valid = '1' then
I_Valid <= '0';
i := i + 1;
delay := rand_int(1, K_WriteDelay);
pending := false;
end if;
-- Verzögerung herunterzählen
if delay > 0 and not pending then
delay := delay - 1;
end if;
end loop;
end process;
-- Read Stimulus (robust)
Stim_Read : process
variable delay : integer := 0;
variable expected : integer := 1;
variable received : integer;
variable consume_now : boolean := false;
begin
I_Ready <= '0';
wait until I_RST = '0';
while true loop
wait until rising_edge(I_CLK);
-- Wenn O_Valid vorhanden und kein Delay mehr: jetzt lesen
if O_Valid = '1' and delay = 0 and not consume_now then
I_Ready <= '1';
consume_now := true; -- Warte auf nächste Gültigkeit
end if;
-- Sobald Handshake erfolgt (O_Valid & I_Ready), auswerten
if O_Valid = '1' and I_Ready = '1' and consume_now then
received := to_integer(unsigned(O_Data));
if received = expected then
report "Empfange Paket #" & integer'image(expected) severity note;
else
report "FEHLER bei Paket #" & integer'image(expected) &
": erwartet " & integer'image(expected) &
", empfangen " & integer'image(received) severity error;
end if;
expected := expected + 1;
delay := rand_int(1, K_ReadDelay);
consume_now := false;
I_Ready <= '0';
end if;
-- Wartezeit herunterzählen
if delay > 0 and not consume_now then
delay := delay - 1;
end if;
end loop;
end process;
end architecture RTL;

View File

@@ -0,0 +1,237 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="./isim.wdb" id="1" type="auto">
<top_modules>
<top_module name="env" />
<top_module name="glbl" />
<top_module name="math_real" />
<top_module name="numeric_std" />
<top_module name="pipelinebuffer_tb" />
<top_module name="std_logic_1164" />
</top_modules>
</db_ref>
</db_ref_list>
<WVObjectSize size="12" />
<wvobject fp_name="/pipelinebuffer_tb/i_clk" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_clk</obj_property>
<obj_property name="ObjectShortName">i_clk</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_rst" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_rst</obj_property>
<obj_property name="ObjectShortName">i_rst</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_ce" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_ce</obj_property>
<obj_property name="ObjectShortName">i_ce</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_enable" type="array" db_ref_id="1">
<obj_property name="ElementShortName">o_enable[1:0]</obj_property>
<obj_property name="ObjectShortName">o_enable[1:0]</obj_property>
<wvobject fp_name="/pipelinebuffer_tb/o_enable[1]" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[1]</obj_property>
<obj_property name="ObjectShortName">o_enable[1]</obj_property>
<obj_property name="label">MUX</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_enable[0]" type="logic" db_ref_id="1">
<obj_property name="DisplayName">label</obj_property>
<obj_property name="ElementShortName">[0]</obj_property>
<obj_property name="ObjectShortName">o_enable[0]</obj_property>
<obj_property name="label">Enable</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_valid" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_valid</obj_property>
<obj_property name="ObjectShortName">i_valid</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_ready</obj_property>
<obj_property name="ObjectShortName">o_ready</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_data" type="array" db_ref_id="1">
<obj_property name="ElementShortName">i_data[31:0]</obj_property>
<obj_property name="ObjectShortName">i_data[31:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject fp_name="divider12" type="divider">
<obj_property name="label">Out</obj_property>
<obj_property name="DisplayName">label</obj_property>
<obj_property name="BkColor">128 128 255</obj_property>
<obj_property name="TextColor">230 230 230</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_valid" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">o_valid</obj_property>
<obj_property name="ObjectShortName">o_valid</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_ready" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">i_ready</obj_property>
<obj_property name="ObjectShortName">i_ready</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data" type="array" db_ref_id="1">
<obj_property name="ElementShortName">o_data[31:0]</obj_property>
<obj_property name="ObjectShortName">o_data[31:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
<wvobject fp_name="/pipelinebuffer_tb/o_data[31]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[31]</obj_property>
<obj_property name="ObjectShortName">o_data[31]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[30]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[30]</obj_property>
<obj_property name="ObjectShortName">o_data[30]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[29]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[29]</obj_property>
<obj_property name="ObjectShortName">o_data[29]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[28]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[28]</obj_property>
<obj_property name="ObjectShortName">o_data[28]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[27]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[27]</obj_property>
<obj_property name="ObjectShortName">o_data[27]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[26]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[26]</obj_property>
<obj_property name="ObjectShortName">o_data[26]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[25]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[25]</obj_property>
<obj_property name="ObjectShortName">o_data[25]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[24]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[24]</obj_property>
<obj_property name="ObjectShortName">o_data[24]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[23]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[23]</obj_property>
<obj_property name="ObjectShortName">o_data[23]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[22]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[22]</obj_property>
<obj_property name="ObjectShortName">o_data[22]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[21]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[21]</obj_property>
<obj_property name="ObjectShortName">o_data[21]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[20]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[20]</obj_property>
<obj_property name="ObjectShortName">o_data[20]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[19]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[19]</obj_property>
<obj_property name="ObjectShortName">o_data[19]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[18]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[18]</obj_property>
<obj_property name="ObjectShortName">o_data[18]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[17]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[17]</obj_property>
<obj_property name="ObjectShortName">o_data[17]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[16]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[16]</obj_property>
<obj_property name="ObjectShortName">o_data[16]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[15]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[15]</obj_property>
<obj_property name="ObjectShortName">o_data[15]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[14]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[14]</obj_property>
<obj_property name="ObjectShortName">o_data[14]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[13]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[13]</obj_property>
<obj_property name="ObjectShortName">o_data[13]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[12]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[12]</obj_property>
<obj_property name="ObjectShortName">o_data[12]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[11]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[11]</obj_property>
<obj_property name="ObjectShortName">o_data[11]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[10]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[10]</obj_property>
<obj_property name="ObjectShortName">o_data[10]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[9]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[9]</obj_property>
<obj_property name="ObjectShortName">o_data[9]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[8]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[8]</obj_property>
<obj_property name="ObjectShortName">o_data[8]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[7]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[7]</obj_property>
<obj_property name="ObjectShortName">o_data[7]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[6]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[6]</obj_property>
<obj_property name="ObjectShortName">o_data[6]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[5]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[5]</obj_property>
<obj_property name="ObjectShortName">o_data[5]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[4]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[4]</obj_property>
<obj_property name="ObjectShortName">o_data[4]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[3]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[3]</obj_property>
<obj_property name="ObjectShortName">o_data[3]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[2]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[2]</obj_property>
<obj_property name="ObjectShortName">o_data[2]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[1]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[1]</obj_property>
<obj_property name="ObjectShortName">o_data[1]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/o_data[0]" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">[0]</obj_property>
<obj_property name="ObjectShortName">o_data[0]</obj_property>
</wvobject>
</wvobject>
<wvobject fp_name="group15" type="group">
<obj_property name="label">Buffer</obj_property>
<obj_property name="DisplayName">label</obj_property>
<wvobject fp_name="/pipelinebuffer_tb/i_PipelineBuffer/i_enable" type="array" db_ref_id="1">
<obj_property name="ElementShortName">i_enable[1:0]</obj_property>
<obj_property name="ObjectShortName">i_enable[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_PipelineBuffer/i_data" type="array" db_ref_id="1">
<obj_property name="ElementShortName">i_data[31:0]</obj_property>
<obj_property name="ObjectShortName">i_data[31:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_PipelineBuffer/o_data" type="array" db_ref_id="1">
<obj_property name="ElementShortName">o_data[31:0]</obj_property>
<obj_property name="ObjectShortName">o_data[31:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_PipelineBuffer/c_mux" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">c_mux</obj_property>
<obj_property name="ObjectShortName">c_mux</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_PipelineBuffer/c_enable" type="logic" db_ref_id="1">
<obj_property name="ElementShortName">c_enable</obj_property>
<obj_property name="ObjectShortName">c_enable</obj_property>
</wvobject>
<wvobject fp_name="/pipelinebuffer_tb/i_PipelineBuffer/r_data" type="array" db_ref_id="1">
<obj_property name="ElementShortName">r_data[31:0]</obj_property>
<obj_property name="ObjectShortName">r_data[31:0]</obj_property>
<obj_property name="Radix">UNSIGNEDDECRADIX</obj_property>
</wvobject>
</wvobject>
</wave_config>

516
tests/PipelineSwitch_tb.vhd Normal file
View File

@@ -0,0 +1,516 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity PipelineSwitch_tb is
end entity PipelineSwitch_tb;
architecture RTL of PipelineSwitch_tb is
constant G_MaskWidth : integer := 4;
constant G_Mask : std_logic_vector(G_MaskWidth - 1 downto 0) := "1101";
-- === Signals for mode "none" ===
signal I_Match_none : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_none : std_logic := '0';
signal O_Ready_none : std_logic;
signal O_Default_Valid_none : std_logic;
signal I_Default_Ready_none : std_logic := '0';
signal O_Selected_Valid_none : std_logic;
signal I_Selected_Ready_none : std_logic := '0';
-- === Signals for mode "or" ===
signal I_Match_or : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_or : std_logic := '0';
signal O_Ready_or : std_logic;
signal O_Default_Valid_or : std_logic;
signal I_Default_Ready_or : std_logic := '0';
signal O_Selected_Valid_or : std_logic;
signal I_Selected_Ready_or : std_logic := '0';
-- === Signals for mode "and" ===
signal I_Match_and : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_and : std_logic := '0';
signal O_Ready_and : std_logic;
signal O_Default_Valid_and : std_logic;
signal I_Default_Ready_and : std_logic := '0';
signal O_Selected_Valid_and : std_logic;
signal I_Selected_Ready_and : std_logic := '0';
-- === Signals for mode "xor" ===
signal I_Match_xor : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_xor : std_logic := '0';
signal O_Ready_xor : std_logic;
signal O_Default_Valid_xor : std_logic;
signal I_Default_Ready_xor : std_logic := '0';
signal O_Selected_Valid_xor : std_logic;
signal I_Selected_Ready_xor : std_logic := '0';
-- === Signals for mode "equal" ===
signal I_Match_eq : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_eq : std_logic := '0';
signal O_Ready_eq : std_logic;
signal O_Default_Valid_eq : std_logic;
signal I_Default_Ready_eq : std_logic := '0';
signal O_Selected_Valid_eq : std_logic;
signal I_Selected_Ready_eq : std_logic := '0';
-- === Signals for mode "not_eq" ===
signal I_Match_neq : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_neq : std_logic := '0';
signal O_Ready_neq : std_logic;
signal O_Default_Valid_neq : std_logic;
signal I_Default_Ready_neq : std_logic := '0';
signal O_Selected_Valid_neq : std_logic;
signal I_Selected_Ready_neq : std_logic := '0';
-- === Signals for mode "gt" ===
signal I_Match_gt : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_gt : std_logic := '0';
signal O_Ready_gt : std_logic;
signal O_Default_Valid_gt : std_logic;
signal I_Default_Ready_gt : std_logic := '0';
signal O_Selected_Valid_gt : std_logic;
signal I_Selected_Ready_gt : std_logic := '0';
-- === Signals for mode "ge" ===
signal I_Match_ge : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_ge : std_logic := '0';
signal O_Ready_ge : std_logic;
signal O_Default_Valid_ge : std_logic;
signal I_Default_Ready_ge : std_logic := '0';
signal O_Selected_Valid_ge : std_logic;
signal I_Selected_Ready_ge : std_logic := '0';
-- === Signals for mode "lt" ===
signal I_Match_lt : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_lt : std_logic := '0';
signal O_Ready_lt : std_logic;
signal O_Default_Valid_lt : std_logic;
signal I_Default_Ready_lt : std_logic := '0';
signal O_Selected_Valid_lt : std_logic;
signal I_Selected_Ready_lt : std_logic := '0';
-- === Signals for mode "le" ===
signal I_Match_le : std_logic_vector(G_MaskWidth - 1 downto 0) := (others => '0');
signal I_Valid_le : std_logic := '0';
signal O_Ready_le : std_logic;
signal O_Default_Valid_le : std_logic;
signal I_Default_Ready_le : std_logic := '0';
signal O_Selected_Valid_le : std_logic;
signal I_Selected_Ready_le : std_logic := '0';
begin
-- === Instanz: "none" ===
UUT_none : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "none"
)
port map(
I_Match => I_Match_none,
I_Valid => I_Valid_none,
O_Ready => O_Ready_none,
O_Default_Valid => O_Default_Valid_none,
I_Default_Ready => I_Default_Ready_none,
O_Selected_Valid => O_Selected_Valid_none,
I_Selected_Ready => I_Selected_Ready_none
);
-- === Instanz: "or" ===
UUT_or : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "or"
)
port map(
I_Match => I_Match_or,
I_Valid => I_Valid_or,
O_Ready => O_Ready_or,
O_Default_Valid => O_Default_Valid_or,
I_Default_Ready => I_Default_Ready_or,
O_Selected_Valid => O_Selected_Valid_or,
I_Selected_Ready => I_Selected_Ready_or
);
-- === Instanz: "and" ===
UUT_and : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "and"
)
port map(
I_Match => I_Match_and,
I_Valid => I_Valid_and,
O_Ready => O_Ready_and,
O_Default_Valid => O_Default_Valid_and,
I_Default_Ready => I_Default_Ready_and,
O_Selected_Valid => O_Selected_Valid_and,
I_Selected_Ready => I_Selected_Ready_and
);
-- === Instanz: "xor" ===
UUT_xor : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "xor"
)
port map(
I_Match => I_Match_xor,
I_Valid => I_Valid_xor,
O_Ready => O_Ready_xor,
O_Default_Valid => O_Default_Valid_xor,
I_Default_Ready => I_Default_Ready_xor,
O_Selected_Valid => O_Selected_Valid_xor,
I_Selected_Ready => I_Selected_Ready_xor
);
-- === Instanz: "equal" ===
UUT_eq : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "equal"
)
port map(
I_Match => I_Match_eq,
I_Valid => I_Valid_eq,
O_Ready => O_Ready_eq,
O_Default_Valid => O_Default_Valid_eq,
I_Default_Ready => I_Default_Ready_eq,
O_Selected_Valid => O_Selected_Valid_eq,
I_Selected_Ready => I_Selected_Ready_eq
);
-- === Instanz: "not_eq" ===
UUT_neq : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "not_equal"
)
port map(
I_Match => I_Match_neq,
I_Valid => I_Valid_neq,
O_Ready => O_Ready_neq,
O_Default_Valid => O_Default_Valid_neq,
I_Default_Ready => I_Default_Ready_neq,
O_Selected_Valid => O_Selected_Valid_neq,
I_Selected_Ready => I_Selected_Ready_neq
);
-- === Instanz: "gt" ===
UUT_gt : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "gt"
)
port map(
I_Match => I_Match_gt,
I_Valid => I_Valid_gt,
O_Ready => O_Ready_gt,
O_Default_Valid => O_Default_Valid_gt,
I_Default_Ready => I_Default_Ready_gt,
O_Selected_Valid => O_Selected_Valid_gt,
I_Selected_Ready => I_Selected_Ready_gt
);
-- === Instanz: "ge" ===
UUT_ge : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "ge"
)
port map(
I_Match => I_Match_ge,
I_Valid => I_Valid_ge,
O_Ready => O_Ready_ge,
O_Default_Valid => O_Default_Valid_ge,
I_Default_Ready => I_Default_Ready_ge,
O_Selected_Valid => O_Selected_Valid_ge,
I_Selected_Ready => I_Selected_Ready_ge
);
-- === Instanz: "lt" ===
UUT_lt : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "lt"
)
port map(
I_Match => I_Match_lt,
I_Valid => I_Valid_lt,
O_Ready => O_Ready_lt,
O_Default_Valid => O_Default_Valid_lt,
I_Default_Ready => I_Default_Ready_lt,
O_Selected_Valid => O_Selected_Valid_lt,
I_Selected_Ready => I_Selected_Ready_lt
);
-- === Instanz: "le" ===
UUT_le : entity work.PipelineSwitch
generic map(
G_MaskWidth => G_MaskWidth,
G_Mask => G_Mask,
G_MaskMode => "le"
)
port map(
I_Match => I_Match_le,
I_Valid => I_Valid_le,
O_Ready => O_Ready_le,
O_Default_Valid => O_Default_Valid_le,
I_Default_Ready => I_Default_Ready_le,
O_Selected_Valid => O_Selected_Valid_le,
I_Selected_Ready => I_Selected_Ready_le
);
stimulus : process
begin
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "none"
----------------------------------------------------------------
report "Testmodus: none";
I_Default_Ready_none <= '1';
I_Match_none <= "0000";
I_Valid_none <= '1';
wait for 10 ns;
assert O_Default_Valid_none = '1' and O_Selected_Valid_none = '0'
report "Fehler im Modus 'none'" severity error;
I_Valid_none <= '0';
I_Default_Ready_none <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "or"
----------------------------------------------------------------
report "Testmodus: or";
I_Selected_Ready_or <= '1';
I_Match_or <= "0100"; -- bit 2 matches mask
I_Valid_or <= '1';
wait for 10 ns;
assert O_Selected_Valid_or = '1' and O_Default_Valid_or = '0'
report "Fehler im Modus 'or' (Match-Fall)" severity error;
I_Selected_Ready_or <= '0';
I_Valid_or <= '0';
wait for 10 ns;
I_Default_Ready_or <= '1';
I_Match_or <= "0010"; -- no bit matches mask
I_Valid_or <= '1';
wait for 10 ns;
assert O_Default_Valid_or = '1' and O_Selected_Valid_or = '0'
report "Fehler im Modus 'or' (No-Match-Fall)" severity error;
I_Default_Ready_or <= '0';
I_Valid_or <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "and"
----------------------------------------------------------------
report "Testmodus: and";
I_Selected_Ready_and <= '1';
I_Match_and <= "1101";
I_Valid_and <= '1';
wait for 10 ns;
assert O_Selected_Valid_and = '1' and O_Default_Valid_and = '0'
report "Fehler im Modus 'and' (Match-Fall)" severity error;
I_Selected_Ready_and <= '0';
I_Valid_and <= '0';
wait for 10 ns;
I_Default_Ready_and <= '1';
I_Match_and <= "1001"; -- bit 2 missing
I_Valid_and <= '1';
wait for 10 ns;
assert O_Default_Valid_and = '1' and O_Selected_Valid_and = '0'
report "Fehler im Modus 'and' (No-Match-Fall)" severity error;
I_Default_Ready_and <= '0';
I_Valid_and <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "xor"
----------------------------------------------------------------
report "Testmodus: xor";
I_Selected_Ready_xor <= '1';
I_Match_xor <= "1001"; -- differs at bit 2
I_Valid_xor <= '1';
wait for 10 ns;
assert O_Selected_Valid_xor = '1' and O_Default_Valid_xor = '0'
report "Fehler im Modus 'xor' (Match-Fall)" severity error;
I_Selected_Ready_xor <= '0';
I_Valid_xor <= '0';
wait for 10 ns;
I_Default_Ready_xor <= '1';
I_Match_xor <= "1101";
I_Valid_xor <= '1';
wait for 10 ns;
assert O_Default_Valid_xor = '1' and O_Selected_Valid_xor = '0'
report "Fehler im Modus 'xor' (No-Match-Fall)" severity error;
I_Default_Ready_xor <= '0';
I_Valid_xor <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "equal"
----------------------------------------------------------------
report "Testmodus: equal";
I_Selected_Ready_eq <= '1';
I_Match_eq <= "1101";
I_Valid_eq <= '1';
wait for 10 ns;
assert O_Selected_Valid_eq = '1' and O_Default_Valid_eq = '0'
report "Fehler im Modus 'equal' (Match-Fall)" severity error;
I_Selected_Ready_eq <= '0';
I_Valid_eq <= '0';
wait for 10 ns;
I_Default_Ready_eq <= '1';
I_Match_eq <= "1111";
I_Valid_eq <= '1';
wait for 10 ns;
assert O_Default_Valid_eq = '1' and O_Selected_Valid_eq = '0'
report "Fehler im Modus 'equal' (No-Match-Fall)" severity error;
I_Default_Ready_eq <= '0';
I_Valid_eq <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "not_equal"
----------------------------------------------------------------
report "Testmodus: not_equal";
I_Selected_Ready_neq <= '1';
I_Match_neq <= "1111"; -- not equal
I_Valid_neq <= '1';
wait for 10 ns;
assert O_Selected_Valid_neq = '1' and O_Default_Valid_neq = '0'
report "Fehler im Modus 'not_equal' (Match-Fall)" severity error;
I_Selected_Ready_neq <= '0';
I_Valid_neq <= '0';
wait for 10 ns;
I_Default_Ready_neq <= '1';
I_Match_neq <= "1101";
I_Valid_neq <= '1';
wait for 10 ns;
assert O_Default_Valid_neq = '1' and O_Selected_Valid_neq = '0'
report "Fehler im Modus 'not_equal' (No-Match-Fall)" severity error;
I_Default_Ready_neq <= '0';
I_Valid_neq <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "gt"
----------------------------------------------------------------
report "Testmodus: gt";
I_Selected_Ready_gt <= '1';
I_Match_gt <= "1110"; -- > 1101
I_Valid_gt <= '1';
wait for 10 ns;
assert O_Selected_Valid_gt = '1' and O_Default_Valid_gt = '0'
report "Fehler im Modus 'gt' (Match-Fall)" severity error;
I_Selected_Ready_gt <= '0';
I_Valid_gt <= '0';
wait for 10 ns;
I_Default_Ready_gt <= '1';
I_Match_gt <= "1010"; -- < 1101
I_Valid_gt <= '1';
wait for 10 ns;
assert O_Default_Valid_gt = '1' and O_Selected_Valid_gt = '0'
report "Fehler im Modus 'gt' (No-Match-Fall)" severity error;
I_Default_Ready_gt <= '0';
I_Valid_gt <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "ge"
----------------------------------------------------------------
report "Testmodus: ge";
I_Selected_Ready_ge <= '1';
I_Match_ge <= "1101"; -- == 1101
I_Valid_ge <= '1';
wait for 10 ns;
assert O_Selected_Valid_ge = '1' and O_Default_Valid_ge = '0'
report "Fehler im Modus 'ge' (Match-Fall ==)" severity error;
I_Selected_Ready_ge <= '0';
I_Valid_ge <= '0';
wait for 10 ns;
I_Default_Ready_ge <= '1';
I_Match_ge <= "0101"; -- < 1101
I_Valid_ge <= '1';
wait for 10 ns;
assert O_Default_Valid_ge = '1' and O_Selected_Valid_ge = '0'
report "Fehler im Modus 'ge' (No-Match-Fall)" severity error;
I_Default_Ready_ge <= '0';
I_Valid_ge <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "lt"
----------------------------------------------------------------
report "Testmodus: lt";
I_Selected_Ready_lt <= '1';
I_Match_lt <= "0101"; -- < 1101
I_Valid_lt <= '1';
wait for 10 ns;
assert O_Selected_Valid_lt = '1' and O_Default_Valid_lt = '0'
report "Fehler im Modus 'lt' (Match-Fall)" severity error;
I_Selected_Ready_lt <= '0';
I_Valid_lt <= '0';
wait for 10 ns;
I_Default_Ready_lt <= '1';
I_Match_lt <= "1111"; -- > 1101
I_Valid_lt <= '1';
wait for 10 ns;
assert O_Default_Valid_lt = '1' and O_Selected_Valid_lt = '0'
report "Fehler im Modus 'lt' (No-Match-Fall)" severity error;
I_Default_Ready_lt <= '0';
I_Valid_lt <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Mode: "le"
----------------------------------------------------------------
report "Testmodus: le";
I_Selected_Ready_le <= '1';
I_Match_le <= "1101"; -- == 1101
I_Valid_le <= '1';
wait for 10 ns;
assert O_Selected_Valid_le = '1' and O_Default_Valid_le = '0'
report "Fehler im Modus 'le' (Match-Fall ==)" severity error;
I_Selected_Ready_le <= '0';
I_Valid_le <= '0';
wait for 10 ns;
I_Default_Ready_le <= '1';
I_Match_le <= "1111"; -- > 1101
I_Valid_le <= '1';
wait for 10 ns;
assert O_Default_Valid_le = '1' and O_Selected_Valid_le = '0'
report "Fehler im Modus 'le' (No-Match-Fall)" severity error;
I_Default_Ready_le <= '0';
I_Valid_le <= '0';
wait for 10 ns;
----------------------------------------------------------------
-- Done!
----------------------------------------------------------------
report "Alle Tests abgeschlossen!" severity note;
wait;
end process;
end architecture RTL;