مقدمة إلى مجموعات المواد الكيميائية الثقيلة

فـي هـذا الـنظم الالكترونية المعقدة، حيث تنمو التصميمات وتعقدها، تصبح المحافظة على جودة المواد أمراً بالغ الأهمية، ومن أكثر الطرق فعالية لتحقيق التصميمات النموذجية القابلة لإعادة الاستخدام، والرمز الصالح للاستمرار في VHDL، استخدام مجموعات من الأدوات الفنية ذات الطابع العرفي.

سواء كنت تبني مشروع صغير لـ (إف بي جي) أو تصميم كبير لـ (إس إيه) سيبسط حزمة عملك ويقلل من الأخطاء ويجعل شفرتك أسهل للقراءة والاستمرار

ما هو حزمة VHDL؟

A VHDL package] is a design unit that provides a way to group logically related declarations. It consists of two parts:

  • Package declaration]: Defines the interface -- types, subtypes, constants, signals, functions, and procedures that are visible to the outside world.
  • Package body] (optional): Contains the implementation of any subprograms (functions and procedures) declared in the package declaration.

وتخزن المجموعة نفسها في مكتبة (عادة مكتبة " العمل " أو مكتبة محددة للمستعملين) ويمكن الرجوع إليها من قبل وحدات تصميم أخرى تستخدم شرط ، وهذا الفصل بين الوصلات بينية والتنفيذ مبدأ أساسي في التصميم النموذجي في VHDL.

مواد إعلان التعبئة

ويبدأ الإعلان بالكلمة الرئيسية يليها اسم الطرد وينتهي بـ (أو ).

  • Types and subtypes - for example, enumerated types, arrays, records, or subtypes of standard types.
  • Constants] - Global values that remain fixed during simulation or synthesis.
  • Functions and procedures] - subprograms that operate on the declared types.
  • Atributes and aliases] (less common, but useful in advanced contexts).

هنا الهيكل العظمي:

package My_Package is
 -- Type declarations
 type State_Type is (idle, read, write, error);
 subtype Byte is std_logic_vector(7 downto 0);

 -- Constant declarations
 constant Clock_Period : time := 10 ns;
 constant Data_Width : integer := 16;

 -- Function prototype
 function Max(A, B : integer) return integer;

 -- Procedure prototype
 procedure Reset_Counters(signal count1, count2 : inout integer);
end package My_Package;

هيئة تنفيذ مجموعة التعبئة

وتتضمن مجموعة التدابير التنفيذ الكامل لأي برامج فرعية معلنة في رأس الرزمة، ويجب أن يكون لها نفس الاسم الذي تحمله المجموعة، ويُعلن أنها .

package body My_Package is
 function Max(A, B : integer) return integer is
 begin
 if A > B then
 return A;
 else
 return B;
 end if;
 end function Max;

 procedure Reset_Counters(signal count1, count2 : inout integer) is
 begin
 count1 <= 0;
 count2 <= 0;
 end procedure Reset_Counters;
end package body My_Package;

ملاحظة أن الأنواع والثبات وغيرها من الإعلانات غير البرنامجية لا تظهر في هيئة الطرد؛ وهي لا تظهر إلا في الجزء المتعلق بالإعلان.

لماذا تستخدمين أكياس "في دي إل"؟

