在逻辑设计课程中,我们都了解到可以最小化逻辑功能,例如通过使用卡诺图或Quine-McCluskey算法。我们还了解到“ Do n't Care”值增加了最小化的可能性。
例如拿一个注册文件。该write_address
和write_data
信号时,并不真正重要write_enable
信号'0'
。因此,应为它们分配“无关”值,以允许在驱动这些信号的逻辑中进行更多优化(即不在寄存器文件本身中)。
为了使综合工具有更多空间进行可能的优化,在VHDL中指定此类“无关”值的正确方法是什么?
到目前为止,我发现以下可能合适的方法。但是我不确定每个方法的优缺点是什么:
- 根本不分配信号。这似乎可以工作。但是我发现,当您想定义某种“不做任何操作的常量”时,它是行不通的
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
and 做些write_data
什么吗?您希望进行什么优化?