Compare commits

..

4 Commits

Author SHA1 Message Date
310a85bcb5 feat(entity): add default values to GenericCounter ports
- Initialize all input and output ports with default values
- Enhances usability by preventing uninitialized signals
2025-07-07 12:26:50 +00:00
c86249d4b3 refactor(entity): rename generics and ports for clarity
- Standardizes naming conventions for generics and ports
- Improves readability and consistency across the entity architecture
2025-07-07 12:24:38 +00:00
685e94e8ae feat(counter): update clock timing constraints 2025-07-07 12:19:31 +00:00
eb7cf461f9 feat(devcontainer): add development environment configuration
- Introduces a devcontainer.json for Xilinx ISE development setup
- Replaces project.cfg with project.yml for improved build clarity
- Updates .gitignore to exclude build artifacts and configuration files
- Removes outdated Git submodules and legacy project files
- Enhances VS Code settings for better UI customization
- Configures GPG signing and Python package installation post startup
2025-07-07 12:19:19 +00:00
9 changed files with 357 additions and 135 deletions

View File

@@ -0,0 +1,30 @@
{
"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"
],
"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"
}

7
.gitignore vendored
View File

@@ -1 +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": "#d48282",
"activityBar.background": "#d48282",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#b8e7b8",
"activityBarBadge.foreground": "#15202b"
},
"peacock.color": "#80d5e0",
"peacock.remoteColor": "#c75c5c"
}

1
build

Submodule build deleted from a8ed470e7d

View File

