На курсах логічного дизайну ми всі дізналися, що можна мінімізувати логічну функцію, наприклад, використовуючи карту Карно або алгоритм Quine – McCluskey . Ми також дізналися, що значення "Небайдуже" збільшують потенціал мінімізації.
Наприклад, візьміть файл реєстру. write_address
І write_data
сигнали на насправді не має значення , коли write_enable
сигнал '0'
. Таким чином, їм слід призначити значення "Небайдуже", щоб дозволити більше оптимізації в логіці, що рухає цими сигналами (тобто не в самому файлі реєстру).
Який правильний спосіб вказати такі значення "Небайдуже" у VHDL, щоб забезпечити інструменту синтезу більше місця для можливих оптимізацій?
Поки що я знайшов такі речі, які можуть бути підходящими. Але я не дуже впевнений, які плюси і мінуси кожного підходу:
- Просто не призначаючи сигнал. Здається, це могло б спрацювати. Однак я виявив, що він не працює, коли потрібно визначити якийсь
record
тип "не робити нічого постійного" , оскільки константи запису потрібно повністю вказати (принаймні, так говорить мені Модельсім). std_logic_1164
Пакет визначає значення'-' -- Don't care
дляstd_ulogic
. Це виглядає так, що це семантично правильний вибір для явного "байдуже", але я ніколи не бачив, щоб він використовувався ніде (за винятком спорідненихcase?
конструкцій VHDL-2008 ).- 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
? Яку оптимізацію ви очікуєте провести?