请帮我解决以下vhdl代码中的语法错误

时间:2016-04-26 13:51:19

标签: vhdl

我使用Xlinix ISE 14.1编写以下代码。

我发现语法是正确的,但xilinx IDE在第27行和第30行显示错误。

我试图找到数字矩阵的第一个偏导数,类似于找到图像中的边缘。

函数by2i用于将字节(即位)转换为整数。

在这个VHDL代码中,我收到错误消息:

  

“错误:HDLC编译器:806 B:/gxgyVHDL.vhd”第27行:“返回”附近的语法错误。
  “错误:HDLCompiler:806 - ”B:/gxgyVHDL.vhd“第30行:”,“附近的语法错误”。

我无法纠正这些错误,因为我对VHDL知之甚少。我学习了VHDL的基本编程,如实现MUX,计数器等。

这是我第一次编写图像处理程序而且我不确定这个程序是否像预期的那样工作但它在matlab和python中运行良好。

请帮助纠正这些错误。

这是vhdl代码:

enter code here
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.numeric_std.ALL;
use IEEE.math_real.ALL;

entity getGxGy is
  generic (width : natural := 66; 
           height : natural := 130); --width and height of the image window.

Port( pxl : in STD_LOGIC_VECTOR(7 downto 0);
        clk : in bit;
         fv : out real); --need to configure 'fv' signal properly to appropriate bit vector.
end getHOGfv;

architecture behave of getGxGy is

function by2i (b : STD_LOGIC_VECTOR(7 downto 0)) return natural is
  variable num : natural;
  begin
    num := 0;
    for i in b'Range loop
      if b(i) = '1' then
        num := num + 2**i;
      end if;
    end loop
   return num
end by2i;

type bufarr is array (1 to height, 1 to width) of natural;
type gxgy is array (1 to height-2, 1 to width-2) of integer;

--signal tempfv : mat4;

process(clk, pxl)
variable buf: bufarr;
variable gx, gy: gxgy;

begin
  --Buffer to store/create 64*128 pixels/widthindowidth
  for h in 2 to height-1 loop
    for w in 2 to width-1 loop
      buf(h)(w) := by2i(pxl);
    end loop;
  end loop;

  --1pixel padding
  for w in 1 to width loop
    buf(1)(w) := 0;
  end loop;
  for w in 1 to width loop
    buf(height)(w) := 0;
  end loop;
  for h in 2 to height-1 loop
    buf(h)(1) := 0;
  end loop;
  for h in 2 to height-1 loop
    buf(h)(width) := 0;
  end loop;

  --compute gradients
  for h in 2 to height-1 loop
    for w in 2 to width-1 loop
      gx(h)(w) := buf(h+1)(w)-buf(h-1)(w);
      gy(h)(w) := buf(h)(w+1)-buf(h)(w-1);
      mag(h)(w) := abs(gx(h)(w)+gy(h)(w));
      ang(h)(w) := gy(h)(w)/gx(h)(w);
    end loop;
  end loop;

  end process;

  end behave;

2 个答案:

答案 0 :(得分:1)

