Add GenericCounter VHDL module
The Generic Counter VHDL module has been added under `src`, providing a configurable digital counter with synchronous reset, clock enable, set priority, over/underflow flag, and up/down counting capabilities. This addition includes detailed documentation and a waveform for simulation purposes, signifying an emphasis on maintainability and verification via the included Testbench, which has passed simulation.
This commit is contained in:
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
|||||||
[submodule "build"]
|
[submodule "build"]
|
||||||
path = build
|
path = build
|
||||||
url = ssh://git@github.com:PxaMMaxP/Xilinx-ISE-Makefile.git
|
url = https://github.com/PxaMMaxP/Xilinx-ISE-Makefile.git
|
||||||
|
1
build
Submodule
1
build
Submodule
Submodule build added at d7eebb6517
183
src/GenericCounter.vhd
Normal file
183
src/GenericCounter.vhd
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
----------------------------------------------------------------------------------
|
||||||
|
--@ - Name: Generic Counter <br>
|
||||||
|
--@ - Version: 0.0.2 <br>
|
||||||
|
--@ - Author: __Maximilian Passarello ([Blog](mpassarello.de))__ <br>
|
||||||
|
--@ - License: [MIT](LICENSE) <br>
|
||||||
|
--@
|
||||||
|
--@ Generic Counter with the following features:
|
||||||
|
--@ - **Without Output Register**
|
||||||
|
--@ - Look ahead value (configurable per generic)
|
||||||
|
--@ - Synchronous reset
|
||||||
|
--@ - Clock enable
|
||||||
|
--@ - Set with priority over the `CountEnable`
|
||||||
|
--@ - Over- and Underflow flag
|
||||||
|
--@ - Configurable width
|
||||||
|
--@ - Configurable initial value
|
||||||
|
--@ - Configurable reset value
|
||||||
|
--@ - Configurable counting direction (Up and Down counting)
|
||||||
|
--@ ## History
|
||||||
|
--@ - 0.0.1 (2024-03-15) Initial version
|
||||||
|
--@ - 0.0.2 (2024-03-16) Added Testbench. Simulation passed.
|
||||||
|
----------------------------------------------------------------------------------
|
||||||
|
--@ ## Waveform
|
||||||
|
--@ {
|
||||||
|
--@ "signal": [
|
||||||
|
--@ [
|
||||||
|
--@ "General",
|
||||||
|
--@ {
|
||||||
|
--@ "name": "CLK",
|
||||||
|
--@ "wave": "P.....|........",
|
||||||
|
--@ "node": "0123456789abcde",
|
||||||
|
--@ "period": 1
|
||||||
|
--@ },
|
||||||
|
--@ {
|
||||||
|
--@ "name": "RST",
|
||||||
|
--@ "wave": "10....|.....10."
|
||||||
|
--@ },
|
||||||
|
--@ {
|
||||||
|
--@ "name": "CE",
|
||||||
|
--@ "wave": "0.1...|........"
|
||||||
|
--@ }
|
||||||
|
--@ ],
|
||||||
|
--@ [
|
||||||
|
--@ "Set",
|
||||||
|
--@ {
|
||||||
|
--@ "name": "Set",
|
||||||
|
--@ "wave": "0.....|..10...."
|
||||||
|
--@ },
|
||||||
|
--@ {
|
||||||
|
--@ "name": "SetValue",
|
||||||
|
--@ "wave": "x.....|..8x....",
|
||||||
|
--@ "data": [
|
||||||
|
--@ "5"
|
||||||
|
--@ ]
|
||||||
|
--@ }
|
||||||
|
--@ ],
|
||||||
|
--@ [
|
||||||
|
--@ "Counter",
|
||||||
|
--@ {
|
||||||
|
--@ "name": "CountEnable",
|
||||||
|
--@ "wave": "0..1..|.......0"
|
||||||
|
--@ },
|
||||||
|
--@ {
|
||||||
|
--@ "name": "CounterValue",
|
||||||
|
--@ "wave": "4..777|77777777",
|
||||||
|
--@ "data": "0 1 2 3 15 0 5 6 7 8 1 1"
|
||||||
|
--@ },
|
||||||
|
--@ {
|
||||||
|
--@ "name": "LookAheadValue",
|
||||||
|
--@ "wave": "4..777|77777777",
|
||||||
|
--@ "data": "1 2 3 4 0 1 6 7 8 9 2 2"
|
||||||
|
--@ }
|
||||||
|
--@ ],
|
||||||
|
--@ [
|
||||||
|
--@ "Flags",
|
||||||
|
--@ {
|
||||||
|
--@ "name": "OverUnderflow",
|
||||||
|
--@ "wave": "0.....|.10....."
|
||||||
|
--@ }
|
||||||
|
--@ ]
|
||||||
|
--@ ],
|
||||||
|
--@ "config": {
|
||||||
|
--@ "hscale": 1
|
||||||
|
--@ },
|
||||||
|
--@ "head": {
|
||||||
|
--@ "text": "<b>Generic Counter</b>"
|
||||||
|
--@ },
|
||||||
|
--@ "foot": {
|
||||||
|
--@ "text": "RST Value = 0"
|
||||||
|
--@ }
|
||||||
|
--@ }
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
use ieee.math_real.all;
|
||||||
|
|
||||||
|
entity GenericCounter is
|
||||||
|
generic (
|
||||||
|
--@ Width of the counter
|
||||||
|
Width : integer := 4;
|
||||||
|
--@ Initial value of the counter
|
||||||
|
InitialValue : integer := 0;
|
||||||
|
--@ Reset value of the counter
|
||||||
|
ResetValue : integer := 0;
|
||||||
|
--@ Counting direction: "UP" or "DOWN"
|
||||||
|
CountingDirection : string := "UP";
|
||||||
|
--@ Look ahead value
|
||||||
|
LookAhead : integer := 0
|
||||||
|
);
|
||||||
|
port (
|
||||||
|
--@ Clock input; rising edge
|
||||||
|
CLK : in std_logic;
|
||||||
|
--@ Reset input; active high; synchronous
|
||||||
|
RST : in std_logic;
|
||||||
|
--@ Clock enable; active high
|
||||||
|
CE : in std_logic;
|
||||||
|
--@ Count enable; active high
|
||||||
|
CountEnable : in std_logic;
|
||||||
|
--@ Counter Value
|
||||||
|
CounterValue : out std_logic_vector(Width - 1 downto 0);
|
||||||
|
--@ Look ahead value
|
||||||
|
LookAheadValue : out std_logic_vector(Width - 1 downto 0);
|
||||||
|
--@ Set with priority over the `CountEnable`
|
||||||
|
Set : in std_logic;
|
||||||
|
--@ If set is high, the counter will be set to SetValue
|
||||||
|
SetValue : in std_logic_vector(Width - 1 downto 0);
|
||||||
|
--@ Over- and Underflow flag
|
||||||
|
OverUnderflow : out std_logic
|
||||||
|
);
|
||||||
|
end entity GenericCounter;
|
||||||
|
|
||||||
|
architecture RTL of GenericCounter is
|
||||||
|
function CountingStep(BinaryValue : unsigned; Step : integer := 1)
|
||||||
|
return unsigned is
|
||||||
|
begin
|
||||||
|
if 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 C_OverUnderflow : std_logic;
|
||||||
|
begin
|
||||||
|
|
||||||
|
process (CLK)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK) then
|
||||||
|
if RST = '1' then
|
||||||
|
R_Counter <= to_unsigned(ResetValue, Width);
|
||||||
|
elsif 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);
|
||||||
|
begin
|
||||||
|
V_OverUnderflow := CountingStep("0" & R_Counter);
|
||||||
|
|
||||||
|
if Set = '1' then
|
||||||
|
C_NextCounter <= unsigned(SetValue);
|
||||||
|
C_LookAhead <= CountingStep(unsigned(SetValue), 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);
|
||||||
|
else
|
||||||
|
C_NextCounter <= R_Counter;
|
||||||
|
C_LookAhead <= CountingStep(R_Counter, LookAhead);
|
||||||
|
C_OverUnderflow <= '0';
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
LookAheadValue <= std_logic_vector(C_LookAhead);
|
||||||
|
CounterValue <= std_logic_vector(C_NextCounter);
|
||||||
|
OverUnderflow <= C_OverUnderflow;
|
||||||
|
|
||||||
|
end architecture RTL;
|
Reference in New Issue
Block a user