1

我最近开始学习VHDL。我写了一段 VHDL 代码来确定算术

声明,但它不起作用。实际上当我模拟它时,输出没有

变化,它仍然是 0.0。我不知道我的错误在哪里。我需要使用一个

外部时钟?当我这样做时,它不会改变:-(

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

package mypack is
    type real_vector is array (integer range <>) of real;
end mypack;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.mypack.all;

entity convolution is port (
    x:in real_vector(0 to 3);
    y:in real_vector(0 to 1);

    f:out real_vector (0 to 4)
);
end convolution;

architecture Behavioral of convolution is
    --signal temp : real_vector (0 to 4):= (others => 0.0);
    --signal enable : std_logic :='0';
begin
    process (x,y)
        variable sum :real;
    begin

        for n in f'range loop
            enable <= '0';
            for k in y'range loop
                sum:=sum + x(k)*y(n-k);
            end loop;
            -- temp(n) <= sum;
            f(n) <= sum ;
            sum:=0.0;
        end loop;

        enable <= '1';

        --if (enable'event and enable='1') then
        --    f <= temp;
        --end if;

    end process;
end Behavioral;
4

2 回答 2

0

我可以在您的代码示例中看到一些内容:

  1. 你使用真正的类型。您应该避免使用它们,因为通常无法合成并且只能在模拟中工作。另一种方法是使用定点算法
  2. 你使用变量。只要您真的不知道自己在做什么,就应该尽量避免使用变量,因为变量的行为与正常信号不同。变量立即赋值,而信号值在进程结束时赋值。因此,变量通常仅用于简化更复杂的语句(例如#defineC 中的语句)。
  3. 您应该使您的设计同步/时钟并使用寄存器。每个时钟周期执行一项特定操作。

我认为sum:=0.0主循环末尾的语句会覆盖 assignment 中 sum 的值f(n) <= sum

于 2013-02-16T11:05:37.483 回答
0

VHDL 不是一种编程语言,它是一种硬件描述语言。

出于这个原因,为了获得可靠的结果并尽可能优化最终设计,使用硬件原生的 std_logic_vectors、unsigneds 和其他原语非常重要。

您没有看到输出变化,因为整个 for 循环在流程的一次迭代中完全执行。最终结果只会是 for 循环的最后一个状态,在这种情况下是sum:=0.0;. 为了解决这个问题,强烈建议您在设计中使用外部时钟,并且该时钟是您的工艺敏感度列表的一部分。这将允许您将您的流程本质上用作 for 循环,这将完全消除对显式 for 循环的需要。

几天前在 EE 堆栈交换站点上出现了一个与此问题非常相似的问题,我写了一个非常全面的答案,解释了如何以这种方式将进程用作 for 循环。

这是我对另一个问题的回答的链接。 连接器

我已经浏览了您的代码并对其进行了一些修复(并添加了一个时钟!)。我没有模拟它,所以它可能不会执行 100% 计时,但这是一个示例,可以了解我在将进程用作 for 循环并让您走上正确的轨道方面的意思。

干得好。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

-- unsigned types are part of the numeric_std package. They are like std_logic types, but have native support for +,-,*, etc.
package mypack is
    type x_vector is array(0 to 3) of unsigned(0 to 31);
    type y_vector is array(0 to 1) of unsigned(0 to 31);
    type f_vector is array(0 to 4) of unsigned(0 to 31);
end mypack;

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

use work.mypack.all;

entity convolution is 
port (
    clk : in std_logic;
    rst : in std_logic;
    x:in x_vector;
    y:in y_vector;
    f:out f_vector
);
end convolution;

architecture Behavioral of convolution is
    signal enable : std_logic;

    -- These are your for-loop count variables
    signal n_count : unsigned(0 to 4);
    signal k_count : unsigned(0 to 1);

    -- sum variable (you might want to look into making this 64 bits long, so the answer doesn't overflow)
    signal sum : unsigned (0 to 31);
begin

    -- process only executes when clock or reset changes
    convolve : process (clk,rst)
    begin
        if (rst = '1') then

            -- this is where you set your variables to 0;
            n_count <= (others => '0');
            k_count <= (others => '0');
            sum <= (others => '0');
            enable <= '0';

            -- nice way of setting all values in f array to zero (nest "others =>" for as many dimensions as you need)
            f <= (others => (others => '0'));

        elsif (rising_edge(clk)) then
            -- if your n counter hits its max value ('high), reset the counter
            if (n_count = n_count'high) then
                n_count <= (others => '0');
                -- Add whatever you want to do when n hits it's max here...

            -- This is what is executed while n is counting up.
            else 

                -- if your k counter hits its max value ('high), reset the counter
                if (k_count = k_count'high) then
                    k_count <= (others => '0');
                    -- Add whatever you want it to do when k hits it's max here...

                -- This is what is executed while k is counting up (with n)
                else
                    -- This is where the actual convolution takes place.
                    -- The counters are converted to integers in order to be used as array references
                    sum <= sum + sum + (x(to_integer(k_count))*y(to_integer(n_count-k_count)));
                    -- Increment k!
                    k_count <= k_count + "1";
                end if;
                -- Increment n!
                n_count <= n_count + "1";

                -- I'm not hugely sure what you want to do with the enable, but this is where 
                -- it was in the other code.  
                enable <= '0';
                -- drive F with sum value
                f(to_integer(n_count)) <= sum;
                -- clear sum for next round.
                sum <= (others => '0');
            end if;
            -- enable again.
            enable <= '1';
        end if;
    end process;
end Behavioral;
于 2013-02-18T03:06:40.250 回答