B
Brandon Spiteri
I implemented an 8-bit Synchronous programmable counter with;
-asynchronous active low reset
-Synchronous enable
-Count up or down (with rising edge)
-Terminal counter up (for overflow)
-Terminal Counter down (underflow)
-Asynch load
-8-bit parallel load:
--counter.vhd
LIBRARY ieee;
-- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
use ieee.std_logic_1164.all;
-- SIGNED and UNSIGNED types, and relevant functions
use ieee.numeric_std.all;
ENTITY counter IS
PORT (
dir, cnt_en, clk : in std_logic := '0';
Reset, load : in std_logic;
p : in INTEGER RANGE 0 TO 255;
qd : inout INTEGER RANGE 0 TO 255;
TCU, TCD : out std_logic;
cnt_in : inout std_logic_vector (7 downto 0) := (others => '0');
cnt_out : out std_logic_vector (7 downto 0) := (others => '0'));
END counter;
ARCHITECTURE RTL OF counter IS
signal cnt : INTEGER RANGE 0 TO 255;
signal NotCPU : std_logic := '0';
BEGIN
cnt_out <= std_logic_vector(to_unsigned(cnt, cnt_out'length));
PROCESS (clk, Reset, p, qd, dir, cnt_en, cnt, load)
BEGIN
IF (Reset = '0') THEN
cnt <= 0;
ELSIF (load = '1' and Reset = '1') THEN --load is activated
cnt <= p;
ELSE
IF (rising_edge(clk)) THEN
IF (dir = '1' and cnt_en = '1') THEN
cnt <= cnt + 1;
TCD <= '1';
TCU <= '1';
ELSIF (dir = '0' and cnt_en = '1') THEN
cnt <= cnt - 1;
TCD <= '1';
TCU <= '1';
END IF;
END IF;
END IF;
qd <= cnt;
if cnt = 0 then
if (dir = '1') then
TCD <= '1';
TCU <= '1';
elsif (dir = '0') then
TCD <= '0';
TCU <= '1';
end if;
elsif (cnt = 255) then
if (dir = '1') then
TCD <= '1';
TCU <= '0';
elsif (dir = '0') then
TCD <= '1';
TCU <= '1';
end if;
end if;
END PROCESS;
END RTL;
_____________________________________________________________________________________________________
When I simulated with the following test bench I got results that match theTruth table in the 74HC193 data sheet. What do you think? The only problemis that although I am declaring an integer with a range, when the integer (cnt) is exceeding the maximum upper limit 255, the simulation stops instead of resetting the this integer (cnt) automatically. Do I have to take careof resetting it my self in the vhdl code?
--counter_test.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity counter_test is
end Entity counter_test;
Architecture behavioral of counter_test is
Signal dir, cnt_en, clk, TCU, TCD : std_logic := '0';
Signal Reset, load : std_logic := '1';
signal p, qd : integer range 0 to 255 ;
Signal Endsim : std_logic := '0';
Signal cnt_in, cnt_out : std_logic_vector (7 downto 0) := (others => '0');
begin
UUT : entity work.counter
port map ( clk => clk,
Reset => Reset,
load => load,
p => p,
dir => dir,
qd => qd,
TCU => TCU,
TCD => TCD,
cnt_en => cnt_en,
cnt_in => cnt_in,
cnt_out => cnt_out);
CLK_process
rocess
begin
if(EndSim = '0') then
clk <= NOT clk;
wait for 2ns;
else wait;
end if;
end process;
Signals : process
Begin
wait for 0.5 ns;
Reset <= '1';
dir <= '1';
cnt_en <= '1';
load <= '0';
wait for 1020ns;
cnt_en <= '0';
wait for 50ns;
cnt_en <= '1';
dir <= '0';
wait for 1020ns;
cnt_en <= '0';
wait for 50ns;
load <= '1';
p <= 100;
wait for 4ns;
load <= '0';
cnt_en <= '1';
wait for 200ns;
Reset <= '0';
wait for 100ns;
EndSim <= '1';
wait;
end process;
end Architecture behavioral;
-asynchronous active low reset
-Synchronous enable
-Count up or down (with rising edge)
-Terminal counter up (for overflow)
-Terminal Counter down (underflow)
-Asynch load
-8-bit parallel load:
--counter.vhd
LIBRARY ieee;
-- STD_LOGIC and STD_LOGIC_VECTOR types, and relevant functions
use ieee.std_logic_1164.all;
-- SIGNED and UNSIGNED types, and relevant functions
use ieee.numeric_std.all;
ENTITY counter IS
PORT (
dir, cnt_en, clk : in std_logic := '0';
Reset, load : in std_logic;
p : in INTEGER RANGE 0 TO 255;
qd : inout INTEGER RANGE 0 TO 255;
TCU, TCD : out std_logic;
cnt_in : inout std_logic_vector (7 downto 0) := (others => '0');
cnt_out : out std_logic_vector (7 downto 0) := (others => '0'));
END counter;
ARCHITECTURE RTL OF counter IS
signal cnt : INTEGER RANGE 0 TO 255;
signal NotCPU : std_logic := '0';
BEGIN
cnt_out <= std_logic_vector(to_unsigned(cnt, cnt_out'length));
PROCESS (clk, Reset, p, qd, dir, cnt_en, cnt, load)
BEGIN
IF (Reset = '0') THEN
cnt <= 0;
ELSIF (load = '1' and Reset = '1') THEN --load is activated
cnt <= p;
ELSE
IF (rising_edge(clk)) THEN
IF (dir = '1' and cnt_en = '1') THEN
cnt <= cnt + 1;
TCD <= '1';
TCU <= '1';
ELSIF (dir = '0' and cnt_en = '1') THEN
cnt <= cnt - 1;
TCD <= '1';
TCU <= '1';
END IF;
END IF;
END IF;
qd <= cnt;
if cnt = 0 then
if (dir = '1') then
TCD <= '1';
TCU <= '1';
elsif (dir = '0') then
TCD <= '0';
TCU <= '1';
end if;
elsif (cnt = 255) then
if (dir = '1') then
TCD <= '1';
TCU <= '0';
elsif (dir = '0') then
TCD <= '1';
TCU <= '1';
end if;
end if;
END PROCESS;
END RTL;
_____________________________________________________________________________________________________
When I simulated with the following test bench I got results that match theTruth table in the 74HC193 data sheet. What do you think? The only problemis that although I am declaring an integer with a range, when the integer (cnt) is exceeding the maximum upper limit 255, the simulation stops instead of resetting the this integer (cnt) automatically. Do I have to take careof resetting it my self in the vhdl code?
--counter_test.vhd
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity counter_test is
end Entity counter_test;
Architecture behavioral of counter_test is
Signal dir, cnt_en, clk, TCU, TCD : std_logic := '0';
Signal Reset, load : std_logic := '1';
signal p, qd : integer range 0 to 255 ;
Signal Endsim : std_logic := '0';
Signal cnt_in, cnt_out : std_logic_vector (7 downto 0) := (others => '0');
begin
UUT : entity work.counter
port map ( clk => clk,
Reset => Reset,
load => load,
p => p,
dir => dir,
qd => qd,
TCU => TCU,
TCD => TCD,
cnt_en => cnt_en,
cnt_in => cnt_in,
cnt_out => cnt_out);
CLK_process
begin
if(EndSim = '0') then
clk <= NOT clk;
wait for 2ns;
else wait;
end if;
end process;
Signals : process
Begin
wait for 0.5 ns;
Reset <= '1';
dir <= '1';
cnt_en <= '1';
load <= '0';
wait for 1020ns;
cnt_en <= '0';
wait for 50ns;
cnt_en <= '1';
dir <= '0';
wait for 1020ns;
cnt_en <= '0';
wait for 50ns;
load <= '1';
p <= 100;
wait for 4ns;
load <= '0';
cnt_en <= '1';
wait for 200ns;
Reset <= '0';
wait for 100ns;
EndSim <= '1';
wait;
end process;
end Architecture behavioral;