В VHDL можно ли использовать переменные, отличные от i, j, в циклах FOR? - PullRequest
0 голосов
/ 08 ноября 2018

Я новичок в VHDL и изучаю его сам.

На практике я выполняю обработку данных (вычисление средних пространственных данных) для графических данных 320 * 240. Я рассматриваю способ, как это: 1. Создайте кластер из 10 * 10 однородных простых элементов, где каждый элемент вычисляет среднее значение одного пикселя. 2. Каждый раз подключайте одну часть графических данных к кластеру 10 * 10, выполняйте расчеты, затем меняйте соединение. И после 32 * 24 раз работы, работа закончена.

Но я получил синтезирующую проблему на шаге 2. Чтобы динамически изменять соединения, я должен использовать переменные, отличные от i, j, в операторе FOR. Но, похоже, это невозможно синтезировать для этой схемы использования цикла FOR (время синтеза не ограничено).

Кто-нибудь мне поможет?

Проблемный сегмент кода выглядит следующим образом:

FSM1: process(clk) is
variable cnt1 : integer range 0 to 5 := 0;
variable cnt2 : integer range 0 to 32-1 := 0;
variable cnt3 : integer range 0 to 24-1 := 0;
variable BlockBaseX : integer range 0 to 310 := 0;
variable BlockBaseY : integer range 0 to 230 := 0;
variable varPRLLc_ave_indata : std_logic_vector(400*8-1 downto 0) :=(others=>'0');
begin
if rising_edge(clk) then
    PRLLc_ave_indata <= varPRLLc_ave_indata;
    if stateFSM2A = s3 then
        case stateFSM1 is
            when s1 =>
                if do_InitCopy = '1' then
                    workGD <= baseGD;
                end if;
                stateFSM1 <= s2;
            when s2 =>
                if do_NumProc = '1' then

                    case cnt1 is
                        when 0 =>
                            BlockBaseX := cnt2*10; -- 10, 20, ..., 310
                            BlockBaseY := cnt3*10; -- 10, 20, ..., 230

                            for i in 0 to 9 loop
                                for j in 0 to 9 loop  -- PRLLc_ave_indata (400*8-1 downto 0);
                                    if i = 9 then
                                        if j = 9 then
                                            varPRLLc_ave_indata((i*10+j)*32+31 downto (i*10+j)*32) := workGD(BlockBaseY+i, BlockBaseX+j) & workGD(BlockBaseY+i, BlockBaseX+j-1) & workGD(BlockBaseY+i-1, BlockBaseX+j) & workGD(BlockBaseY+i-1, BlockBaseX+j-1);
                                        else
                                            varPRLLc_ave_indata((i*10+j)*32+31 downto (i*10+j)*32) := workGD(BlockBaseY+i, BlockBaseX+j) & workGD(BlockBaseY+i, BlockBaseX+j+1) & workGD(BlockBaseY+i-1, BlockBaseX+j) & workGD(BlockBaseY+i-1, BlockBaseX+j+1);
                                        end if;                                         
                                    else
                                        if j = 9 then
                                            varPRLLc_ave_indata((i*10+j)*32+31 downto (i*10+j)*32) := workGD(BlockBaseY+i, BlockBaseX+j) & workGD(BlockBaseY+i, BlockBaseX+j-1) & workGD(BlockBaseY+i+1, BlockBaseX+j) & workGD(BlockBaseY+i+1, BlockBaseX+j-1);                                            
                                        else
                                            varPRLLc_ave_indata((i*10+j)*32+31 downto (i*10+j)*32) := workGD(BlockBaseY+i, BlockBaseX+j) & workGD(BlockBaseY+i, BlockBaseX+j+1) & workGD(BlockBaseY+i+1, BlockBaseX+j) & workGD(BlockBaseY+i+1, BlockBaseX+j+1);                                            
                                        end if;
                                    end if;
                                end loop;
                            end loop;
-- If the above For loop is replaced with the following one(BlockBaseX,BlockBaseY are removed), the synthesis can be accomplished. 
--                              for i in 0 to 9 loop
--                                  for j in 0 to 9 loop  -- PRLLc_ave_indata (400*8-1 downto 0);
--                                      if i = 9 then
--                                          if j = 9 then
--                                              varPRLLc_ave_indata((i*10+j)*32+31 downto (i*10+j)*32) := workGD(i, j) & workGD(i, j-1) & workGD(i-1, j) & workGD(i-1, j-1);
--                                          else
--                                              varPRLLc_ave_indata((i*10+j)*32+31 downto (i*10+j)*32) := workGD(i, j) & workGD(i, j+1) & workGD(i-1, j) & workGD(i-1, j+1);
--                                          end if;                                         
--                                      else
--                                          if j = 9 then
--                                              varPRLLc_ave_indata((i*10+j)*32+31 downto (i*10+j)*32) := workGD(i, j) & workGD(i, j-1) & workGD(i+1, j) & workGD(i+1, j-1);                                            
--                                          else
--                                              varPRLLc_ave_indata((i*10+j)*32+31 downto (i*10+j)*32) := workGD(i, j) & workGD(i, j+1) & workGD(i+1, j) & workGD(i+1, j+1);                                            
--                                          end if;
--                                      end if;
--                                  end loop;
--                              end loop;                               

                        when 1 =>
                        when 2 =>
                        when 3 => -- got answer

                        when 4 =>
                        when others =>

                    end case;

                    if cnt1 < 5 then
                        cnt1 := cnt1 + 1;
                    else
                        cnt1 := 0;

                        if cnt2 < 32 then
                            cnt2 := cnt2 + 1;
                        else
                            cnt2 := 0;
                            if cnt3 < 24 then
                                cnt3 := cnt3 + 1;
                            else
                                cnt3 := 0;
                                stateFSM1 <= s3;

                            end if;                                         

                        end if;

                    end if;



                else

                end if;
            when s3 => -- after detecting a signal indicating OV7670 module has come to the requested point,
                          -- launch the pump out function - pump data from WorkGD to a stream
            when others =>

        end case;

    else
        stateFSM1 <= s1;
    end if;
end if;
end process FSM1;
...