我有一个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;信号。
答案 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的名称并重置以指示极性,取自不完整的单元格定义。
这就是:
如果您更具体一点,我可以根据您的期望量身定制接口。
这表明如何在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中)。
注意用于在测试平台中停止输入激励的模拟时间(现在)的测试。