-- Universal Register -- This design is a universal register which can be used as a straightforward storage register, a bi-directional shift register, an up counter and a down counter. -- The register can be loaded from a set of parallel data inputs and the mode is controlled by a 3-bit input. -- The 'termcnt' (terminal count) output goes high when the register contains zero. -- download from: www.fpga.com.cn & www.pld.com.cn LIBRARY ieee; USE ieee.Std_logic_1164.ALL; USE ieee.Std_logic_unsigned.ALL; ENTITY unicntr IS GENERIC(n : Positive := 8); --size of counter/shifter PORT(clock, serinl, serinr : IN Std_logic; --serial inputs mode : IN Std_logic_vector(2 DOWNTO 0); --mode control datain : IN Std_logic_vector((n-1) DOWNTO 0); --parallel inputs dataout : OUT Std_logic_vector((n-1) DOWNTO 0); --parallel outputs termcnt : OUT Std_logic); --terminal count output END unicntr; ARCHITECTURE v1 OF unicntr IS SIGNAL int_reg : Std_logic_vector((n-1) DOWNTO 0); BEGIN main_proc : PROCESS BEGIN WAIT UNTIL rising_edge(clock); CASE mode IS --reset WHEN "000" => int_reg <= (OTHERS => '0'); --parallel load WHEN "001" => int_reg <= datain; --count up WHEN "010" => int_reg <= int_reg + 1; --count down WHEN "011" => int_reg <= int_reg - 1; --shift left WHEN "100" => int_reg <= int_reg((n-2) DOWNTO 0) & serinl; --shift right WHEN "101" => int_reg <= serinr & int_reg((n-1) DOWNTO 1); --do nothing WHEN OTHERS => NULL; END CASE; END PROCESS; det_zero : PROCESS(int_reg) --detects when count is 0 BEGIN termcnt <= '1'; FOR i IN int_reg'Range LOOP IF int_reg(i) = '1' THEN termcnt <= '0'; EXIT; END IF; END LOOP; END PROCESS; --connect internal register to dataout port dataout <= int_reg; END v1;