对数组中的每个字节应用相同的操作
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 中设置信号显示)。
注意测试台中用于停止输入刺激的模拟时间(现在)测试。
我有一大堆 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 中设置信号显示)。
注意测试台中用于停止输入刺激的模拟时间(现在)测试。