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

library work;
use work.Utils.all;

entity tb_b_padder_test is
generic 
(
    P_VAL: integer := 11;
    D_V: integer := 6
);
end tb_b_padder_test;

architecture Behavioral of tb_b_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;

-- This memory contains the position of the bit to 1.
type bit_pos_mem is array(0 to D_V-1) of integer range 0 to P_VAL;
-- subtype bit_pos_type is unsigned(my_log2(P_VAL)-1 downto 0);

signal bit_mem: bit_pos_mem := (
    0, 1, 7, 8, 9, 10
);

signal dut_mem_en:   std_logic := '0'; -- Enable signal for the memory
signal dut_mem_adr:  std_logic_vector(my_log2(D_V)-1 downto 0) := (others => '0');
signal dut_mem_data: std_logic_vector(my_log2(P_VAL)-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;

BPadderComp: entity work.BPadder 
    generic map (D_V => D_V, 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)
    variable  bit_mem_int: integer range 0 to P_VAL := 0;
    variable  bit_mem_un: unsigned(my_log2(P_VAL)-1 downto 0) := (others => '0');
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
         bit_mem_int := bit_mem(to_integer(unsigned(dut_mem_adr)));
         bit_mem_un  := to_unsigned(bit_mem_int, bit_mem_un'length);
         dut_mem_data <= std_logic_vector(bit_mem_un);
     end if;
   end if;
end process;       
       
end Behavioral;
