我使用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;
答案 0 :(得分:1)
几个问题:
entity getGxGy
与end getHOGfv;
;
end loop
上遗漏了by2i
。
;
by2i
begin
语句(type gxgy
和process(clk, pxl)
之间buf(1)(w)
,它应该是buf(1, 2)
。mag
和ang
都未定义。当您遇到大量错误时,可能很难找到确切原因。通常,编译器会在报告错误时感到困惑。从第一个开始,修复它,然后重新编译。继续,直到事情清理。
另外,澄清一点。您不需要by2i
。您可以使用numeric_std进行转换(感谢scary_jeff指出这一点)。使用to_integer(unsigned(pxl))
进行转换。
还有一点。不要同时使用std_logic_unsigned
和numeric_std
。 numeric_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;
类型gxgy
与w
对应的第二个维度的范围为width - 2
,而w
的范围超出width - 1
。
所以还有更多的算法表达式调整。
您打算注册的内容并不是特别清楚。如果它只是fv
可能在不同的流程中发生,当前流程的敏感性列表设置为pxl
和gx
,gy
,{{1 }和mag
制成信号。
所有的abs,multiplies和div都可能不适合目标FPGA,需要使用公共资源进行算术运算,将操作分布在一定数量的时钟上。 VHDL描述了硬件,每个操作员调用或函数调用都可以暗示它自己的硬件。
在综合中,循环语句具有它的语句序列&#39;展开&#39;并且在没有找到相互依赖性的地方产生单独的硬件。对于h在2到高度 - 1和w在2到宽度 - 嵌套循环中的1个范围,您的通用值意味着ang
和gx
的每个减去8001次减法,{{1并且gy
除以{,更改mag
的值。这告诉我们,如果没有在一定数量的时钟上共享资源,时间和空间的权衡,你的硬件就不适合任何FPGA。
因此,您的算法不仅需要一点工作,还需要考虑实施资源。
您不能用VHDL编程来描述硬件。