-- $Source: /evtfs/home/tres/vhdl/ref_design/RCS/count_enable.vhd,v $ -- $Revision: 1.2 $ -- Synthesis Template Example: -- A counts every clock, B counts when A rolls, C counts when B rolls -- Mike Treseler Thu May 25 12:07:53 2006 ------------------------------------------------------------------------------- -- See end of this file for the Process Template -- See http://home.comcast.net/~mike_treseler/count_enable.vhd for this file. -- See http://home.comcast.net/~mike_treseler/count_enable.pdf to see netlist ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; ------------------------------------------------------------------------------- entity count_enable is generic (small_c : positive := 5; big_c : positive := 14 ); port ( clock : in std_ulogic; reset : in std_ulogic; q_a : out std_logic_vector(small_c-1 downto 0); q_b : out std_logic_vector(small_c-1 downto 0); q_c : out std_logic_vector(big_c -1 downto 0) ); end entity count_enable; ------------------------------------------------------------------------------- architecture synth of count_enable is -- no signals required begin count_enable : process(reset, clock) is ------------------------------------------------------------------------------- -- Process declarations for the Template Procedures ------------------------------------------------------------------------------- subtype vec_small_t is unsigned(small_c downto 0); -- msb is carry constant zero_small_c : vec_small_t := (others => '0'); subtype vec_big_t is unsigned(q_c'range); -- no carry needed constant zero_big_c : vec_big_t := (others => '0'); -- Instance counter registers: variable a_v : vec_small_t ; variable b_v : vec_small_t ; variable c_v : vec_big_t ; ------------------------------------------------------------------------------- -- Template Procedures: Always same three names. Contents varies. ------------------------------------------------------------------------------- procedure init_regs is -- init of register variables only begin a_v := zero_small_c; b_v := zero_small_c; c_v := zero_big_c; end procedure init_regs; ------------------------------------------------------------------------------- procedure update_regs is -- distilled functional description -- a counts every clock, b counts when a rolls, c counts when b rolls begin a:a_v := a_v + 1; -- fast count b:if a_v(a_v'left) = '1' then -- a carry? a_v(a_v'left) := '0'; -- clear carry b_v := b_v + 1; c:if b_v(b_v'left) = '1' then -- b carry? b_v(b_v'left) := '0'; -- clear carry c_v := c_v + 1; -- slow count, unsigned rolls over, no carry end if c; end if b; end procedure update_regs; -------------------------------------------------------------------------------- procedure update_ports is -- wire register variables out to port begin q_a <= std_logic_vector(a_v(q_a'range)); -- strip carry q_b <= std_logic_vector(b_v(q_b'range)); -- strip carry q_c <= std_logic_vector(c_v); end procedure update_ports; ------------------------------------------------------------------------------- -- Process Template -- Always exactly the same: ------------------------------------------------------------------------------- begin -- process template if reset = '1' then -- Assumes synched trailing edge reset init_regs; -- reg_v := init_c; No port init required elsif rising_edge(clock) then update_regs; -- reg_v := f(reg_v); no port update need here end if; -- Synchronous init optional (state_v = idle_c) update_ports; -- out_port <= reg_v; end process count_enable; -- will infer port wires ok for reset or clock end architecture synth; -------------------------------------------------------------------------------