Roll -over values using MOD funtion

Guest
Hello folks,

I would like to have a counter which counts only from 0000 to 1111 so i
have used a mod function. but somehow during the simulation i exceed
"1111" and getting message as follows:

"RUNTIME: Fatal Error: RUNTIME_0043 addr_counter.vhd (54): Value 17 out
of range (0 to 16)"

I understand tht my counter is exceeding "1111" so on as i hve given a
range for int_count signal but is tht range is incorrect ? or should i
consider as differnt datatype?

Can someof you find the fault in my code ?

Sincerely,
ALI


------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
------------------------------------------------------------------
ENTITY ADDR_COUNTER IS
GENERIC
(
WIDTH : NATURAL := 4
);
PORT
(
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN_COUNT : IN STD_LOGIC;
UPDOWN : IN STD_LOGIC;
FULL : OUT STD_LOGIC;
EMPTY : OUT STD_LOGIC
);
END ADDR_COUNTER;
------------------------------------------------------------------
ARCHITECTURE ARCH_COUNTER OF ADDR_COUNTER IS

CONSTANT LENGTH : INTEGER := 2 ** WIDTH;
SIGNAL INT_COUNT : INTEGER RANGE 0 TO LENGTH;
------------------------------------------------------------------
BEGIN

FULL <= '1' WHEN INT_COUNT = LENGTH ELSE '0';
EMPTY <= '1' WHEN INT_COUNT = 0 ELSE '1';

COUNT_PRO: PROCESS (CLK, RST)
BEGIN
IF RST = '0' THEN
INT_COUNT <= 0;
FULL <= '0';
EMPTY <= '1';
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF EN_COUNT = '1' THEN
IF UPDOWN='1' THEN
INT_COUNT <= INT_COUNT + 1 MOD LENGTH;
ELSE
INT_COUNT <= INT_COUNT - 1 MOD LENGTH;
END IF;
END IF;
END IF;
END PROCESS COUNT_PRO;
------------------------------------------------------------------
END ARCH_COUNTER;
------------------------------------------------------------------
 
Hello again,

The below mentioned works fine,but i am not able to get EMPTY = '1'
when int_count <= length value and Full = '1' when int_count <= length;

can anybody tell me where i went wrong?

Sincerely,
ALI

------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
------------------------------------------------------------------
ENTITY ADDR_COUNTER IS
GENERIC
(
WIDTH : INTEGER := 4 -- ADDR WIDTH
);
PORT
(
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN_COUNT : IN STD_LOGIC;
UPDOWN : IN STD_LOGIC;
FULL : OUT STD_LOGIC;
EMPTY : OUT STD_LOGIC
);
END ADDR_COUNTER;
------------------------------------------------------------------
ARCHITECTURE ARCH_COUNTER OF ADDR_COUNTER IS

CONSTANT LENGTH : NATURAL := 2 ** ADDR_WIDTH;
SIGNAL INT_COUNT : UNSIGNED(1 TO (ADDR_WIDTH));
------------------------------------------------------------------
BEGIN

FULL <= '1' WHEN INT_COUNT = LENGTH ELSE '0';
EMPTY <= '1' WHEN INT_COUNT < LENGTH ELSE '0';

COUNT_PRO: PROCESS (CLK, RST)
BEGIN
IF RST = '0' THEN
INT_COUNT <= "0000"; --
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF EN_COUNT = '1' THEN
IF UPDOWN='1' THEN
INT_COUNT <= INT_COUNT + 1 MOD LENGTH;
ELSE
INT_COUNT <= INT_COUNT - 1 MOD LENGTH;
END IF;
END IF;
END IF;
END PROCESS COUNT_PRO;
------------------------------------------------------------------
END ARCH_COUNTER;
------------------------------------------------------------------




jahaya@gmail.com wrote:
Hello folks,

I would like to have a counter which counts only from 0000 to 1111 so i
have used a mod function. but somehow during the simulation i exceed
"1111" and getting message as follows:

"RUNTIME: Fatal Error: RUNTIME_0043 addr_counter.vhd (54): Value 17 out
of range (0 to 16)"

I understand tht my counter is exceeding "1111" so on as i hve given a
range for int_count signal but is tht range is incorrect ? or should i
consider as differnt datatype?

Can someof you find the fault in my code ?

Sincerely,
ALI


------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
------------------------------------------------------------------
ENTITY ADDR_COUNTER IS
GENERIC
(
WIDTH : NATURAL := 4
);
PORT
(
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN_COUNT : IN STD_LOGIC;
UPDOWN : IN STD_LOGIC;
FULL : OUT STD_LOGIC;
EMPTY : OUT STD_LOGIC
);
END ADDR_COUNTER;
------------------------------------------------------------------
ARCHITECTURE ARCH_COUNTER OF ADDR_COUNTER IS

CONSTANT LENGTH : INTEGER := 2 ** WIDTH;
SIGNAL INT_COUNT : INTEGER RANGE 0 TO LENGTH;
------------------------------------------------------------------
BEGIN

FULL <= '1' WHEN INT_COUNT = LENGTH ELSE '0';
EMPTY <= '1' WHEN INT_COUNT = 0 ELSE '1';

COUNT_PRO: PROCESS (CLK, RST)
BEGIN
IF RST = '0' THEN
INT_COUNT <= 0;
FULL <= '0';
EMPTY <= '1';
ELSIF (CLK'EVENT AND CLK = '1') THEN
IF EN_COUNT = '1' THEN
IF UPDOWN='1' THEN
INT_COUNT <= INT_COUNT + 1 MOD LENGTH;
ELSE
INT_COUNT <= INT_COUNT - 1 MOD LENGTH;
END IF;
END IF;
END IF;
END PROCESS COUNT_PRO;
------------------------------------------------------------------
END ARCH_COUNTER;
------------------------------------------------------------------
 
The best solution is not to use integers for counters. Use
std_logic_vector(WIDTH-1 DOWNTO 0)
There is automatic rollover with vectors, hence you need not bother
about FATAL errors.
But your above logic should work properly if the module before this is
controlled properly. i.e once your counter is full, there are no more
increments.

Sudhi
 
when unsigned(3 downto 0) is used ? what is the use of mod operation ?
 
jahaya@gmail.com wrote:

I would like to have a counter which counts only from 0000 to 1111 so i
have used a mod function.
A "difficult" solution for a simple problem... What about:

signal cnt : unsigned(3 downto 0);

process(rst,clk)
begin
if (rst='0') then
cnt<=(others=>'0');
elsif rising_edge(clk) then
cnt<=cnt+1; -- rolls over automatically
end if;
end process;


Ralf
 
jahaya@gmail.com wrote:

Can someof you find the fault in my code ?


CONSTANT LENGTH : INTEGER := 2 ** WIDTH;
SIGNAL INT_COUNT : INTEGER RANGE 0 TO LENGTH;
You probably want range 0 to (LENGTH-1) here.

-a
 

Welcome to EDABoard.com

Sponsor

Back
Top