وتقدم مجموعات المواد العرفية مزايا عديدة تتوافق مع الممارسات الحديثة في هندسة البرمجيات المطبقة على وصف المعدات:

  • Modularity]: Break complex designs into self-contained units with clear interfaces. Each package handles a specific domain (math facilities, bus protocols, memory types, etc.).
  • Reusability]: يمكن استخدام مجموعة مصممة جيداً عبر عشرات المشاريع، على سبيل المثال، يمكن تقاسم مجموعة تحدد إشارات الحافلات المشتركة (مثل AXI-Stream) بين نواة شركاء التنفيذ، وإنقاذ أسابيع من إعادة العمل.
  • Maintainability] When requirements change, you update the package in one location, and all design units that use it automatically receive the update-without modifying each entity.
  • Consistency]: تمنع تعاريف النوع المركزي من الأخطاء، وإذا كان كل ملف يحدد نفسه ، فإن تغييراً لاحقاً إلى 9 أجزاء يتطلب الصيد في كل مرة.
  • Readability]: Descriptive package names and well-documented declarations make code self-explanatory. New team members can quickly grasp the design’s building blocks.
  • Version control friendly]: يتم تتبع التغييرات في مجموعة من التغييرات باعتبارها تغييرات في ذلك الملف فقط، وتبسيط عمليات استعراض الرموز، والدمج.

)٢( انظر: " VHDL " ، مثل التدفقات المستخدمة في متعاقدي الدفاع، وشركات الفضاء الجوي، وشركات شبه الموصلات، التي تأمر باستخدام مجموعات من المواد لأي مشروع غير طارئ، و " المعيار IEE VHDL " )١٠٧٦( يدعم صراحة الطرود، و " توصي باستخدامها مبادئ توجيهية للممارسات الفضلى مثل المبادئ التوجيهية التي وضعتها فريق التحليل والتوحيد القياسيين] VHDL.

دليل الخطوة خطوة خطوة إلى الأمام: إنشاء واستخدام مجموعة من المواد العرفية

لنمشي خلال العملية الكاملة لإنشاء مجموعة من العرف القوي ودمجها في تصميم VHDL.

الخطوة 1: تحديد إعلان الحزمة

فتح ملف جديد في القانون الإنساني الدولي (مثلاً، [(FLT:9]) وكتابة إعلان الطرد، وابدأ بشرط المكتبة ليشمل المكتبات المعيارية للمعهد إذا استخدمت أنواعها (مثل ) ولكن الطرد نفسه يمكن أن يكون نقياً، فهو يعتمد فقط على الأنواع التي تختارها، ولأجل أقصى قدر من قابلية النقل، تجنب الاعتماد على مجموعات محددة من البائعين ما لم تكن هناك حاجة إليها.

-- math_utils.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

package Math_Utils is
 -- Type for signed integers (if needed for synthesis)
 subtype Slv16 is std_logic_vector(15 downto 0);

 -- Constants
 constant PI : real := 3.141592653589793;
 constant E : real := 2.718281828459045;
 constant MAX_DIM : integer := 256;

 -- Function prototypes
 function Add(A, B : integer) return integer;
 function Multiply(A, B : integer) return integer;
 function Clamp(Value, Low, High : integer) return integer;
 function Is_Power_Of_Two(Value : positive) return boolean;
 function Log2(Value : positive) return natural;

 -- Procedure prototypes
 procedure Swap(signal X, Y : inout integer);
end package Math_Utils;

لاحظنا أنّنا ضمننا وظيفة (يُضفي عليها ثلاجة بين الحدود) ووظيفة (لوج2) (يُستخدم عادةً في حسابات المُستعارة الصغيرة) سننفذها في الجسم

الخطوة 2: كتابة هيئة التعبئة

وفي الملف نفسه (أو ملف منفصل) ينفذون مجموعة الحزمة، ويحتفظ معظم المصممين بكلتاهما في ملف واحد لأن الجسم يمكن أن يكون طويلا، ولكن يمكن أن يكونا منفصلين عمليا.

package body Math_Utils is
 function Add(A, B : integer) return integer is
 begin
 return A + B;
 end function Add;

 function Multiply(A, B : integer) return integer is
 begin
 return A * B;
 end function Multiply;

 function Clamp(Value, Low, High : integer) return integer is
 begin
 if Value < Low then
 return Low;
 elsif Value > High then
 return High;
 else
 return Value;
 end if;
 end function Clamp;

 function Is_Power_Of_Two(Value : positive) return boolean is
 begin
 return (Value and (Value - 1)) = 0;
 end function Is_Power_Of_Two;

 function Log2(Value : positive) return natural is
 variable result : natural := 0;
 variable temp : natural := Value;
 begin
 while temp > 1 loop
 temp := temp / 2;
 result := result + 1;
 end loop;
 return result;
 end function Log2;

 procedure Swap(signal X, Y : inout integer) is
 variable tmp : integer;
 begin
 tmp := X;
 X <= Y;
 Y <= tmp;
 end procedure Swap;
end package body Math_Utils;

Note on synthesis:] The and procedures are synthesable (clamp produces comparators and multiplexers; swap uses middle variable). and are used in testbenches or for generating body version

الخطوة 3: استخدام الحزمة في تصميمك

(أ) استخدام الطرد، إضافة شرط في كيانك أو هيكلك، والضرائب النموذجية هي:

library work;
use work.Math_Utils.all;

The keyword makes all declarations visible. You can also selectively import specific items using etc.

هنا مثال كامل على كيان يستخدم حزمتنا:

-- calculator.vhd
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.Math_Utils.all;

entity Calculator is
 port (
 A, B : in integer;
 Operation: in std_logic_vector(1 downto 0);
 Result : out integer;
 Error : out std_logic
 );
end entity Calculator;

architecture Behavioral of Calculator is
begin
 process(A, B, Operation)
 variable temp : integer;
 begin
 Error <= '0';
 case Operation is
 when "00" => Result <= Add(A, B);
 when "01" => Result <= Multiply(A, B);
 when "10" =>
 temp := A - B;
 -- Clamp the result to 0..255
 Result <= Clamp(temp, 0, 255);
 when "11" =>
 if B = 0 then
 Error <= '1';
 Result <= -1;
 else
 Result <= A / B;
 end if;
 when others =>
 Error <= '1';
 Result <= 0;
 end case;
 end process;
end architecture Behavioral;

وفي هذا التصميم، نستخدم ، ، و] من الطرد، ولا يستخدم إجراء ] هنا، ولكن يمكن استدعاؤه في اختبار لتبادل القيم.