几个问题:

  1. 您的实体名称不匹配。也就是说,entity getGxGyend getHOGfv;
  2. 不匹配
  3. 您在;
  4. end loop上遗漏了by2i
  5. 您在;
  6. 的回复中错过了by2i
  7. 您的体系结构中缺少begin语句(type gxgyprocess(clk, pxl)之间
  8. 您使用多维数组的语法是错误的。而不是buf(1)(w),它应该是buf(1, 2)
  9. magang都未定义。
  10. 当您遇到大量错误时,可能很难找到确切原因。通常,编译器会在报告错误时感到困惑。从第一个开始,修复它,然后重新编译。继续,直到事情清理。

    另外,澄清一点。您不需要by2i。您可以使用numeric_std进行转换(感谢scary_jeff指出这一点)。使用to_integer(unsigned(pxl))进行转换。

    还有一点。不要同时使用std_logic_unsignednumeric_stdnumeric_std是使用有符号和无符号数字的标准方法。 std_logic_unsigned是特定于供应商的扩展,不是标准扩展。

    编辑:您使用以下语法定义数组:

    type bufarr is array (1 to height, 1 to width) of natural;
    

    这很好。如上所述,您必须使用buf(h, w)语法。但是你可以用不同的方式定义它,例如:

    type width_array is array(1 to width) of natural;
    type bufarr is array(1 to height) of width_array;
    

    然后您可以使用buf(h)(w)进行索引。

    我更喜欢前者。

答案 1 :(得分:1)

除了PlayDough提到的语法项和缺失声明之外,还有两个多余的上下文子句,用于包numeric_std(不应与Synopsys算术页面std_logic_unsigned混合)和math_real(尚未使用)。

在以下编辑所有更改之后:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
-- use ieee.numeric_std.all;
-- use ieee.math_real.all;

entity getgxgy is
  generic (width : natural := 66; 
           height : natural := 130); -- width and height of the image window.

port( pxl : in std_logic_vector(7 downto 0);
        clk : in bit;
         fv : out real); -- need to configure 'fv' signal properly to appropriate bit vector.
end getgxgy;            -- WAS gethogfv;

architecture behave of getgxgy is

    function by2i (b : std_logic_vector(7 downto 0)) return natural is
        variable num : natural;
    begin
        num := 0;
        for i in b'range loop
            if b(i) = '1' then
              num := num + 2 ** i;
            end if;
        end loop;  -- MISSING ';'
       return num; -- MISSING ';'
    end function by2i;

    type bufarr is array (1 to height, 1 to width) of natural;
    type gxgy is array (1 to height - 2, 1 to width - 2) of integer;

    --signal tempfv : mat4;

begin  -- for architecture modiy WAS MISSING

    process (clk, pxl)
        variable buf: bufarr;
        variable gx, gy: gxgy;
        variable mag, ang: gxgy;  -- MISSING DECLARATIONS

    begin
      --buffer to store/create 64*128 pixels/widthindowidth
        for h in 2 to height - 1 loop
            for w in 2 to width - 1 loop
                buf(h, w) := by2i(pxl);  -- WAS  buf(h)(w)
            end loop;
        end loop;

        --1pixel padding
        for w in 1 to width loop
            buf(1, w) := 0;                -- WAS buf(1)(w)
        end loop;
        for w in 1 to width loop
            buf(height, w) := 0;           -- WAS buf(height)(w)
        end loop;
        for h in 2 to height - 1 loop
            buf(h, 1) := 0;                -- WAS buf(h)(1)
        end loop;
        for h in 2 to height - 1 loop
            buf(h, width) := 0;            -- WAS buf(h)(width)
        end loop;

    --compute gradients
        for h in 2 to height - 1 loop
            for w in 2 to width - 1 loop
                gx(h, w) := buf(h + 1, w) - buf(h - 1, w); -- WAS gx(h)(w), buf(h+1)(w) and buf(h-1)(w) 
                gy(h, w) := buf(h, w + 1) - buf(h, w - 1);  -- WAS gy(h)(w), buf(h)(w+1) and buf(h)(w-1)
                mag(h, w) := abs(gx(h, w) + gy(h, w)); -- WAS mag(h)(w), x(h)(w) and gy(h)(w)
                ang(h, w) := gy(h, w) / gx(h, w); --WAS ang(h)(w), gy(h)(w) and gx(h)(w)
            end loop;
        end loop;

    end process;

end architecture behave;

您的代码进行了分析和阐述,注意到fv没有分配,类型REAL不符合综合条件且没有合成资格使用clk

如果clk是std_logic(或std_ulogic),则可以使用std_logic_1164函数rising_edge。

为时钟边缘添加可识别的顺序逻辑RTL构造,可以得到:

    process (clk) --  pxl NOT NEEDED , pxl)
        variable buf: bufarr;
        variable gx, gy: gxgy;
        variable mag, ang: gxgy;  -- MISSING DECLARATIONS

    begin
        if clk'event and clk = '1' then
          --buffer to store/create 64*128 pixels/widthindowidth
            for h in 2 to height - 1 loop
                for w in 2 to width - 1 loop
                    buf(h, w) := conv_integer(pxl);  -- WAS  buf(h)(w)
                end loop;            -- CHANGED to use conv_integer
            end loop;

            --1pixel padding
            for w in 1 to width loop
                buf(1, w) := 0;                -- WAS buf(1)(w)
            end loop;
            for w in 1 to width loop
                buf(height, w) := 0;           -- WAS buf(height)(w)
            end loop;
            for h in 2 to height - 1 loop
                buf(h, 1) := 0;                -- WAS buf(h)(1)
            end loop;
            for h in 2 to height - 1 loop
                buf(h, width) := 0;            -- WAS buf(h)(width)
            end loop;

        --compute gradients
            for h in 2 to height - 1 loop
                for w in 2 to width - 1 loop
                    gx(h, w) := buf(h + 1, w) - buf(h - 1, w); -- WAS gx(h)(w), buf(h+1)(w) and buf(h-1)(w) 
                    gy(h, w) := buf(h, w + 1) - buf(h, w - 1);  -- WAS gy(h)(w), buf(h)(w+1) and buf(h)(w-1)
                    mag(h, w) := abs(gx(h, w) + gy(h, w)); -- WAS mag(h)(w), x(h)(w) and gy(h)(w)
                    ang(h, w) := gy(h, w) / gx(h, w); --WAS ang(h)(w), gy(h)(w) and gx(h)(w)
                end loop;
            end loop;
        end if;

    end process;

还注意到使用函数by2i切换到包std_logic_unsigned函数conv_integer。

所以这些变化以及删除功能by2i分析。

创建测试平台以查找边界错误:

library ieee;
use ieee.std_logic_1164.all;

entity getgxgy_tb is
end entity;

architecture foo of getgxgy_tb is
    signal pxl:  std_logic_vector(7 downto 0) := (others => '0');
    signal clk:  bit;
    signal fv:   real; 
begin

DUT:
    entity work.getgxgy
        port map (
            pxl => pxl,
            clk => clk,
            fv => fv
        );

CLOCK:
    process
    begin
        wait for 10 ns;
        clk <= not clk;
        if now > 120 ns then
            wait;
        end if;
    end process;

end architecture;

我们详细说明并运行测试平台并获得运行时错误!

ang的赋值中,错误除以零,因此您的算法仍需要一些工作。

使用if语句阻止它,我们发现分配中存在一个边界错误:

    gx(h, w) := buf(h + 1, w) - buf(h - 1, w); -- WAS gx(h)(w), buf(h+1)(w) and buf(h-1)(w) 

时点击w = 65引起的
    type gxgy is array (1 to height - 2, 1 to width - 2) of integer;

类型gxgyw对应的第二个维度的范围为width - 2,而w的范围超出width - 1

所以还有更多的算法表达式调整。

您打算注册的内容并不是特别清楚。如果它只是fv可能在不同的流程中发生,当前流程的敏感性列表设置为pxlgxgy,{{1 }和mag制成信号。

所有的abs,multiplies和div都可能不适合目标FPGA,需要使用公共资源进行算术运算,将操作分布在一定数量的时钟上。 VHDL描述了硬件,每个操作员调用或函数调用都可以暗示它自己的硬件。

在综合中,循环语句具有它的语句序列&#39;展开&#39;并且在没有找到相互依赖性的地方产生单独的硬件。对于h在2到高度 - 1和w在2到宽度 - 嵌套循环中的1个范围,您的通用值意味着anggx的每个减去8001次减法,{{1并且gy除以{,更改mag的值。这告诉我们,如果没有在一定数量的时钟上共享资源,时间和空间的权衡,你的硬件就不适合任何FPGA。

因此,您的算法不仅需要一点工作,还需要考虑实施资源。

您不能用VHDL编程来描述硬件。