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

时间:2015-03-01 04:06:04

标签: vhdl

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

我的第一个想法是在其输入端设计一个带多路复用器的寄存器,因此我可以决定给寄存器赋予哪个值,但这对我来说似乎不是最明智的想法(因为我需要实例化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;

即使多次实例化,我也不知道如何按顺序访问每一套&#39;信号和全局所有&#39; calc&#39;信号。

1 个答案:

答案 0 :(得分:1)

因为您没有提供关于如何连接这些单元格的一些参数,所以我假设每个单元都有它自己的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的名称并重置以指示极性,取自不完整的单元格定义。

这就是:

bunch_tb.png (点击)

如果您更具体一点,我可以根据您的期望量身定制接口。

这表明如何在for generate循环中连接set,calc和data的不同总线大小。

这是通过OS X 10.9.5上的ghdl-0.31和gtkwave 3.3.64来完成的。

  

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

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

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