رسوم التعبئة المسبقة

وإلى جانب المهام الأساسية والثبات، تدعم مجموعات القانون الإنساني الدولي عدة هياكل متقدمة تعزز النمط وتكرار العمل.

تحميل زائد في الحزم

ويتيح القانون الإنساني الدولي تحميل المهام والإجراءات على نحو مفرط بمختلف أنواع أو أرقام البارامترات، وهذا مفيد بصفة خاصة عندما تحتاج إلى معالجة مختلف بيانات التمثيل (مثلاً، ، ، ). ويمكنك أن تعلن نسخاً متعددة من وظيفة تحمل نفس الاسم ولكن قوائم حجج مختلفة.

package Overload_Example is
 function Add(A, B : integer) return integer;
 function Add(A, B : std_logic_vector) return std_logic_vector;
 function Add(A, B : signed) return signed;
end package Overload_Example;

package body Overload_Example is
 function Add(A, B : integer) return integer is
 begin
 return A + B;
 end function;

 function Add(A, B : std_logic_vector) return std_logic_vector is
 variable result : std_logic_vector(A'length-1 downto 0);
 begin
 result := std_logic_vector(unsigned(A) + unsigned(B));
 return result;
 end function;

 function Add(A, B : signed) return signed is
 begin
 return A + B;
 end function;
end package body Overload_Example;

النسخة الصحيحة تُحل في الوقت المُحدد بناءً على أنواع الحجج، هذا يُجنّب تَصَمُّمَكَ بأسمِ الوظائف مثل ، ، الخ.

مجموعات المواد الجينية (VHDL-2008 وفيما بعد)

بدءاً من VHDL-2008، يمكن أن تُعدّل الطرود بواسطة مواد عامة، مماثلة للكيانات والعناصر، وتسمح مجموعة عامة لكم بتحديد أنواع أو ثباتات أو برامج فرعية تعتمد على البارامترات العامة، مثلاً مجموعة من المواد الخاصة بجهاز تحديد القيمة المالية لأي عمق أو عرض بيانات:

generic type data_type is private;
package Generic_FIFO is
 type FIFO_Array is array (natural range <>) of data_type;
 function Is_Empty(f : FIFO_Array) return boolean;
 -- ...
end package Generic_FIFO;

package body Generic_FIFO is
 function Is_Empty(f : FIFO_Array) return boolean is
 begin
 return f'length = 0;
 end function;
end package body Generic_FIFO;

لتفكير مجموعة عامة، تستخدمين شرط مع خريطة عامة:

package my_fifo_pkg is new work.Generic_FIFO
 generic map (data_type => std_logic_vector(7 downto 0));

وهذا سمة قوية لبناء مكتبات قابلة لإعادة الاستخدام إلى حد كبير، غير أن الدعم المقدم للمجموعات العامة محدود في بعض الأدوات التوليفية القديمة؛ والتحقق من وثائق البائعين (Xilinx, Intel, Lattice).

الأنواع المحمية (VHDL-2002+)

وتتيح الأنواع المحمية المتغيرات المشتركة في القانون الإنساني الدولي، وهي مفيدة للاختبارات والنماذج الرفيعة المستوى (مثل لوحات التقييم)، وتُعلن داخل مجموعة من المواد كتعريف من النوع المحمي، وهذا هو أكثر من سمة التحقق من التوليفي، ولكنه يساعد على بناء مرافق اختبار معقدة.

package Scoreboard_Pkg is
 type Scoreboard_Type is protected
 procedure Push(item : integer);
 function Pop return integer;
 function Count return natural;
 end protected Scoreboard_Type;
end package Scoreboard_Pkg;

ويجب أن يظهر تنفيذ نوع محمي في مجموعة من المواد، على غرار البرامج الفرعية، والأنواع المحمية هي أقرب نوع من برامج التنمية البشرية التي يمكن أن تستهدفها جهات موضوعية.

أفضل الممارسات في مجال تصميم العبوات

لجعل رزمتك قابلة للاستمرار وإعادة استخدامها حقا، اتباع هذه المبادئ التوجيهية:

1- مجموعات الأسماء بوضوح

Use descriptive names that reflect the package’s domain: , , . Avoid general names like or .

2 - الحفاظ على مجموعات تركز

ولا تفرغ كل وظيفة في مجموعة كبيرة واحدة، بل تخلق مجموعات متعددة من الرزم الصغيرة والمتماسكة، مثل روتينات الرياضيات المنفصلة من أنواع الوصل البيني للحافلات، مما يحسن من إمكانية القراءة ويقلل من مستويات إعادة التجميع.

3 - وثيقة الحزمة المشتركة

إدراج تعليقات توضح الغرض من كل نوع ثابت وفرعي، ذكر أي قيود (مثلاً الوظائف غير القابلة للتوحيد) - استخدام أسلوب التعليق المتسق (التشخيص الشامل).

-- Clamp: Returns Value saturated within [Low, High].
-- If Low > High, returns Low.
-- This function is synthesizable.

4- استخدام الأنواع القياسية حيثما أمكن

Define subtypes of or from rather than inventing new base types. This maintains compatibility with most IPs and Library.

5 - تجنب المعاقل المستبدة

وإذا استخدمت حزمتك أنواعاً من مجموعة أخرى، فإنها ستتسبب في مسائل نظام التجميع صراحة في إعلان الطرد، ولا تعتمد على وحدة تصميم الآباء التي أدرجت مجموعة التدابير الأخرى.

6 - نسخ حزمتك

إدراج صيغة ثابتة تتتبع النسخة النهائية (مصدر رئيسي)، وهذا يساعد على معالجة قضايا التكامل.

constant PKG_VERSION : string := "1.2";

الشلالات المشتركة وكيفية تجنبها

وحتى المصممين ذوي الخبرة في مجال التنمية البشرية يقعون أحيانا في فخ مع مجموعات، وهنا تكمن المشاكل الأكثر تواترا:

  • Missing package body for functions ]: إذا أعلنت وظيفة في الطرد، يجب أن تقدم تنفيذا في الهيئة الرزمية، حتى لو كان ذلك تافها، فإن الهيئة المفقودة ستتسبب في خطأ تجميعي.
  • Order of compilation]: يجب تجميع هذه المجموعة قبل أي وحدة تصميم تستخدمها، واستخدام مجموعات طلبات تجميع أدوات المحفز أو التوليفي الخاصة بك، أو تجميع مجموعات من المواد في مكتبة منفصلة عن كيانات التصميم.
  • Name conflicts]: إذا أعلنت حزمتان الاسم نفسه، فلا يمكن لـ VHDL أن تحل الإشارة.
  • Package body with no declarations]: من القانوني أن يكون هناك إعلان حزمة بدون برامج فرعية (فقط أنواع/متواثيق) وفي هذه الحالة، لا تحتاج إلى هيئة طرد، ولكن إذا أضيفت لاحقاً برنامجاً فرعياً، يجب أن تضيف الهيئة.
  • Recompilation cascades: Changing a package declaration forces recompilation of all design units that use it. To minimize this, only put stable interfaces in the declaration; put implementation details (like local helper functions) in the package body if they are not needed by other units.
  • Non-synthesizable subprograms]: Functions like file I/O, recursion, or dynamic allocation are not synthesizable.

