VHDL多个常量驱动程序错误,涉及'Z'和'L'

问题描述 投票:0回答:1

要学习VHDL,我正在使用VHDL实现自己的自定义CPU。

我正在实现内存映射IO,从用户代码的角度来看,它以相同的方式访问传统RAM和各种I / O外设。

这是数据地址空间“根”的实现:

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

entity data_memory_controller is
    port (
        clock: in std_logic;
        addr: in std_logic_vector(31 downto 0);
        rq: out std_logic_vector(31 downto 0);
        wq: in std_logic_vector(31 downto 0);
        re: in std_logic;
        we: in std_logic;

        ledr: out std_logic_vector(9 downto 0);
        sw: in std_logic_vector(9 downto 0)
    );
end;

architecture rtl of data_memory_controller is
    component onchip_ram
        generic (
            addr_width: integer;
            data_width: integer
        );
        port (
            clock: in std_logic;
            addr: in std_logic_vector(addr_width-1 downto 0);
            rq: out std_logic_vector(data_width-1 downto 0);
            wq: in std_logic_vector(data_width-1 downto 0);
            re: in std_logic;
            we: in std_logic
        );
    end component;

    component ledr_controller
        port (
            clock: in std_logic;
            rq: out std_logic_vector(31 downto 0);
            wq: in std_logic_vector(31 downto 0);
            re: in std_logic;
            we: in std_logic;
            ledr: out std_logic_vector(9 downto 0)
        );
    end component;

    component sw_controller
        port (
            clock: in std_logic;
            rq: out std_logic_vector(31 downto 0);
            re: in std_logic;
            sw: in std_logic_vector(9 downto 0)
        );
    end component;

    signal c0, c1, c2: std_logic;
    signal rq_tri: std_logic_vector(31 downto 0);
begin
    c0 <= '1' when std_match(addr, "000000000000000000000000--------") else '0';
    c1 <= '1' when std_match(addr, "10000000000000000000000000000000") else '0';
    c2 <= '1' when std_match(addr, "10000000000000000000000000000001") else '0';

    onchip_ram_c: onchip_ram generic map(
        addr_width => 8,
        data_width => 32
    ) port map (
        clock => clock,
        addr => addr(7 downto 0),
        rq => rq_tri,
        wq => wq,
        re => re and c0,
        we => we and c0
    );

    ledr_controller_c: ledr_controller port map(
        clock => clock,
        rq => rq_tri,
        wq => wq,
        re => re and c1,
        we => we and c1,
        ledr => ledr
    );

    sw_controller_c: sw_controller port map(
        clock => clock,
        rq => rq_tri,
        re => re and c2,
        sw => sw
    );

    rq <= rq_tri;          -- line 90
    rq <= (others => 'L'); -- line 91
end;

这是I / O外设之一的实现:

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

entity sw_controller is
    port (
        clock: in std_logic;
        rq: out std_logic_vector(31 downto 0);
        re: in std_logic;
        sw: in std_logic_vector(9 downto 0)
    );
end;

architecture rtl of sw_controller is
begin
    process(clock)
    begin
        if rising_edge(clock) then
            if std_match(re, '1') then
                rq <= "0000000000000000000000" & sw;
            else
                rq <= (others => 'Z');
            end if;
        end if;
    end process;
end;

每个外设都接受读使能信号。如果读取使能变高,则驱动rq线;否则留下高阻抗,以允许其他外设可以驱动。

data_memory_controller的第90行和第91行的目的是高阻抗状态不会传播到该实体之外;对于实际硬件,这可以通过下拉电阻实现。

据我所知,由于std_logic的分辨率规则,如果没有驱动输出的外围设备(= rq是'Z'),data_memory_controllerrq_tri变为'L';否则,rq复制rq_tri的内容。

但是,分析和合成步骤会返回以下错误:

Error (10028): Can't resolve multiple constant drivers for net "rq[31]" at data_memory_controller.vhd(90) Error (10029): Constant driver at data_memory_controller.vhd(91) Error (10028): Can't resolve multiple constant drivers for net "rq[30]" at data_memory_controller.vhd(90) Error (10028): Can't resolve multiple constant drivers for net "rq[29]" at data_memory_controller.vhd(90) ...... [similar Error (10028) messages] ......

是的,我在同一条线上“驱动”多个信号,但我认为这种情况有明确的规则,应该接受这个程序。

如果我说的有什么不对,请纠正我。而且,我想找到替代方法

  1. 每个外设都可以驱动输出或'Z'取决于读使能信号,和
  2. 不要在data_memory_controller之外传播'Z'

我使用的是Quartus Prime Lite版本18.0,此实现将上传到Intel MAX 10系列FPGA芯片上。

vhdl quartus
1个回答
1
投票

FPGA仅支持引脚上的三态驱动器。虽然synth工具可能会将内部三态转换为多路复用器,但它并没有真正为其他读取代码的人提供明确的设计意图。 Tri-states应仅用于真正的inout端口,并且仅用于顶层,tri state驱动程序最好也位于顶层(但如果你愿意,它可以在层次结构中更深地移动)

你得到了多个司机因为你在开车

rq <= rq_tri;          -- line 90
rq <= (others => 'L'); -- line 91

这是从(其他'L')值获取rq_tri值和0。 'L'将在内部转换为'0',并驱动eq_tri应该是什么。虽然这可能在模拟中起作用,但它不符合合成器中的预期设计模式。

如果你真的想要这个,你可以提出一个增强请求与英特尔,但我怀疑它将被忽略,因为它不匹配事实编码风格,即有明确的方向所有信号(进或出)。

© www.soinside.com 2019 - 2024. All rights reserved.