Advertisement
mikepfrank

Fast 64-bit Carry-Save Counter

Apr 11th, 2011
251
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 6.13 KB | None | 0 0
  1.     -- 64-bit carry-save counter
  2.     -- by Michael Frank (FAMU/FSU), 4/12/2011
  3.     -- (placed in the public domain)
  4.    
  5.     -- This counter has been tested & verified to be capable of running as fast as
  6.     -- a 3-stage ring oscillator, up to at least 666 MHz on an Altera/Terasic DE2 board.
  7.     -- Note the time scales as O(1), so the counter can be made any size without penalty.
  8.  
  9. library ieee;
  10.     use ieee.std_logic_1164.all;
  11.    
  12. entity csc_64b is
  13.     port (
  14.         clk: in std_logic;                                      -- Fast clock
  15.         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.
  16.         cs_carry: out std_logic_vector(64 downto 1)     -- Migrating carry bits.  Can be added to cs_count to recover binary counter value.
  17.     );
  18. end entity;
  19.  
  20. architecture impl of csc_64b is
  21.  
  22.         -- We do some "manual" buffering of the clock to head off possible fanout delay problems in the
  23.         -- clock distribution (not counting on synthesis tool to be smart enough to do that automatically).
  24.        
  25.     signal clock_copies: std_logic_vector(0 to 7);      -- Eight (inverted) copies of the input clock.
  26.         -- NOTE: Each byte-sized chunk of the state machine will use the same copy of the clock,
  27.         -- which reduces the chance of skew problems.
  28.        
  29.         -- The following prevents the synthesis tool from optimizing away all the copies of the clock.
  30.        
  31.     attribute keep: boolean;
  32.     attribute keep of clock_copies: signal is true;
  33.    
  34.         -- Registers to store the sum and carry bits separately.
  35.        
  36.     signal sum: std_logic_vector(63 downto 0)   := x"0000000000000000";
  37.     signal carry: std_logic_vector(64 downto 1) := x"0000000000000000";
  38.    
  39. begin
  40.  
  41.     cs_count <= sum;        -- Output the current values of sum and carry registers.
  42.     cs_carry <= carry;
  43.  
  44.         -- This "process" really just combinationally generates the 8 inverted copies of the clock.
  45.         -- (At 7 lines of code, we could equally well have just made 8 copies of the loop body.)
  46.        
  47.     process (clk) is
  48.         variable clk_i: integer range 0 to 7;
  49.     begin
  50.         for clk_i in 0 to 7 loop
  51.             clock_copies(clk_i) <= not clk;
  52.         end loop;
  53.     end process;
  54.    
  55.         -- The following eight processes are really (except for a boundary case in the first process)
  56.         -- the exactly same process repeated eight times, but just using different copies of the clock.
  57.         -- There is probably a more elegant way to do this, by using some kind of array instantiation of
  58.         -- a sub-entity, or some kind of process template, but at the moment I'm trying to hurry and
  59.         -- didn't want to stop to figure out that syntax.
  60.        
  61.     bits_7to0: process is                                   -- byte 0 of 8
  62.         variable bit_i: integer range 0 to 7;
  63.     begin
  64.         wait until rising_edge(clock_copies(0));
  65.        
  66.             -- Special case for least significant bit.
  67.             -- Carry out is just the previous value of the low-order sum bit,
  68.             -- and the low-order sum bit just gets toggled on each cycle.
  69.        
  70.         sum(0) <= not sum(0);
  71.         carry(1) <= sum(0);     -- Note this gets old not new value of sum(0) b/c we're using signal assignment
  72.        
  73.         for bit_i in 1 to 7 loop
  74.             sum(bit_i) <= sum(bit_i) xor carry(bit_i);      -- Uses old not new value of carry (signal assignment).
  75.             carry(bit_i+1) <= sum(bit_i) and carry(bit_i);      -- Uses old not new value of sum/carry (signal assignment).
  76.         end loop;
  77.        
  78.     end process;
  79.  
  80.     bits_15to8: process is                                  -- byte 1 of 8
  81.         variable bit_i: integer range 8 to 15;
  82.     begin
  83.         wait until rising_edge(clock_copies(1));
  84.         for bit_i in 8 to 15 loop
  85.             sum(bit_i) <= sum(bit_i) xor carry(bit_i);      -- Uses old not new value of carry (signal assignment).
  86.             carry(bit_i+1) <= sum(bit_i) and carry(bit_i);      -- Uses old not new value of sum/carry (signal assignment).
  87.         end loop;
  88.     end process;
  89.  
  90.     bits_23to16: process is                                 -- byte 2 of 8
  91.         variable bit_i: integer range 16 to 23;
  92.     begin
  93.         wait until rising_edge(clock_copies(2));
  94.         for bit_i in 16 to 23 loop
  95.             sum(bit_i) <= sum(bit_i) xor carry(bit_i);      -- Uses old not new value of carry (signal assignment).
  96.             carry(bit_i+1) <= sum(bit_i) and carry(bit_i);      -- Uses old not new value of sum/carry (signal assignment).
  97.         end loop;
  98.     end process;
  99.  
  100.     bits_31to24: process is                                 -- byte 3 of 8
  101.         variable bit_i: integer range 24 to 31;
  102.     begin
  103.         wait until rising_edge(clock_copies(3));
  104.         for bit_i in 24 to 31 loop
  105.             sum(bit_i) <= sum(bit_i) xor carry(bit_i);      -- Uses old not new value of carry (signal assignment).
  106.             carry(bit_i+1) <= sum(bit_i) and carry(bit_i);      -- Uses old not new value of sum/carry (signal assignment).
  107.         end loop;
  108.     end process;
  109.  
  110.     bits_39to32: process is                                 -- byte 4 of 8
  111.         variable bit_i: integer range 32 to 39;
  112.     begin
  113.         wait until rising_edge(clock_copies(4));
  114.         for bit_i in 32 to 39 loop
  115.             sum(bit_i) <= sum(bit_i) xor carry(bit_i);      -- Uses old not new value of carry (signal assignment).
  116.             carry(bit_i+1) <= sum(bit_i) and carry(bit_i);      -- Uses old not new value of sum/carry (signal assignment).
  117.         end loop;
  118.     end process;
  119.    
  120.     bits_47to40: process is                                 -- byte 5 of 8
  121.         variable bit_i: integer range 40 to 47;
  122.     begin
  123.         wait until rising_edge(clock_copies(5));
  124.         for bit_i in 40 to 47 loop
  125.             sum(bit_i) <= sum(bit_i) xor carry(bit_i);      -- Uses old not new value of carry (signal assignment).
  126.             carry(bit_i+1) <= sum(bit_i) and carry(bit_i);      -- Uses old not new value of sum/carry (signal assignment).
  127.         end loop;
  128.     end process;
  129.  
  130.     bits_55to48: process is                                 -- byte 6 of 8
  131.         variable bit_i: integer range 48 to 55;
  132.     begin
  133.         wait until rising_edge(clock_copies(6));
  134.         for bit_i in 48 to 55 loop
  135.             sum(bit_i) <= sum(bit_i) xor carry(bit_i);      -- Uses old not new value of carry (signal assignment).
  136.             carry(bit_i+1) <= sum(bit_i) and carry(bit_i);      -- Uses old not new value of sum/carry (signal assignment).
  137.         end loop;
  138.     end process;
  139.    
  140.     bits_63to56: process is                                 -- byte 7 of 8
  141.         variable bit_i: integer range 0 to 63;
  142.     begin
  143.         wait until rising_edge(clock_copies(7));
  144.         for bit_i in 56 to 63 loop
  145.             sum(bit_i) <= sum(bit_i) xor carry(bit_i);      -- Uses old not new value of carry (signal assignment).
  146.             carry(bit_i+1) <= sum(bit_i) and carry(bit_i);      -- Uses old not new value of sum/carry (signal assignment).
  147.         end loop;
  148.     end process;
  149.        
  150. end architecture;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement