0

我想使用四个按钮作为输入,三个七段 LED 显示器作为输出。两个按钮应通过 16 个 RAM 位置上下移动;另外两个应该增加和减少当前显示的内存位置的内容。一个七段显示器应显示当前地址 (0–F),另外两个应以十六进制 (00–FF) 显示该位置的内容。这是我尝试执行此操作的代码(我还没有实现显示):

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity raminfr is
    port (
        clk : in std_logic;
        we : in std_logic;
        do : out unsigned(7 downto 0)
    );
end raminfr;

architecture rtl of raminfr is

type ram_type is array (0 to 15) of unsigned(7 downto 0);
signal RAM : ram_type;
signal read_a : unsigned(3 downto 0);
signal a : unsigned(3 downto 0);
signal di : unsigned(7 downto 0);
signal clock : std_logic;
signal key : std_logic_vector(3 downto 0);
begin
  U1: entity work.lab1 port map (
    clock =>clock,
    key => key,
    register_counter => a,
    value_counter => di
  );
process (clk)
begin
    if rising_edge(clk) then
        if we = '1' then
            RAM(to_integer(a)) <= di;
        end if;
        read_a <= a;
    end if;
end process;
do <= RAM(to_integer(read_a));
end rtl;

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity lab1 is
    port(
        clock : in std_logic;
        key : in std_logic_vector(3 downto 0); 
        value_counter   : buffer unsigned(7 downto 0) ;
        register_counter : buffer unsigned(3 downto 0) 
        );
end lab1;

architecture up_and_down of lab1 is
    signal value_in_ram : unsigned(7 downto 0);
    signal clk : std_logic;
    signal we : std_logic;
        begin
        U1: entity work.raminfr port map (
            do=>value_in_ram,
            clk=>clk,
            we=>we
        );
    process(clock, value_counter, register_counter)
        begin
            if rising_edge(clock) then
                if (key(3)='0' and key(2)='0' and key(1)='1' and key(0)='0') then
                    value_counter <= value_counter + "1";   
                elsif (key(3)='0' and key(2)='0' and key(1)='0' and key(0)='1') then  
                    value_counter <= value_counter - "1";   
                elsif (key(3)='1' and key(2)='0' and key(1)='0' and key(0)='0') then
                    register_counter<= register_counter + "1";
                    value_counter <= value_in_ram;
                elsif (key(3)='0' and key(2)='1' and key(1)='0' and key(0)='0') then
                    register_counter<= register_counter - "1";
                    value_counter <= value_in_ram;
                end if;
            end if;
    end process;
end architecture up_and_down;

当我尝试编译它时,我会一遍又一遍地重复以下错误:

Error (12051): Project too complex: hierarchy path is too long
Error (12052): Entity "lab1" is instantiated by entity "raminfr"
Error (12052): Entity "raminfr" is instantiated by entity "lab1"

这显然是由于我已经将每个实体的端口映射到另一个,但我不知道任何其他方式来完成我想要完成的事情。有人可以提出替代方案吗?

4

1 回答 1

2

这是一个猜测,因为不太清楚你想做什么。问题似乎是设计问题之一:您很清楚最终结果应该做什么,但不清楚如何将其分解为以最简单的方式交互以实现目标的组件。

我的猜测是基于“raminfr”中的活动代码存储和加载数据独立于其他已经潜入的东西的事实。

所以我建议将“raminfr”作为一个内存组件进行清理,而不需要任何其他东西。然后它可以嵌入到处理键的“lab1”组件中,并存储和显示来自正确寄存器的值。它也可以在您需要内存的任何其他地方重复使用。

那么让我们看看raminfr。

entity raminfr is
    port (
        clk : in std_logic;
        we : in std_logic;
        do : out unsigned(7 downto 0)
    );
end raminfr;

它有一个时钟、一个写使能输入和一个数据输出。但奇怪的是,没有地址或数据输入!现在,内存是一种标准的“设计模式”,偏离它可能是不明智的,所以让我们添加它们......

entity raminfr is
    port (
        clk  : in std_logic;
        we   : in std_logic;
        addr : in unsigned(3 downto 0);
        di   : in  unsigned(7 downto 0);
        do   : out unsigned(7 downto 0)
    );
end raminfr;

记忆模式的一些变体具有其他特征;读使能、输出使能、单独的读和写时钟等,但这个简单的在这里就可以了。

您还可以使用泛型自定义其大小,修改其数据和地址总线宽度以匹配。这使它更有用,并节省了相似但不同的模块的扩散......

让我们清理架构以匹配。

architecture rtl of raminfr is
   type ram_type is array (0 to 15) of unsigned(7 downto 0);
   signal RAM    : ram_type;
   signal read_a : unsigned(3 downto 0);
begin
process (clk)
...
end process;
do <= RAM(to_integer(read_a));
end rtl;

现在我们可以在“lab1”模块中实例化它,连接它的新端口

    U1: entity work.raminfr port map (
        addr => register_counter,   -- was "a", typo
        di   => value_counter,
        do   => value_in_ram,
        clk  => clk,
        we   => we
    );

并对lab1 的其余部分进行任何支持性更改。

这不是唯一合理的分解:您还可以使“lab1”成为一个没有自己存储的简单组件,并带出其他必要的信号作为端口。然后,您将需要第三个“顶级”实体,其架构将 lab1 和 raminfr 互连。

于 2013-01-26T10:36:29.110 回答