Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- 64-bit carry-save counter
- -- by Michael Frank (FAMU/FSU), 4/12/2011
- -- (placed in the public domain)
- -- This counter has been tested & verified to be capable of running as fast as
- -- a 3-stage ring oscillator, up to at least 666 MHz on an Altera/Terasic DE2 board.
- -- Note the time scales as O(1), so the counter can be made any size without penalty.
- library ieee;
- use ieee.std_logic_1164.all;
- entity csc_64b is
- port (
- clk: in std_logic; -- Fast clock
- cs_count: out std_logic_vector(63 downto 0); -- Value of carry-save counter. Bit N changes N cycles later than in a normal counter.
- cs_carry: out std_logic_vector(64 downto 1) -- Migrating carry bits. Can be added to cs_count to recover binary counter value.
- );
- end entity;
- architecture impl of csc_64b is
- -- We do some "manual" buffering of the clock to head off possible fanout delay problems in the
- -- clock distribution (not counting on synthesis tool to be smart enough to do that automatically).
- signal clock_copies: std_logic_vector(0 to 7); -- Eight (inverted) copies of the input clock.
- -- NOTE: Each byte-sized chunk of the state machine will use the same copy of the clock,
- -- which reduces the chance of skew problems.
- -- The following prevents the synthesis tool from optimizing away all the copies of the clock.
- attribute keep: boolean;
- attribute keep of clock_copies: signal is true;
- -- Registers to store the sum and carry bits separately.
- signal sum: std_logic_vector(63 downto 0) := x"0000000000000000";
- signal carry: std_logic_vector(64 downto 1) := x"0000000000000000";
- begin
- cs_count <= sum; -- Output the current values of sum and carry registers.
- cs_carry <= carry;
- -- This "process" really just combinationally generates the 8 inverted copies of the clock.
- -- (At 7 lines of code, we could equally well have just made 8 copies of the loop body.)
- process (clk) is
- variable clk_i: integer range 0 to 7;
- begin
- for clk_i in 0 to 7 loop
- clock_copies(clk_i) <= not clk;
- end loop;
- end process;
- -- The following eight processes are really (except for a boundary case in the first process)
- -- the exactly same process repeated eight times, but just using different copies of the clock.
- -- There is probably a more elegant way to do this, by using some kind of array instantiation of
- -- a sub-entity, or some kind of process template, but at the moment I'm trying to hurry and
- -- didn't want to stop to figure out that syntax.
- bits_7to0: process is -- byte 0 of 8
- variable bit_i: integer range 0 to 7;
- begin
- wait until rising_edge(clock_copies(0));
- -- Special case for least significant bit.
- -- Carry out is just the previous value of the low-order sum bit,
- -- and the low-order sum bit just gets toggled on each cycle.
- sum(0) <= not sum(0);
- carry(1) <= sum(0); -- Note this gets old not new value of sum(0) b/c we're using signal assignment
- for bit_i in 1 to 7 loop
- sum(bit_i) <= sum(bit_i) xor carry(bit_i); -- Uses old not new value of carry (signal assignment).
- carry(bit_i+1) <= sum(bit_i) and carry(bit_i); -- Uses old not new value of sum/carry (signal assignment).
- end loop;
- end process;
- bits_15to8: process is -- byte 1 of 8
- variable bit_i: integer range 8 to 15;
- begin
- wait until rising_edge(clock_copies(1));
- for bit_i in 8 to 15 loop
- sum(bit_i) <= sum(bit_i) xor carry(bit_i); -- Uses old not new value of carry (signal assignment).
- carry(bit_i+1) <= sum(bit_i) and carry(bit_i); -- Uses old not new value of sum/carry (signal assignment).
- end loop;
- end process;
- bits_23to16: process is -- byte 2 of 8
- variable bit_i: integer range 16 to 23;
- begin
- wait until rising_edge(clock_copies(2));
- for bit_i in 16 to 23 loop
- sum(bit_i) <= sum(bit_i) xor carry(bit_i); -- Uses old not new value of carry (signal assignment).
- carry(bit_i+1) <= sum(bit_i) and carry(bit_i); -- Uses old not new value of sum/carry (signal assignment).
- end loop;
- end process;
- bits_31to24: process is -- byte 3 of 8
- variable bit_i: integer range 24 to 31;
- begin
- wait until rising_edge(clock_copies(3));
- for bit_i in 24 to 31 loop
- sum(bit_i) <= sum(bit_i) xor carry(bit_i); -- Uses old not new value of carry (signal assignment).
- carry(bit_i+1) <= sum(bit_i) and carry(bit_i); -- Uses old not new value of sum/carry (signal assignment).
- end loop;
- end process;
- bits_39to32: process is -- byte 4 of 8
- variable bit_i: integer range 32 to 39;
- begin
- wait until rising_edge(clock_copies(4));
- for bit_i in 32 to 39 loop
- sum(bit_i) <= sum(bit_i) xor carry(bit_i); -- Uses old not new value of carry (signal assignment).
- carry(bit_i+1) <= sum(bit_i) and carry(bit_i); -- Uses old not new value of sum/carry (signal assignment).
- end loop;
- end process;
- bits_47to40: process is -- byte 5 of 8
- variable bit_i: integer range 40 to 47;
- begin
- wait until rising_edge(clock_copies(5));
- for bit_i in 40 to 47 loop
- sum(bit_i) <= sum(bit_i) xor carry(bit_i); -- Uses old not new value of carry (signal assignment).
- carry(bit_i+1) <= sum(bit_i) and carry(bit_i); -- Uses old not new value of sum/carry (signal assignment).
- end loop;
- end process;
- bits_55to48: process is -- byte 6 of 8
- variable bit_i: integer range 48 to 55;
- begin
- wait until rising_edge(clock_copies(6));
- for bit_i in 48 to 55 loop
- sum(bit_i) <= sum(bit_i) xor carry(bit_i); -- Uses old not new value of carry (signal assignment).
- carry(bit_i+1) <= sum(bit_i) and carry(bit_i); -- Uses old not new value of sum/carry (signal assignment).
- end loop;
- end process;
- bits_63to56: process is -- byte 7 of 8
- variable bit_i: integer range 0 to 63;
- begin
- wait until rising_edge(clock_copies(7));
- for bit_i in 56 to 63 loop
- sum(bit_i) <= sum(bit_i) xor carry(bit_i); -- Uses old not new value of carry (signal assignment).
- carry(bit_i+1) <= sum(bit_i) and carry(bit_i); -- Uses old not new value of sum/carry (signal assignment).
- end loop;
- end process;
- end architecture;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement