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

请帮助我解决我编写的以下vhdl代码中的语法错误,vhdl,Vhdl,我使用Xlinix ISE 14.1编写了以下代码 我发现语法是正确的,但是xilinx在第27行和第30行显示了错误 我试图找到一个数字矩阵的一阶偏导数,这类似于在图像中找到边缘 函数by2i用于将字节(即位)转换为整数 在此VHDL代码中,我收到错误消息: “错误:HDLCompiler:806 B:/gxgyVHDL.vhd”第27行:“return”附近的语法错误。 “错误:HDLCompiler:806-”B:/gxgyVHDL.vhd“第30行:靠近“”的语法错误,” 我无法纠正这些

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

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

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

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

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

“错误:HDLCompiler:806 B:/gxgyVHDL.vhd”第27行:“return”附近的语法错误。
“错误:HDLCompiler:806-”B:/gxgyVHDL.vhd“第30行:靠近“”的语法错误,”

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

这是我第一次为图像处理编写程序,我不确定这个程序是否能像预期的那样工作,但它在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;
几个问题:

  • 您的实体名称不匹配。也就是说,
    实体getGxGy
    end getHOGfv不匹配
  • 您缺少一个尾随的
    by2i中的
    结束循环上的code>
  • 您缺少一个尾随的
    返回时在
    by2i
  • 您的体系结构中缺少一条
    begin
    语句(在
    类型gxgy
    进程(clk,pxl)
  • 您使用多维数组的语法错误。与其使用
    buf(1)(w)
    ,不如使用
    buf(1,2)
  • 未定义
    mag
    ang
  • 当您有大量错误时,可能很难找到确切的原因。编译器在报告错误时通常会感到困惑。从第一个开始,修复错误,然后重新编译。继续,直到问题得到解决

    还有一点需要澄清。您不需要使用
    by2i
    。您可以使用numeric\u std进行对话(感谢jeff指出这一点)。使用
    到整数(无符号(pxl))
    进行转换

    还有一点。不要同时使用
    std\u logic\u unsigned
    numeric\u std
    numeric\u std
    是使用有符号和无符号数字的标准方式。
    std\u logic\u 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)
    对其进行索引


    我更喜欢前者。

    除了Playmough注意到的语法项和缺少的声明之外,还有两个多余的上下文子句用于包numeric\u std(不应与Synopsys算术页面std\u logic\u unsigned混合)和math\u 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
    是标准逻辑(或标准逻辑),则可以使用标准逻辑1164函数上升沿

    为时钟边缘添加可识别的顺序逻辑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;
    
    还注意到从使用function
    by2i
    切换到包std_logic_unsigned function conv_integer

    因此,随着2i分析函数的删除,这些变化也随之发生

    生成测试台以查找边界错误:

    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;
    
    这是因为当

        type gxgy is array (1 to height - 2, 1 to width - 2) of integer;
    
    类型
    gxgy
    对应于
    w
    的第二维度的范围为
    width-2
    ,而
    w
    达到
    width-1
    ,超出范围

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

    您打算注册什么并不特别清楚。如果只是在不同的过程中发生的
    fv
    ,当前过程灵敏度列表设置为仅
    pxl
    gx
    gy
    mag
    ang
    ,并将其转换为信号

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

    在合成中,循环语句将其语句序列“展开”,并且在没有发现相互依赖的情况下,生成单独的硬件。对于嵌套循环中h在2到高度-1的范围内,w在2到宽度-1的范围内,您的通用值意味着对
    gx
    gy
    abs以及
    mag的加法进行8001次减法
    和除法用于
    ang
    ,所有这些都是通过更改
    pxl
    的值来实现的。这告诉我们,如果不在一定数量的时钟上共享资源,您的硬件将无法适应任何FPGA,这是一种时间和空间权衡

    因此,您的算法不仅需要做一些工作,还需要考虑实现资源


    你不需要用VHDL编程,你需要描述硬件。

    如果你想把一个包含无符号值的
    std\u逻辑向量
    转换成一个整数,只需使用
    value\u作为int“你不用VHDL编程,你需要描述硬件。”阿门。我想我对我代码中的大多数结构都很自由(循环、函数、偶尔的过程、数组和记录),但我脑子里总是有一个硬件体系结构。我知道代码将(或应该)在真正的硬件中产生什么。VHDL是达到目的的一种手段;一种工具。非常感谢。今天我学到了很多。它对我帮助很大。非常感谢。它对我帮助很大
    
        type gxgy is array (1 to height - 2, 1 to width - 2) of integer;