На курсах «Логическое проектирование» мы все узнали, что можно минимизировать логическую функцию, например, используя карту Карно или алгоритм Куайна – МакКласки . Мы также узнали, что значения «Не волнует» увеличивают потенциал минимизации.
Например возьмите файл реестра. 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? Какую оптимизацию вы ожидаете провести?