-- EE552 Lab#4 Carry-Save Counter -- file: cscounter.vhd -- An implementation of a Carry-Save Counter that -- makes use of a provided Carry-Save Adder. -- Uses carry-save arithmetic in a high speed adder -- whose output consists of two vectors which can be added -- together to obtain the unified (actual) sum. -- This avoids the ripple carry critical path of a normal counter. -- Output is in two binary weighted vectors which can be added to -- obtain the unified count. -- synchronous reset and data is valid on rising edge -- of clock... -- Revision 1.0 1999/10/05 -- initial revision. -- -- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library work; use work.sdram_package.all; entity cscounter is generic ( -- width of counter datawidth : positive := 12 ); port ( clock, sreset : in std_logic; -- the following is only used during testing -- count_unified : out std_logic_vector(datawidth-1 downto 0); -- Output is in two binary weighted vectors which can be added to -- obtain the unified count. -- Following two lines used if we do not exceed -- the pin count of the device. count_part1_out, count_part2_out : buffer std_logic_vector(datawidth-1 downto 0) ); end entity cscounter; -- purpose: architecture mixed of cscounter is signal one : std_logic_vector(datawidth-1 downto 0); -- leave room to concatenate a '1' with to make above vector signal zero : std_logic_vector(datawidth-2 downto 0); -- the following are internal signals used as outputs from csadder signal count_part1_int, count_part2_int : std_logic_vector(datawidth downto 0); -- internal signals which hold the present count value signal count_part1, count_part2 : std_logic_vector(datawidth-1 downto 0); begin -- structural implementation of a carry-save counter -- set a vector of variable size to have '1' as the LSB zero <= (others => '0'); one <= zero & '1'; -- used for cases that do not exceed pin count of the -- Altera EPF10K20RC240-4. count_part1_out <= count_part1; count_part2_out <= count_part2; -- the combinational csadder the_csadder : csadder generic map ( datawidth => datawidth ) port map ( adden1 => one, -- present outputs are present inputs to csadder adden2 => count_part1, adden3 => count_part2, sum_part1 => count_part1_int, sum_part2 => count_part2_int ); carry_save_counter : process (sreset, clock) begin if rising_edge(clock) then if sreset = '1' then -- clear inputs to cs adder, leaving the "one" input alone. count_part1 <= (others => '0'); count_part2 <= (others => '0'); else -- Set the output of the csadder to its inputs -- One of the outputs of the csadder is always one -- therefore this will act as a counter that is -- rising edge triggered. -- Ignore high-order bit of internal signals out of csadder count_part1 <= count_part1_int(datawidth-1 downto 0); count_part2 <= count_part2_int(datawidth-1 downto 0); end if; end if; end process carry_save_counter; -- count_unified is slower, but is only for testing purposes --count_unified <= count_part1 + count_part2; end architecture mixed;