Logic Design 과정에서는 Karnaugh 맵 또는 Quine–McCluskey 알고리즘 을 사용하여 로직 기능을 최소화 할 수 있다는 것을 모두 배웠습니다 . 또한 "Do n't Care" 값이 최소화 가능성을 증가 시킨다는 것도 알게되었습니다 .
예를 들어 레지스터 파일을 가져옵니다. write_address
및 write_data
때 신호는별로 중요하지 않습니다 write_enable
신호입니다 '0'
. 따라서 이들 신호를 구동 하는 로직 (예 : 레지스터 파일 자체가 아님) 에서 더 많은 최적화를 허용하려면 "Do n't Care"값을 지정해야합니다 .
합성 툴에 가능한 최적화를위한 더 많은 공간을 허용하기 위해 VHDL에서 이러한 "Do n't Care"값을 지정하는 올바른 방법은 무엇입니까?
지금까지 나는 다음과 같은 것들이 적합하다고 생각했다. 그러나 각 접근법의 장단점이 무엇인지 확실하지 않습니다.
- 단순히 신호를 할당하지 않습니다. 이것은 작동하는 것처럼 보입니다. 그러나
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
? 어떤 최적화가 예상됩니까?