The objective of the project is to create a simple 4 bit counter. However I want to step through the count sequence using the push to break switches. The top level VHDL is made up of three main components as shown below:
library ieee;
use ieee.std_logic_1164.all;
entity StartStopCounter is
port(start: in std_logic; -- E1
stop: in std_logic; --J15
clk_50mhz: in std_logic; --R8
Led0: out std_logic; --A15
Led1: out std_logic; --A13
Led2: out std_logic; --B13
Led3: out std_logic; --A11
Led7 : out std_logic; --L3
Led6 : out std_logic); --B1
end StartStopCounter;
architecture arch_startStopCounter of startStopCounter is
component SetResetLatch is
port(nSet: in std_logic;
nReset: in std_logic;
clk_50mhz: in std_logic;
Q: out std_logic);
end component;
Component BinaryCounter is
generic (n: integer :=4);
port(nReset: in std_logic;
Enable: in std_logic;
clk_50mhz: in std_logic;
Q: out std_logic_vector((n-1) downto 0));
end component;
Component ChangeDetect is
port(
Clk: in std_logic;
Input:in std_logic;
Change: out std_logic
);
end component;
signal Counter_out: std_logic_vector(3 downto 0);
signal SwitchLatch: std_logic;
signal ChangeEnb: std_logic;
begin
led7 <= not start;
led6 <= not stop;
PushToBreak: SetResetLatch port map(Start, Stop, Clk_50mhz, SwitchLatch);
pulse: ChangeDetect port map(Clk_50mhz, SwitchLatch, ChangeEnb);
Counter: BinaryCounter port map ('1',ChangeEnb, Clk_50mhz, Counter_out);
Led0 <= Counter_out(0);
Led1 <= Counter_out(1);
Led2 <= Counter_out(2);
Led3 <= Counter_out(3);
end arch_startStopCounter;
The two push to break switches are connected to a VHDL component called SetResetLatch. The purpose of this component is to latch high when PB1 is pushed and latch low when PB2 is pushed. Pushing PB1 followed by PB2 will create the enable on the counter. The VHDL for SetResetLatch is shown below:
library ieee;
use ieee.std_logic_1164.all;
entity SetResetLatch is
port(nSet: in std_logic;
nReset: in std_logic;
clk_50mhz: in std_logic;
Q: out std_logic);
end SetResetLatch;
architecture arch_SetResetLatch of SetResetLatch is
begin
process(clk_50mhz)
begin
if rising_edge(clk_50mhz) then
if(nSet = '0') then
Q <= '1';
elsif (nReset ='0') then
Q <= '0';
end if; end if; end process;
end arch_SetResetLatch;
However the aim is to increment the counter one for each push of the buttons. Therefore we cannot feed the enable of the counter directly from output of SetResetLatch . We only want to increment the counter when SetResetLatch changes from low to high. This is achieved by the edge detection component ChangeDetect the VHDL of which is shown below.
library ieee;
use ieee.std_logic_1164.all;
entity ChangeDetect is
port(
Clk: in std_logic;
Input:in std_logic;
Change: out std_logic
);
end entity;
architecture ChangeDetect_Arc of changeDetect is
signal dout: std_logic;
begin
process(clk)
begin
if rising_edge(clk) then
dout <= Input;
end if;
end process;
Change <= input and not dout;
end changeDetect_Arc;
The final step is to feed the output from change detect into the enable of the counter as shown below:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity BinaryCounter is
generic (n: integer :=4);
port(nReset: in std_logic;
Enable: in std_logic;
clk_50mhz: in std_logic;
Q: out std_logic_vector((n-1) downto 0));
end BinaryCounter;
architecture arch_BinaryCounter of BinaryCounter is
begin
process(clk_50mhz, nReset)
variable count: unsigned ((n-1) downto 0);
begin
if nReset = '0' then
count := (others => '0');
elsif rising_edge(clk_50mhz) and Enable ='1' then
count := count + 1;
end if;
Q <= std_logic_vector(count);
end process;
end arch_BinaryCounter;
No comments:
Post a Comment