library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.Utils.all;

entity tb_a_padder_test is
generic 
(
	constant Nb: integer := 16;
    constant P_VAL: integer := 41
);
end tb_a_padder_test;

architecture Behavioral of tb_a_padder_test is

-----------------------------------------------------------------------
-- Timing constants
-----------------------------------------------------------------------
constant CLOCK_PERIOD : time := 2 ns; -- 500Mhz Clock
constant T_HOLD       : time := 200 ps;
constant T_STROBE     : time := CLOCK_PERIOD - (20 ps);

signal clk, Rst_n: std_logic;

constant MEMORY_ROW_COUNT: integer := div_ceil(P_VAL, Nb);
constant MEMORY_ROW_COUNT_LOG2: integer := my_log2(MEMORY_ROW_COUNT);

-- This memory contains the position of the bit to 1.
type bit_pos_mem is array(0 to MEMORY_ROW_COUNT-1) of std_logic_vector(0 to Nb-1);

signal bit_mem: bit_pos_mem := (
--    "01"&"00"&"11"&"11",
--    "01"&"10"&"00"&"00"
      "11010000"&"11001100",
      "10101111"&"00110011",
      "11110100"&"10000000"
);

signal dut_mem_en:   std_logic := '0'; -- Enable signal for the memory
signal dut_mem_data: std_logic_vector(Nb-1 downto 0) := (others => '0');
signal dut_mem_adr:  std_logic_vector(MEMORY_ROW_COUNT_LOG2-1 downto 0) := (others => '0');



signal dut_out: std_logic := '0';
signal dut_out_last: std_logic := '0';
signal dut_start, dut_start2, dut_done: std_logic := '0';
signal dut_out_valid: std_logic := '0';

begin

-- Generate the Reset signal
process
begin  -- process
    --- Wait untile the sample memory is not loaded.
--    wait until done_read_samples='1';

	Rst_n <= '0';
    wait for 3*CLOCK_PERIOD/2;
	Rst_n <= '1';
    wait;
end process;

clock_gen : process
begin
    clk <= '0';
    wait for CLOCK_PERIOD;
    loop
        clk <= '0';
        wait for CLOCK_PERIOD/2;
        clk <= '1';
        wait for CLOCK_PERIOD/2;
    end loop;
end process clock_gen;

dut_start2 <= '1' after 300 ns, '0' after 500 ns;    
dut_start <= dut_start2 and not dut_done;

APadder_Comp: entity work.APadder 
    generic map (Nb => Nb, P_VAL => P_VAL) 
    port map (
        clk => clk, Rst_n => Rst_n,
        start_in  => dut_start,
        out_bin   => dut_out,
        out_last  => dut_out_last,
        out_stop  => '0',
        out_valid => dut_out_valid,
        done => dut_done,
        
        mem_in_en => dut_mem_en,
        mem_in_adr => dut_mem_adr,
        mem_in_data => dut_mem_data
);
       
MEM_ROM: process (Rst_n, Clk, dut_mem_en, dut_mem_adr)
begin
   if Rst_n='0' then
     dut_mem_data <= (others => '0');
   else --if rising_edge(Clk) then
     dut_mem_data <= (others => '0');
     if dut_mem_en = '1' then
         dut_mem_data <= bit_mem(to_integer(unsigned(dut_mem_adr)));
     end if;
   end if;
end process;       
       
end Behavioral;
