VHDL:使用循环添加数字列表

时间:2013-02-21 12:38:27

标签: loops add vhdl

首先,我对C的知识非常有限,只是基本功能。我已经在VHDL中设置了一项我没有经验的任务。

任务是用VHDL编写程序,使用循环添加10个数字的列表(13,8,6,5,19,21,7,1,12,3)。

我想到了一种方法,即使在C中这样做,看看我是否可以在某种程度上模仿这种方法。到目前为止,我只想出了

    int start = 0;
    int add = start;
    int increment = 5;

    for (int i=0; i<10; i++) {
    add = add + increment;
    }

现在我知道这是非常基本的,但这是我能做的最好的。该循环只会将其增加5,与我所拥有的列表相同。

非常感谢任何帮助,这是我的第一个问题,如果我打破任何“不成文的法律”,请向我道歉

3 个答案:

答案 0 :(得分:1)

以下解决方案可以帮助您在VHDL中开始解决您的问题:

对于FPGA中的实现,可以找到更好的解决方案。所以,只需将其视为一个开始......

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity add is

    port (
        clk : in  std_logic;
        rst : in  std_logic;
        add : in  std_logic;
        sum : out std_logic_vector(31 downto 0));

end entity add;

architecture RTL of add is

    constant rom_size : integer := 10;
    type     t_rom is array (0 to rom_size-1) of unsigned(31 downto 0);
    constant rom : t_rom := (
        to_unsigned(13, sum'length),
        to_unsigned(8, sum'length),
        to_unsigned(6, sum'length),
        to_unsigned(5, sum'length),
        to_unsigned(19, sum'length),
        to_unsigned(21, sum'length),
        to_unsigned(7, sum'length),
        to_unsigned(1, sum'length),
        to_unsigned(12, sum'length),
        to_unsigned(3, sum'length));
    signal add_d : std_logic;
    signal index : integer range 0 to rom_size;
    signal sum_i : unsigned(sum'range);

begin

    p_add : process (clk) is
    begin
        if rising_edge(clk) then        -- rising clock edge
            if rst = '1' then           -- synchronous reset (active high)
                sum_i <= (others => '0');
                add_d <= '0';
                index <= 0;
            else

                add_d <= add;           -- rising edge detection

                if add_d = '0' and add = '1' then  -- rising_edge -> add next item to sum
                    sum_i <= sum_i + rom(index);
                    index <= index + 1;
                end if;
            end if;
        end if;
    end process p_add;


    -- output
    sum <= std_logic_vector(sum_i);

end architecture RTL;

enter image description here

答案 1 :(得分:1)

你提到这是parwan处理器研究的一部分,所以考虑它的方式很大程度上取决于你如何研究它们。

如果要构建处理器的实现,而不仅仅是学习逻辑运算的语法是重要的部分,您应该关注类型 unsigned range 0 to 255signed range -128 to 127。通过使用包ieee.numeric_std.all,您可以获得为这些类型定义的添加操作。

但是,如果已经为您定义了处理器,请仔细查看处理器接口。您将为此编写的代码将更多地是一个显式的状态机。

无论哪种方式,我发现最好的方法是编写测试台。这是将在输入列表中提供的部分,因为最终您不希望它是for (int i=0; i<10; i++),而是while(1)样式的处理。

这就是理论上的所有东西,所以这里有一些简单累加器过程的伪代码:

signal acc : unsigned range 0 to 255 := 0; --accumulator register
signal b : unsigned range 0 to 255 := 5;   --value to be added 
--each cycle you would change b

accumulator :process (clk)
begin
    if rising_edge(clk)
        acc <= acc + b;
    end if;
end process;

或者更好看看这里:Accumulator

答案 2 :(得分:1)

首先,我要指出没有必要使用std_logic_vectorsigned添加unsigned s或矢量算术的复杂性。这适用于简单的整数:

所以,你有一些数字进来了,总结了:

entity summer
port (
  inputs : integer_vector := (13,8,6,5,19,21,7,1,12,3);
  sum_out : integer);
end entity summer;

注意,我已使用您的值初始化输入端口 - 通常您会在测试平台中写入该端口。

现在要添加它们,你需要一个过程:

process(inputs)
    variable sum : integer;
begin
    sum := 0;
    for i in inputs'range loop
        sum := sum + inputs(i);
    end for;
    sum_out <= sum;
end process;

这是一个简单的解决方案 - 要创建“最佳”解决方案,您需要更详细的规范。例如:输入多久会改变一次?输入改变后你需要多久才能得到答案?有时钟吗?