--- Sample Code for LSU EE 4702-1 Spring 2001 --- --- Population Modules and Testbench --- -- Note: synthesizablity not tested. --- Utility functions. library ieee; use ieee.std_logic_1164.all; package mystuff is function "srl" (a:std_logic_vector; n:natural) return std_logic_vector; function "srl" (a:integer; n:natural) return integer; end mystuff; package body mystuff is function "srl" (a:std_logic_vector; n:natural) return std_logic_vector is variable b: std_logic_vector ( a'range ); begin b := ( others => '0' ); b( b'high - n downto b'low ) := a( a'high downto a'low + n ); return b; end; function "srl" (a:integer; n:natural) return integer is variable p:integer; begin if a >= 0 then return a / 2 ** n; else p:= (-a) / 2 ** n; if p > 0 then p:= p - 1; end if; return integer'high / 2 ** (n-1) - p; end if; end; end mystuff; --- Combinational Population Counter library ieee; use ieee.std_logic_1164.all; library Std_DevelopersKit; use Std_DevelopersKit.Std_Regpak.all; library work; use work.mystuff.all; entity popsc is port( pop:out std_logic_vector (3 downto 0); a: in std_logic_vector (7 downto 0)); end entity popsc; architecture form1 of popsc is begin process(a) variable pop_work: std_logic_vector ( pop'range ); variable a_work: std_logic_vector ( a'range ); begin pop_work := ( others => '0' ); a_work := a; for i in a'range loop pop_work := pop_work + a_work(0); a_work := a_work srl 1; end loop; pop <= pop_work; end process; end form1; --- Sequential Population Counters library ieee; use ieee.std_logic_1164.all; library Std_DevelopersKit; use Std_DevelopersKit.Std_Regpak.all; library work; use work.mystuff.all; entity pops is port( pop:out std_logic_vector (3 downto 0); rdy:out std_logic; a: in std_logic_vector (7 downto 0); clk:in std_logic); end entity pops; architecture form3 of pops is begin process variable pop_work: std_logic_vector ( pop'range ); variable a_work, a_copy: std_logic_vector ( a'range ) := ( others => '0' ); begin wait until rising_edge(clk); if a_copy /= a then wait until rising_edge(clk); rdy <= '0'; pop_work := to_stdlogicvector(0,pop'length); a_work := a; a_copy := a; wait until rising_edge(clk); while a_work /= 0 loop wait until rising_edge(clk); pop_work := pop_work + a_work(0); a_work := a_work srl 1; end loop; pop <= pop_work; wait until rising_edge(clk); end if; if a_copy = a then rdy <= '1'; else rdy <= '0'; end if; end process; end form3; library ieee; use ieee.std_logic_1164.all; library Std_DevelopersKit; use Std_DevelopersKit.Std_Regpak.all; use Std_DevelopersKit.Std_IOpak.all; library work; use work.mystuff.all; entity poptb is end; architecture a of poptb is signal clk:std_logic:= '0'; signal rdy:std_logic; signal pout,pout2:std_logic_vector (3 downto 0); signal num:std_logic_vector (7 downto 0) := ( others => '0' ); function pop(a : integer) return integer is variable p: integer := 0; variable b: integer := a; begin while b /= 0 loop p := p + b mod 2; b := b srl 1; end loop; return p; end; begin pop1:entity work.pops(form3) port map(pout,rdy,num,clk); pop2:entity work.popsc(form1) port map(pout2,num); clk <= not clk after 2 ns; process variable check: integer := 0; begin num <= to_stdlogicvector(1,num'length); wait until rdy = '0'; wait until rdy = '1'; for i in 0 to 255 loop num <= to_stdlogicvector(i,num'length); if num /= i then wait until rdy = '0'; end if; wait until rdy = '1'; assert '0' & pout = pop(i) report "Seq wrong value i " & to_string(i) & " pop: " & to_string(pout) severity failure; assert '0' & pout2 = pop(i) report "Cmb wrong value i " & to_string(i) & " pop: " & to_string(pout2) severity failure; check := check + to_integer( '0' & pout ); end loop; assert check = 256 * 4 report "Incorrect check."; assert false report "Done with tests." severity failure; end process; end a;