VHDL - 写入寄存器

时间:2013-01-26 01:04:07

标签: vhdl

我想使用四个按钮作为输入,三个七段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"

这显然是因为我有端口映射另一个实体的每个实体,但我不知道任何其他方式来实现我想要完成的任务。有人可以提出替代方案吗?

1 个答案:

答案 0 :(得分: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。