VHDL ошибка нескольких постоянных драйверов, которая включает в себя «Z» и «L» - PullRequest
0 голосов
/ 01 сентября 2018

Чтобы изучить VHDL, я реализую свой собственный CPU с VHDL.

Я реализую IO с отображением в памяти, который одинаково обращается к традиционной оперативной памяти и различным периферийным устройствам ввода-вывода с точки зрения пользовательского кода.

Это реализация "корня" адресного пространства данных:

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;

Это реализация одного из периферийных устройств ввода / вывода:

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 линии; в противном случае задается высокий импеданс, чтобы другие периферийные устройства могли двигаться.

Назначение строки 90 и строки 91 data_memory_controller состоит в том, что состояние с высоким импедансом не распространяется за пределы этой сущности; для реального оборудования это может быть реализовано понижающим резистором.

Насколько я знаю, из-за правила разрешения std_logic, rq из data_memory_controller становятся 'L', если нет периферийных устройств, которые управляют выходом (= rq_tri - это 'Z'); в противном случае 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. не распространять 'Z' снаружи data_memory_controller

Я использую Quartus Prime Lite Edition версии 18.0, и эта реализация будет загружена на микросхему FPGA серии Intel MAX 10.

1 Ответ

0 голосов
/ 07 сентября 2018

ПЛИС поддерживают только драйверы с тремя состояниями на контактах. Хотя инструмент синтеза может преобразовывать внутренние три-состояния в мультиплексоры, он на самом деле не дает четкого замысла для тех, кто читает код. Три состояния должны использоваться только на истинных входных портах и ​​только на верхнем уровне, при этом драйвер три состояния предпочтительно также находится на верхнем уровне (но при желании его можно перемещать глубже в иерархии)

Вы получаете несколько водителей, потому что вы ведете

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

Это принимает значение rq_tri и 0s из значения (другие 'L'). 'L' будет просто преобразован в '0' внутри и направлен против того, что должно быть eq_tri. Хотя это может работать в симуляции, оно не соответствует ожидаемым схемам проектирования в синтезаторе.

Если вы действительно хотите, чтобы это работало, вы можете подать запрос на улучшение с Intel, но я подозреваю, что он будет проигнорирован, так как он не соответствует стилю кодирования де-факто, который должен иметь явные указания для всех сигналов (как входных, так и выходных). ).

...