在VHDL中,是否可以在FOR循环中使用i,j以外的变量进行合成?

时间:2018-11-08 09:08:46

标签: for-loop vhdl synthesis

我是VHDL的新生,并且正在独自学习。

作为一种实践,我正在对320 * 240图形数据进行数据处理(计算空间平均数据)。 我正在考虑这样的方式: 1.创建一个10 * 10的均质简单元素簇,其中每个元素计算单个像素的平均值。 2.每次将图形数据的一部分连接到10 * 10群集,进行计算然后更改连接。并且经过32 * 24次操作后,工作完成了。

但是我在步骤2中遇到了综合问题。为了动态更改连接,我必须在FOR语句中使用i,j以外的变量。但是对于这种使用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;

0 个答案:

没有答案