На курсах «Логическое проектирование» мы все узнали, что можно минимизировать логическую функцию, например, используя карту Карно или алгоритм Куайна – МакКласки . Мы также узнали, что значения «Не волнует» увеличивают потенциал минимизации.
Например возьмите файл реестра. write_address
И write_data
сигналы на самом деле не имеет значения , когда write_enable
сигнал '0'
. Таким образом, им должно быть присвоено значение «Не заботиться», чтобы позволить больше оптимизаций в логике, управляющей этими сигналами (т.е. не в самом файле регистра).
Как правильно указать такие значения «Не волнует» в VHDL, чтобы предоставить инструменту синтеза больше места для возможных оптимизаций?
До сих пор я нашел следующие вещи, которые могут быть подходящими. Но я не совсем уверен, каковы плюсы и минусы каждого подхода:
- Просто не присваивать сигнал. Кажется, это может сработать. Однако я обнаружил, что это не работает, когда вы хотите определить константу «ничего не делать» некоторого
record
типа, поскольку константы записи должны быть полностью определены (по крайней мере, Modelsim говорит мне об этом). std_logic_1164
Пакет определяет значение'-' -- Don't care
дляstd_ulogic
. Похоже, что это семантически правильный выбор для явного «пофиг», но я никогда не видел, чтобы он использовался где-либо (кроме несвязанных конструкций VHDL-2008case?
).- Modelsim использует это значение
'X'
для отображения неопределенных сигналов. Однако я не уверен, что инструменты синтеза понимают явное'X'
назначение как «все равно».
Вот упрощенный фрагмент кода для пояснения, где я инициализировал сигналы пофиг '-'
.
Как вы можете видеть, сигнал control.reg_write_address
может иметь 3 различных значения: "----"
, instruction(11 downto 8);
и instruction(3 downto 0);
. Теперь я ожидаю, что это будет синтезировано в мультиплексор с 2 входами, если '-'
интерпретируется как «все равно». Если бы я инициализировал сигнал (others => '0')
вместо '-'
, инструмент должен был бы генерировать 3-х входной мультиплексор.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package mytypes is
type control_signals_t is record
write_enable : std_logic;
write_address : std_ulogic_vector(3 downto 0);
read_address : std_ulogic_vector(3 downto 0);
end record;
-- All members of this constant must be fully specified.
-- So it's not possible to simply not assign a value.
constant CONTROL_NOP : control_signals_t := (
write_enable => '0',
write_address => (others => '-'),
read_address => (others => '-')
);
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library cfx;
use cfx.mytypes.all;
entity control_unit is
port(
instruction : in std_ulogic_vector(15 downto 0);
write_data : out std_ulogic_vector(15 downto 0);
ctrl : out control_signals_t
);
end entity;
architecture rtl of control_unit is
begin
decode_instruction : process(instruction) is
begin
-- Set sensible default values that do nothing.
-- Especially all "write_enable" signals should be '0'.
-- Everything else is mostly irrelevant (don't care).
ctrl <= CONTROL_NOP;
write_data <= (others => '-');
if instruction(15 downto 12) = "1100" then
-- Load 8 bit of data into the register file
ctrl.write_enable <= '1';
write_data <= std_ulogic_vector(resize(signed(instruction(7 downto 0)), 16));
ctrl.write_address <= instruction(11 downto 8);
elsif instruction(15 downto 8) = "11111001" then
-- Load 4 bit of data into the register file
write_data <= std_ulogic_vector(resize(signed(instruction(7 downto 4)), 16));
ctrl.write_address <= instruction(3 downto 0);
elsif instruction(15 downto 8) = "10110101" then
-- Read from the register file. Don't use the write signals at all.
ctrl.read_address <= instruction(3 downto 0);
end if;
end process;
end architecture;
write_address
и с чемwrite_data
? Какую оптимизацию вы ожидаете провести?