在一个时钟

时间:2018-01-24 13:07:43

标签: vhdl

我想访问矢量的特定元素,并在一个时钟中添加它们的值。缓存输入已在此计算之前写入,因此可以立即访问它们。

type cache_type is array (89 downto 0) of std_logic_vector(14 downto 0);
signal input_cache : cache_type := (others => (others => '0'));

signal cluster_square_sum   : integer   := 0;

calc: process (clk)
begin
  if rising_edge(clk) and cache_ready then
     cluster_square_sum  <= conv_integer(input_cache(5)) + 
         conv_integer(input_cache(6)) + conv_integer(input_cache(7)) + 
         conv_integer(input_cache(12)) + conv_integer(input_cache(13)) + 
         conv_integer(input_cache(14)) + conv_integer(input_cache(15)) + ...
  end if;
end process;

如果没有在添加中明确写出所有需要的元素,我如何实现此行为?我已经考虑过程中的变量迭代器,但由于单个时钟计算它不起作用。

实际上,我首先不需要进程,我可以使用“when语句”直接在架构中编写我的总和

cluster_square_sum  <= conv_integer(input_cache(5)) + 
         conv_integer(input_cache(6)) + conv_integer(input_cache(7)) + 
         conv_integer(input_cache(12)) + conv_integer(input_cache(13)) + 
         conv_integer(input_cache(14)) + conv_integer(input_cache(15)) + ...
         when cache_ready <= '1';

不幸的是,我不知道如何以一种方式实现我的行为。

2 个答案:

答案 0 :(得分:2)

关于你的问题的一些事情尚不清楚,但关于这个问题的一件事是明确的:更好的设计会让你使用类型系统,而不是每一行都对抗它。

有一点不清楚:你在缓存中存储了什么?它是专门为数字保留的,还是可以存储数字,文本,指令等的CPU缓存?

如果它专门用于数字数据,那么

type cache_type is array (89 downto 0) of natural range  0 to 2**14 - 1;

会简化你的总和。或等效的有符号整数范围,以适合您的应用程序为准。这也使设计意图清晰。或者您可以使用signed中的unsignednumeric_std

cluster_square_sum  <= input_cache(5) + input_cache(6) + input_cache(7) + ...
         when cache_ready <= '1';

它还不清楚你正在总结的缓存子集,特别是因为它不是[MCVE]并且似乎覆盖了非连续范围。所以我只需要猜测它是一个固定的连续子集;你可以使用一个循环。

calc: process (clk)
variable running_total : natural;
begin
  if rising_edge(clk) then
     if cache_ready then
        running_total := 0;
        for i in lower_bound to upper_bound loop
           running_total := running_total + input_cache(6)(i);
        end loop;
        cluster_square_sum  <= running_total;
     end if;
  end if;
end process;

该变量允许即时赋值(变量赋值语义)而不是推迟赋值(信号赋值语义),因此您可以获得运行总计。

如果边界不是常数(或泛型),或者范围不是连续的,则此策略需要进行一些修改。

另一个不明确的事情是你的速度(延迟和吞吐量)和逻辑大小目标。这将在单个周期中执行每次添加,但该周期可能相当慢。如果您可能需要每个时钟周期输出一个具有真实时钟频率的输出,那么您必须对其进行流水线操作。

或者如果在需要输出之前cache_ready之后有足够的周期,则将循环和计算嵌入由cache_ready触发的状态机中。这可以在每个时钟周期执行一次加法(和循环迭代),允许input_cache成为块Ram而不是单独可访问的寄存器,用于非常小且快速的时钟设计。 (在这种情况下,每个时钟只添加一个,您可以安全地使用running_total的变量或信号。

答案 1 :(得分:1)

在所有情况下,我建议使用一个函数。

在你想要添加的元素中似乎没有任何逻辑,所以我让函数接受一组元素索引。

“最小”示例:

library IEEE;
use IEEE.std_logic_1164.all;

entity e is
    port(clk: in std_logic);
end entity;

architecture a of e is
    use IEEE.numeric_std.all;

    type cache_type is array(0 to 89) of std_logic_vector(14 downto 0);
    signal input_cache : cache_type := (
        5 => "000010101010101",
        6 => "000001010101010",
        7 => "000000101010101",
        12 => "000000010101010",
        13 => "000000001010101",
        14 => "000000000101010",
        15 => "000000000010101",
        others => (others => '0'));

    type integer_array is array(natural range <>) of integer;
    constant elements_to_add : integer_array := (5, 6, 7, 12, 13, 14, 15);

    signal cluster_square_sum   : integer   := 0;

    function add_elements(input_array : cache_type; element_idxs: integer_array) return integer is
        variable output : integer := 0;
    begin
        for idx in element_idxs'low to element_idxs'high loop
            output := output + to_integer(unsigned(input_array(element_idxs(idx))));
        end loop;
        return output;
    end;

begin
    calc: process(clk)
    begin
        if rising_edge(clk) then
            cluster_square_sum  <= add_elements(input_cache, elements_to_add);
        end if;
    end process;
end architecture;

请注意,您也可以使用此功能进行无处理/直接分配。

Plus testbench:

entity e_tb is end entity;

library IEEE;

architecture a of e_tb is
    use IEEE.std_logic_1164.all;
    signal clk : std_logic := '0';
begin
    UUT : entity work.e port map (clk => clk);

    test: process begin
        wait for 1 ns;
        clk <= '1';
        wait for 1 ns;
        clk <= '0';
        wait;
    end process;
end architecture;

请注意,如果要在FPGA中实现此功能,则需要相当多的资源并且会失去性能。管道设计会更好:使用多个时钟周期来添加元素。