Mantık Tasarımı derslerinde hepimiz, örneğin bir Karnaugh haritası veya Quine – McCluskey algoritması kullanarak bir mantık işlevini en aza indirmenin mümkün olduğunu öğrendik . Ayrıca "Umurumda Değil" değerlerinin minimizasyon potansiyelini artırdığını öğrendik .
Örneğin bir kayıt dosyası alın. write_address
Ve write_data
ne zaman sinyalleri gerçekten önemli değil write_enable
sinyaldir '0'
. Bu nedenle, bu sinyalleri yönlendiren mantıkta daha fazla optimizasyon sağlamak için bir "Umurumda Olma" değeri atanmalıdır (yani kayıt dosyasının kendisinde değil).
Sentez aracının olası optimizasyonlara daha fazla yer vermesini sağlamak için VHDL'de bu tür "Umursamayın" değerlerini belirtmenin doğru yolu nedir?
Şimdiye kadar uygun olabilecek aşağıdaki şeyleri buldum. Ama her bir yaklaşımın artıları ve eksileri neler olduğundan emin değilim:
- Sadece sinyali atamamak. Bu işe yarayabilir gibi görünüyor. Ancak
record
, kayıt sabitlerinin tam olarak belirtilmesi gerektiğinden (en azından Modelsim bana söyler) bazı tür "sabit bir şey yapma" tanımlamak istediğinizde işe yaramadı buldum . std_logic_1164
Paket değerini tanımlar'-' -- Don't care
içinstd_ulogic
. Bu, açık bir "umrumda değil" için anlamsal olarak doğru bir seçim gibi görünüyor, ancak daha önce hiçbir yerde kullanıldığını görmedim (ilgisiz VHDL-2008case?
yapıları hariç ).- Modelsim bu değeri
'X'
tanımsız sinyalleri görüntülemek için kullanır . Ancak sentez araçlarının açık bir'X'
atamayı "umursamadıkları" olarak anlayıp anlamadıklarından emin değilim .
Burada, önemsiz sinyalleri başlattığım açıklama için basitleştirilmiş bir kod snippet'i var '-'
.
Gördüğünüz gibi, sinyal control.reg_write_address
3 farklı değerlere sahip olabilir: "----"
, instruction(11 downto 8);
ve instruction(3 downto 0);
. Şimdi '-'
"umurumda değil" olarak yorumlanırsa, bunun 2 girişli bir çoklayıcıya sentezlenmesini beklerdim . Birlikte sinyal başlatılır vardı (others => '0')
yerine '-'
, araç yerine 3-giriş çoklayıcıyı oluşturmak gerekir.
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
vewrite_data
? Hangi optimizasyonun gerçekleşmesini bekliyorsunuz?