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_addresse write_datanon contano davvero quando è il write_enablesegnale '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
recordtipo, poiché le costanti dei record devono essere completamente specificate (almeno mi dice Modelsim). - Il
std_logic_1164pacchetto definisce il valore'-' -- Don't careperstd_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_addresspuò 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_addressewrite_data? Quale ottimizzazione ti aspetti di avere?