معرض العالم الحقيقي: مجموعة بسيطة من طراز UART

للتوضيح التطبيق العملي، لنصمم مجموعة من أجل (أوستر) (الإستلام المتزامن مع (ترانسميتر)

package UART_Utils is
 constant DEFAULT_BAUD : positive := 115200;
 constant CLK_FREQ : positive := 50000000; -- 50 MHz

 -- Calculate divisor for baud rate generator
 function Baud_Divider(Baud : positive; Clock_Freq : positive) return natural;

 -- Serialize a byte (LSB first)
 function To_Serial(B : std_logic_vector(7 downto 0)) return std_logic_vector;

 -- Deserialize a 10-bit UART frame (start, 8 data, stop)
 function From_Serial(frame : std_logic_vector(9 downto 0)) return std_logic_vector;

 -- Type for UART state machine
 type UART_State is (Idle, Start, Data, Stop, Error);
end package UART_Utils;

package body UART_Utils is
 function Baud_Divider(Baud : positive; Clock_Freq : positive) return natural is
 begin
 return (Clock_Freq / Baud) - 1;
 end function;

 function To_Serial(B : std_logic_vector(7 downto 0)) return std_logic_vector is
 variable result : std_logic_vector(9 downto 0);
 begin
 result(0) := '0'; -- start bit
 for i in 0 to 7 loop
 result(i+1) := B(i);
 end loop;
 result(9) := '1'; -- stop bit
 return result;
 end function;

 function From_Serial(frame : std_logic_vector(9 downto 0)) return std_logic_vector is
 variable data : std_logic_vector(7 downto 0);
 begin
 for i in 0 to 7 loop
 data(i) := frame(i+1);
 end loop;
 return data;
 end function;
end package body UART_Utils;

ويمكن استخدام هذه المجموعة في كل من أجهزة إرسال وأجهزة استقبال UART، بما يكفل إجراء حسابات ثابتة للمساحة.

خاتمة

إن مجموعات المواد التعريفية VHDL تشكل حجر الزاوية في تصميم المعدات المهنية، وهي تشجع على تطبيق نظام الوحدات، وإعادة الاستخدام، وتساوي الصيانة التي تزداد أهميتها كمنطلق للتصميمات، ومن خلال حصر الأنواع المشتركة والثباتات والبرامج الفرعية، تخفض الازدواجية، وتمنع الأخطاء، وتسهل قاعدة قواعد البيانات الخاصة بك الملاحة والتحديث.

وفي هذه المادة، غطينا مجموعة الحزم وهيكلها، والإنشاء التدريجي، والملامح المتقدمة مثل الحمولة الزائدة والجسيمات، وأفضل الممارسات، والأوراق المشتركة، وسواء كنت تصمم مشروعا صغيرا لمؤسسة FPGA أو نظاما متعدد الأقمشة، فإن اعتماد استراتيجية مجموعة مُنضبطة سيدفع أرباحا في تقليص وقت التنمية وتحسين نوعية التصميم.

For further reading, refer to the IEE Standard VHDL Language Reference Manual (1076-2019) and sales-specific guidelines from Xilinx or Intel. The EDA Playground] is a good online tool for experimenting with package-based designs.