对数组中的每个字节应用相同的操作

Apply same operation to every byte in array

我有一大堆 2 位元素。我在每个时钟周期一个接一个地访问这些元素,根据我的设计输入改变 2 位的值。 现在,在访问了所有这些之后,我想将当前包含特定值(如 10)的所有单元格设置为某个值(比方说 11)。我需要在一个时钟周期内完成。

我的第一个想法是设计一个在其输入端带有多路复用器的寄存器,这样我就可以决定将哪个值赋予寄存器,但这对我来说似乎不是最聪明的想法(因为我需要实例化 N 次这个新组件,我不知道按顺序访问所有这些组件是否容易。

有没有一种聪明而简单的方法来做到这一点?我想也许解决方案可能是使用关键字 OTHERS,但我没有找到关于如何使用它的线索,即使在 VHDL 参考手册中也是如此。

编辑:这是我想到的组件。

library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity cell is
  port (
    reset, clk, set, calc: in std_logic;
    data: out std_logic_vector
  );
end entity;

architecture arch of cell is

signal my_reg: std_logic_vector(1 downto 0);

begin

    data <= my_reg;

    main : process(clk, reset)
    begin
        if(reset = '0') then
            my_reg <= "00";
        elsif(clk'event and clk = '0') then
            if(set = '1') then
                my_reg <= "01";
            elsif(calc = '1' and my_reg = "01") then
                my_reg <= "11";
            else
                my_reg <= "00";
            end if;
        end if;
    end process;

end architecture;

即使多次实例化它,我也不知道如何按顺序访问每个 'set' 信号和全局所有 'calc' 信号。

因为您没有提供有关如何连接这些单元格的一些参数,所以我假设每个单元格都有自己的设置和计算位:

library ieee;
use ieee.std_logic_1164.all;

entity cell is
    port (
        reset_n:    in  std_logic;
        clk_n:      in  std_logic;
        set:        in  std_logic;
        calc:       in  std_logic;
        data:       out std_logic_vector(1 downto 0)
    );
end entity;

architecture arch of cell is
    signal my_reg: std_logic_vector(1 downto 0);
begin
    data <= my_reg;
main: 
    process (clk_n, reset_n)
    begin
        if reset_n = '0' then
            my_reg <= "00";
        elsif clk_n'event and clk_n = '0' then -- falling_edge(clk_n)
            if set = '1' then
                my_reg <= "01";
            elsif calc = '1' and my_reg = "01" then
                my_reg <= "11";
            else
                my_reg <= "00";
            end if;
        end if;
    end process;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity bunch is 
generic ( NUMBER_CELLS:     natural := 8);
    port (
    reset_n:    in  std_logic;
    clk_n:      in  std_logic;
    set:        in  std_logic_vector (NUMBER_CELLS - 1 downto 0);
    calc:       in  std_logic_vector (NUMBER_CELLS - 1 downto 0);
    data:       out std_logic_vector (NUMBER_CELLS * 2 - 1 downto 0)
    );
end entity;

architecture foo of bunch is 
    component cell is
        port (
            reset_n:    in  std_logic;
            clk_n:      in  std_logic;
            set:        in  std_logic;
            calc:       in  std_logic;
            data:       out std_logic_vector (1 downto 0)
        );
    end component;   
begin

GEN:
    for i in set'range generate
    CELLX:
        cell
            port map (
                reset_n => reset_n,
                clk_n => clk_n,
                set => set(i),
                calc => calc(i),
                data => data (i * 2 + 1 downto i * 2)
            );
    end generate;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity bunch_tb is 
    constant NUMBER_CELLS:  natural := 8;
end entity;

architecture test of bunch_tb is
    constant CLK_PERIOD:    Time := 40 ns;
    signal reset_n:     std_logic := '1';
    signal clk_n:       std_logic := '1';
    signal set:         std_logic_vector(NUMBER_CELLS - 1 downto 0) 
                            := (others => '0');
    signal calc:        std_logic_vector(NUMBER_CELLS - 1 downto 0) 
                            := (others => '0');
    signal data:        std_logic_vector (NUMBER_CELLS * 2 - 1 downto 0);

begin
NOTCLK:
    process
    begin
        wait for CLK_PERIOD/2;
        clk_n <= not clk_n;
        if Now > 1400 ns then
            wait;
        end if;
    end process;

DUT:
    entity work.bunch 
        generic map (NUMBER_CELLS)
        port map (
            reset_n => reset_n,
            clk_n => clk_n,
            set => set,
            calc => calc,
            data => data
        );
STIMULUS:
    process
        variable bit: std_logic := '1';
    begin
        if Now = 0 ns then
            reset_n <= '0';
            wait for CLK_PERIOD;
        end if;
        if Now > 700 ns then
            bit := '0';
        end if;
        reset_n <= '1';
        set <= bit & set (NUMBER_CELLS - 1 downto 1); -- shift in '1','0'
        wait for CLK_PERIOD;
        calc <= bit & calc (NUMBER_CELLS -1 downto 1); -- shift in '1', '0'
        wait for CLK_PERIOD;
        if Now > 1440 ns then
            wait;
        end if;
    end process;    
end architecture;

正如您可能注意到的那样,clk 的名称已更改并重新设置以指示极性,取自您不完整的单元格定义。

这给出了:

(可点击)

如果您更具体一点,我可以定制界面以满足您的期望。

这里展示的是如何在 for 生成循环中为 set、calc 和 data 连接不同的总线大小。

这是在 OS X 10.9.5 和 gtkwave 3.3.64 上用 ghdl-0.31 完成的。

ghdl -a cell.vhdl
ghdl -e bunch_tb
ghdl -r bunch_tb --wave=bunch_tb.ghw

(并在 gtkwave 中设置信号显示)。

注意测试台中用于停止输入刺激的模拟时间(现在)测试。