Nei corsi di Logic Design abbiamo appreso che è possibile minimizzare una funzione logica, ad esempio usando una mappa di Karnaugh o l' algoritmo Quine – McCluskey . Abbiamo anche appreso che i valori "Non preoccuparti" aumentano il potenziale di minimizzazione.
Ad esempio prendere un file di registro. I segnali write_address
e write_data
non contano davvero quando è il write_enable
segnale '0'
. Pertanto, dovrebbe essere assegnato loro un valore "Non preoccuparti" per consentire ulteriori ottimizzazioni nella logica che guida questi segnali (cioè non nel file di registro stesso).
Qual è il modo corretto di specificare tali valori di "Non preoccuparti" in VHDL per consentire allo strumento di sintesi più spazio per possibili ottimizzazioni?
Finora ho trovato le seguenti cose che potrebbero essere adatte. Ma non sono davvero sicuro di quali siano i pro e i contro di ogni approccio:
- Semplicemente non assegnare il segnale. Sembra che potrebbe funzionare. Tuttavia, ho scoperto che non funziona quando si desidera definire una "costante di non fare nulla" di un certo
record
tipo, poiché le costanti dei record devono essere completamente specificate (almeno mi dice Modelsim). - Il
std_logic_1164
pacchetto definisce il valore'-' -- Don't care
perstd_ulogic
. Sembra che sia la scelta semanticamente corretta per un esplicito "non importa", ma non l'ho mai visto usato da nessuna parte (tranne neicase?
costrutti VHDL-2008 non correlati ). - Modelsim utilizza il valore
'X'
per visualizzare segnali non definiti. Tuttavia, non sono sicuro che gli strumenti di sintesi comprendano'X'
un'assegnazione esplicita come "non importa".
Ecco uno snippet di codice semplificato per chiarimenti, in cui ho inizializzato i segnali non importa '-'
.
Come si può vedere, il segnale control.reg_write_address
può avere 3 diversi valori: "----"
, instruction(11 downto 8);
e instruction(3 downto 0);
. Ora mi aspetto che questo sia sintetizzato in un multiplexer a 2 ingressi se '-'
interpretato come "non importa". Se avessi inizializzato il segnale con (others => '0')
invece di '-'
, lo strumento avrebbe dovuto invece generare un multiplexer a 3 ingressi.
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
ewrite_data
? Quale ottimizzazione ti aspetti di avere?