ในหลักสูตรการออกแบบลอจิกที่เราทุกคนได้เรียนรู้ว่ามันเป็นไปได้ที่จะลดการทำงานตรรกะเช่นโดยการใช้แผนที่ Karnaugh หรืออัลกอริทึมควิน-คสัส นอกจากนี้เรายังได้เรียนรู้ว่าค่า"ไม่สนใจ"เพิ่มโอกาสในการลดขนาด
ตัวอย่างเช่นใช้ไฟล์ลงทะเบียน write_address
และwrite_data
สัญญาณไม่ได้เรื่องจริงๆเมื่อสัญญาณwrite_enable
'0'
ดังนั้นพวกเขาควรจะกำหนดค่า "ไม่สนใจ" เพื่อให้การเพิ่มประสิทธิภาพมากขึ้นในตรรกะที่ขับสัญญาณเหล่านี้ (เช่นไม่ได้อยู่ในไฟล์ลงทะเบียนตัวเอง)
วิธีที่ถูกต้องในการระบุค่า "Don't Care" ใน VHDL คือเพื่อให้เครื่องมือการสังเคราะห์มีพื้นที่มากขึ้นสำหรับการเพิ่มประสิทธิภาพที่เป็นไปได้?
จนถึงตอนนี้ฉันได้พบสิ่งต่อไปนี้ซึ่งอาจเหมาะสม แต่ฉันไม่แน่ใจจริงๆว่าข้อดีข้อเสียของแต่ละวิธีคืออะไร:
- เพียงไม่กำหนดสัญญาณ ดูเหมือนว่ามันจะทำงานได้ อย่างไรก็ตามฉันพบว่ามันไม่ทำงานเมื่อคุณต้องการกำหนด "ไม่ทำอะไรคงที่" บาง
record
ประเภทเนื่องจากค่าคงที่บันทึกต้องได้รับการระบุอย่างสมบูรณ์ (อย่างน้อย Modelsim บอกฉันอย่างนั้น) std_logic_1164
แพคเกจที่กำหนดค่าสำหรับ'-' -- Don't care
std_ulogic
ดูเหมือนว่านี่เป็นตัวเลือกที่ถูกต้องสำหรับความหมายที่ชัดเจนว่า "ไม่สนใจ" แต่ฉันไม่เคยเห็นมันมาใช้เลย (ยกเว้นในโครงสร้าง VHDL-2008 ที่ไม่เกี่ยวข้องcase?
)- 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
? การเพิ่มประสิทธิภาพแบบใดที่คุณคาดว่าจะเกิดขึ้น