@@ -1,89 +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 = GenericCounter
# Target device
# @example xc3s1200e-4-fg320 | xc5vlx50t-1-ff1136
TARGET_PART = xc5vlx50t-1-ff1136
# 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 =
# Optional the name of the ucf file (default is the project name)
CONSTRAINTS = src/GenericCounter.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/GenericCounter.vhd
VHDTEST += tests/GenericCounter_tb.vhd
## ## ## ## ## ## ## ##
# ---------------------
## ISE executable settings.. ##
ISIM_CMD = vcd dumpfile $@.vcd\nvcd dumpvars -m /UUT\nrun 1 us\nvcd dumpflush\nquit
# General command line options to be passed to all ISE executables (default is `-intstyle xflow`)
# COMMON_OPTS =
# Options for the XST synthesizer
# XST_OPTS =
# Options for the NGDBuild tool
# NGDBUILD_OPTS =
# Options for the MAP tool
# @example -mt 2 (multi-threading with 2 threads)
# MAP_OPTS =
# Options for the PAR tool
# @example -mt 2 (multi-threading with 2 threads)
# PAR_OPTS =
# 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 =
## ## ## ## ## ## ## ##
# ---------------------
## 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: GenericCounter
topmodule: GenericCounter
target_device: xc3s1200e-4-fg320
xilinx_path: /opt/Xilinx/14.7/ISE_DS/ISE
constraints: src/GenericCounter.ucf
sources:
vhdl:
- path: src/*.vhd
library: work
- path: libs/*.vhd
library: work
testbenches:
vhdl:
- path: test/*.vhd
library: work
dependencies:
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 500"
# 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"

View File

@@ -1,4 +1,4 @@
#NET CLK LOC = B8;
NET CLK LOC = AG18;
NET CLK LOC = B8;
#NET CLK LOC = AG18;
NET CLK TNM_NET = CLOCK;
TIMESPEC TS_CLOCK = PERIOD CLOCK 700 MHz HIGH 50 %;
TIMESPEC TS_CLOCK = PERIOD CLOCK 200 MHz HIGH 50 %;

View File

@@ -96,88 +96,88 @@ use ieee.math_real.all;
entity GenericCounter is
generic (
--@ Width of the counter
Width : integer := 4;
G_Width : integer := 4;
--@ Initial value of the counter
InitialValue : integer := 0;
G_InitialValue : integer := 0;
--@ Reset value of the counter
ResetValue : integer := 0;
G_ResetValue : integer := 0;
--@ Counting direction: "UP" or "DOWN"
CountingDirection : string := "UP";
G_CountingDirection : string := "UP";
--@ Look ahead value
LookAhead : integer := 0
);
G_LookAhead : integer := 0
);
port (
--@ Clock input; rising edge
CLK : in std_logic;
I_CLK : in std_logic := '0';
--@ Reset input; active high; synchronous
RST : in std_logic;
I_RST : in std_logic := '0';
--@ Clock enable; active high
CE : in std_logic;
I_CE : in std_logic := '1';
--@ Count enable; active high
CountEnable : in std_logic;
I_CountEnable : in std_logic := '0';
--@ Counter Value
CounterValue : out std_logic_vector(Width - 1 downto 0);
O_CounterValue : out std_logic_vector(G_Width - 1 downto 0) := (others => '0');
--@ Look ahead value
LookAheadValue : out std_logic_vector(Width - 1 downto 0);
O_LookAheadValue : out std_logic_vector(G_Width - 1 downto 0) := (others => '0');
--@ Set with priority over the `CountEnable`
Set : in std_logic;
I_Set : in std_logic := '0';
--@ If set is high, the counter will be set to SetValue
SetValue : in std_logic_vector(Width - 1 downto 0);
I_SetValue : in std_logic_vector(G_Width - 1 downto 0) := (others => '0');
--@ Over- and Underflow flag
OverUnderflow : out std_logic
);
O_OverUnderflow : out std_logic := '0'
);
end entity GenericCounter;
architecture RTL of GenericCounter is
function CountingStep(BinaryValue : unsigned; Step : integer := 1)
return unsigned is
begin
if CountingDirection = "UP" then
if G_CountingDirection = "UP" then
return BinaryValue + Step;
else
return BinaryValue - Step;
end if;
end function CountingStep;
signal R_Counter : unsigned(Width - 1 downto 0) := to_unsigned(InitialValue, Width);
signal C_NextCounter : unsigned(Width - 1 downto 0) := to_unsigned(InitialValue, Width);
signal C_LookAhead : unsigned(Width - 1 downto 0) := to_unsigned(InitialValue + LookAhead, Width);
signal R_Counter : unsigned(G_Width - 1 downto 0) := to_unsigned(G_InitialValue, G_Width);
signal C_NextCounter : unsigned(G_Width - 1 downto 0) := to_unsigned(G_InitialValue, G_Width);
signal C_LookAhead : unsigned(G_Width - 1 downto 0) := to_unsigned(G_InitialValue + G_LookAhead, G_Width);
signal C_OverUnderflow : std_logic;
begin
process (CLK)
process (I_CLK)
begin
if rising_edge(CLK) then
if RST = '1' then
R_Counter <= to_unsigned(ResetValue, Width);
elsif CE = '1' then
if rising_edge(I_CLK) then
if I_RST = '1' then
R_Counter <= to_unsigned(G_ResetValue, G_Width);
elsif I_CE = '1' then
R_Counter <= C_NextCounter;
end if;
end if;
end process;
Counting : process (R_Counter, CountEnable, Set, SetValue)
variable V_OverUnderflow : unsigned(Width downto 0);
Counting : process (R_Counter, I_CountEnable, I_Set, I_SetValue)
variable V_OverUnderflow : unsigned(G_Width downto 0);
begin
V_OverUnderflow := CountingStep("0" & R_Counter);
if Set = '1' then
C_NextCounter <= unsigned(SetValue);
C_LookAhead <= CountingStep(unsigned(SetValue), LookAhead);
if I_Set = '1' then
C_NextCounter <= unsigned(I_SetValue);
C_LookAhead <= CountingStep(unsigned(I_SetValue), G_LookAhead);
C_OverUnderflow <= '0';
elsif CountEnable = '1' then
C_NextCounter <= V_OverUnderflow(Width - 1 downto 0);
C_LookAhead <= CountingStep(R_Counter, 1 + LookAhead);
C_OverUnderflow <= V_OverUnderflow(Width);
elsif I_CountEnable = '1' then
C_NextCounter <= V_OverUnderflow(G_Width - 1 downto 0);
C_LookAhead <= CountingStep(R_Counter, 1 + G_LookAhead);
C_OverUnderflow <= V_OverUnderflow(G_Width);
else
C_NextCounter <= R_Counter;
C_LookAhead <= CountingStep(R_Counter, LookAhead);
C_LookAhead <= CountingStep(R_Counter, G_LookAhead);
C_OverUnderflow <= '0';
end if;
end process;
LookAheadValue <= std_logic_vector(C_LookAhead);
CounterValue <= std_logic_vector(C_NextCounter);
OverUnderflow <= C_OverUnderflow;
O_LookAheadValue <= std_logic_vector(C_LookAhead);
O_CounterValue <= std_logic_vector(C_NextCounter);
O_OverUnderflow <= C_OverUnderflow;
end architecture RTL;