Advertisement
milanmetal

Kako ukrasti jos jedan takt?

Nov 28th, 2018
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VHDL 7.87 KB | None | 0 0
  1. -- Given algorithm: Find given element's index by
  2. -- Binary Search.
  3.  
  4. -- Unmodified algorithm:
  5. -- ---------------------------
  6. -- while (left =< right)
  7. -- {
  8. --   middle = (left+right)/2;
  9. --   if x[middle] = key then
  10. --     return key;
  11. --   if x[middle] > key then
  12. --     right = middle - 1;
  13. --   if x[middle] < key then
  14. --     left = middle + 1;
  15. -- }
  16. -- return not_found;
  17.  
  18. -- Modified algorithm:
  19. -- ---------------------------
  20.  
  21. -- state: idle
  22. -- ready <= 1
  23. -- if start = 1 ...
  24. -- op: if left < right or left = right then
  25. --   -- state: new_middle
  26. --   middle = (left + right) >> 1
  27. --   if x(middle) == key_i then
  28. --     el_found_o = 1
  29. --     pos_o = middle
  30.  
  31. --     GOTO idle -- one process done, do it again.
  32. --   else
  33. --     -- state: update_lr
  34. --     if x(middle) > key_i then
  35. --       right = middle - 1
  36. --     else
  37. --       left = middle + 1
  38. --     end if;
  39. --     GOTO op
  40. --   end if;
  41.  
  42. -- else
  43. --   GOTO idle -- not_found, unsuccessfull cycle, do it again
  44. -- end if;
  45.  
  46. -- not_found:
  47. -- found:
  48.  
  49. library ieee;
  50. use ieee.std_logic_1164.all;
  51. use ieee.numeric_std.all;
  52. use work.util_pkg.all;
  53.  
  54. entity binary_search_array is
  55.   generic (
  56.     WIDTH    : integer := 8;
  57.     ARR_SIZE : integer := 30
  58.     );
  59.   port (
  60.     --------------- Clocking and reset interface ---------------
  61.     clk   : in std_logic;
  62.     reset : in std_logic;
  63.  
  64.     -- Array memory interface
  65.     addr_o : out std_logic_vector(7 downto 0);
  66.     ------------------- Output data interface -------------------
  67.     data_o : out std_logic_vector(WIDTH-1 downto 0);
  68.     ------------------- Input data interface -------------------
  69.     data_i : in  std_logic_vector(WIDTH-1 downto 0);
  70.  
  71.     -- element to look for its index
  72.     key_i : in  std_logic_vector(WIDTH-1 downto 0);
  73.     -- element's index
  74.     pos_o : out std_logic_vector(WIDTH-1 downto 0);
  75.  
  76.     left_i     : in  std_logic_vector(WIDTH-1 downto 0);
  77.     right_i    : in  std_logic_vector(WIDTH-1 downto 0);
  78.     rw_o       : out std_logic;
  79.     el_found_o : out std_logic;
  80.  
  81.     --------------------- Command interface --------------------
  82.     start : in  std_logic;
  83.     --------------------- Status interface ---------------------
  84.     ready : out std_logic
  85.     );
  86. end entity;
  87.  
  88. architecture behavioral of binary_search_array is
  89.   type state_type is (idle, op, check); --add, rdrop, ldrop);
  90.   signal state_reg, state_next : state_type;
  91.  
  92.   -- one bit more, because of left+right
  93.   signal middle_reg, middle_next : unsigned(WIDTH downto 0) := (others => '0');
  94.   signal left_reg, left_next     : unsigned(WIDTH-1 downto 0);
  95.   signal right_reg, right_next   : unsigned(WIDTH-1 downto 0);
  96.  
  97.   -- signal p1_addr_i_s : std_logic_vector(7 downto 0);
  98.   -- signal p1_data_i_s : std_logic_vector(WIDTH-1 downto 0);
  99.   -- signal p1_data_o_s : std_logic_vector(WIDTH-1 downto 0);
  100.   -- signal p1_wr_i_s   : std_logic;
  101.  
  102. begin
  103.  
  104.   -- -- Array memory
  105.   -- array_mem : entity work.dp_memory(beh)
  106.   --   generic map (
  107.   --     WIDTH => DATA_WIDTH_c,
  108.   --     SIZE  => 256
  109.   --     )
  110.   --   port map (
  111.   --     clk       => clk,
  112.   --     reset     => reset,
  113.   --     p1_addr_i => p1_addr_i_s,         --addr_o,
  114.   --     p1_data_i => p1_data_i_s,         --data_i,
  115.   --     p1_data_o => p1_data_o_s,         --data_o,
  116.   --     p1_wr_i   => p1_wr_i_s,           --rw_o,
  117.   --     p2_addr_i => (others => '0'),
  118.   --     p2_data_i => (others );
  119.  
  120.   -- MEM : process (clk) is
  121.   -- begin
  122.   --   -- write
  123.   --   if p1_wr_i_s = '1' then
  124.  
  125.   --   else
  126.  
  127.   --   end if;
  128.  
  129.   -- end process;
  130.  
  131. -- State and data registers
  132.   SEQ : process (clk, reset)
  133.   begin
  134.     if reset = '1' then
  135.       state_reg  <= idle;
  136.       left_reg   <= unsigned(left_i);
  137.       right_reg  <= unsigned(right_i);
  138.       middle_reg <= (others => '0');
  139.     elsif (clk'event and clk = '1') then
  140.       state_reg  <= state_next;
  141.       left_reg   <= left_next;
  142.       right_reg  <= right_next;
  143.       middle_reg <= middle_next;
  144.     end if;
  145.   end process;
  146.  
  147. -- Combinatorial circuits
  148.   COMB : process (state_reg, start, data_i, key_i, left_i, right_i,
  149.                   left_reg, left_next, right_reg, right_next, middle_reg, middle_next
  150.                   )
  151.   begin
  152.     -- Default assignments
  153.     el_found_o <= '0';
  154.     pos_o      <= (others => '0');
  155.     data_o     <= (others => '0');
  156.     rw_o       <= '0';                  -- read
  157.  
  158.     -- Default variable values
  159.     left_next   <= left_reg;
  160.     right_next  <= right_reg;
  161.     middle_next <= middle_reg;
  162.     ready       <= '0';
  163.  
  164.     case state_reg is
  165.       when idle =>
  166.         ready <= '1';
  167.         if start = '1' then
  168.           -- state_next <= add;
  169.           -- assign new middle element based on new left and right elements
  170.           middle_next <= resize(right_next + left_next, middle_next'length);
  171.           state_next  <= op;
  172.  
  173.         else
  174.           state_next <= idle;
  175.         end if;
  176.  
  177.       when op =>
  178.  
  179.         if left_next < right_next or left_next = right_next then
  180.           state_next <= check;
  181.           addr_o <= std_logic_vector(
  182.             to_unsigned(to_integer(unsigned(middle_reg)), addr_o'length));
  183.         else
  184.           state_next <= idle;
  185.         end if;
  186.         middle_next <= '0' & middle_reg(WIDTH downto 1);
  187.  
  188.       when check =>
  189.         -- NOTE: x(middle) comes from memory
  190.         if data_i = key_i then
  191.           el_found_o <= '1';
  192.           pos_o <= std_logic_vector(
  193.             to_unsigned(to_integer(unsigned(middle_next)), pos_o'length));
  194.           state_next <= idle;
  195.         else
  196.           if (data_i > key_i) then
  197.             -- drop right
  198.             right_next <= resize(middle_reg - 1, right_next'length);
  199.             middle_next <= resize(right_next + left_next, middle_next'length);
  200.             state_next  <= op;
  201.           else
  202.             -- drop left
  203.             left_next  <= middle_reg(WIDTH-1 downto 0) + 1;
  204.             middle_next <= resize(right_next + left_next, middle_next'length);
  205.             state_next  <= op;
  206.           end if;
  207.         end if;
  208.     end case;
  209.  
  210.     -- case state_reg is
  211.     --   when idle =>
  212.     --     middle_next <= resize(right_next + left_next, middle_next'length);
  213.     --     ready <= '1';
  214.     --     if start = '1' then
  215.     --       middle_next <= '0' & middle_reg(WIDTH downto 1);
  216.     --       -- middle_next <= resize(right_next + left_next, middle_next'length);
  217.     --       -- left_next   <= unsigned(left_i);
  218.     --       -- right_next  <= unsigned(right_i);
  219.     --       state_next  <= op;
  220.     --     else
  221.     --       state_next <= idle;
  222.     --     end if;
  223.     --   when op =>
  224.     --     -- assign new middle element based on new left and right elements
  225.     --     middle_next <= resize(right_next + left_next, middle_next'length);
  226.  
  227.     --     if left_next < right_next or left_next = right_next then
  228.     --       state_next <= shrncheck;
  229.     --       addr_o <= std_logic_vector(
  230.     --         to_unsigned(to_integer(unsigned(middle_reg)), addr_o'length));
  231.     --     else
  232.     --       state_next <= idle;
  233.     --     end if;
  234.  
  235.     --   when shrncheck =>
  236.     --     -- shift right by one place
  237.     --     middle_next <= '0' & middle_reg(WIDTH downto 1);
  238.     --     -- middle_reg <= '0' & middle_next(WIDTH downto 1);
  239.     --     -- NOTE: x(middle) comes from memory
  240.     --     if data_i = key_i then
  241.     --       el_found_o <= '1';
  242.     --       pos_o <= std_logic_vector(
  243.     --         to_unsigned(to_integer(unsigned(middle_next)), middle_next'length));
  244.     --       state_next <= idle;
  245.     --     else
  246.     --       if (data_i > key_i) then
  247.     --         state_next <= rdrop;
  248.     --       else
  249.     --         state_next <= ldrop;
  250.     --       end if;
  251.     --     end if;
  252.  
  253.   --   when rdrop =>
  254.   --     right_next <= resize(middle_reg - 1, right_next'length);
  255.   --     state_next <= op;
  256.   --   when ldrop =>
  257.   --     left_next  <= middle_reg(WIDTH-1 downto 0) + 1;
  258.   --     state_next <= op;
  259.   -- end case;
  260.   end process;
  261. end behavioral;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement