Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

Parameters

جزء من قسم الأساسيات في رحلة Verilog على Coddy — الدرس 11 من 90.

يمكنك إنشاء نسخ عديدة من نفس الوحدة (module) واستخدامها في أماكن مختلفة — وهذا ما يسمى **بالنسخ المتعددة (multiple instances)**. فبدلاً من كتابة الكود نفسه مراراً وتكراراً، يمكنك كتابته مرة واحدة وإعادة استخدامه لعدد المرات التي تحتاج إليها. وتعد كل نسخة (instance) بمثابة نسخة منفصلة من ذلك العتاد على الرقاقة.

ولكن ماذا لو كنت بحاجة إلى أن تكون كل نسخة مختلفة؟ على سبيل المثال، عداد واحد بسعة 8 بت، وعداد واحد بسعة 16 بت، وعداد واحد بسعة 32 بت. بدون المعاملات (parameters)، ستحتاج إلى كتابة ثلاث وحدات (modules) منفصلة.

المعاملات تحل هذه المشكلة.

المعامل (parameter) هو قيمة ثابتة يمكنك تعيينها عند إنشاء مثيل (instance). يتيح لك ذلك تهيئة كل نسخة من الوحدة (module) بشكل مختلف.

التصريح عن المعاملات (Parameters)

module counter #(
  parameter WIDTH = 8
)(
  input clk,
  output reg [WIDTH-1:0] count
);
  always @(posedge clk) count <= count + 1;
endmodule

يحدد #(parameter WIDTH = 8) معلمة تسمى WIDTH بقيمة افتراضية قدرها 8.

عند التصريح عن المعاملات (parameters)، نستخدم الرمز # مباشرة بعد اسم الوحدة (module name) و قبل قائمة المنافذ (port list). يخبر الرمز # لغة Verilog أن ما يليه هو قائمة من المعاملات التي تقوم بتهيئة الوحدة. إذا لم تكن وحدتك تحتوي على معاملات، فببساطة يمكنك حذف # تماماً.

استخدام المعاملات (Parameters)

يمكن استخدام المعاملات في أي مكان يلزم فيه وجود ثابت:

reg [WIDTH-1:0] data;        // حجم المتجه
count <= count + 1;           // يعمل مع أي عرض
assign out = data[WIDTH-1];   // موقع MSB

تجاوز المعلمات

عند استخدام الوحدة (module)، يمكنك تغيير قيمة المعلمة (parameter):

// العرض الافتراضي (8 بت)
counter u1 (.clk(clk), .reset(reset), .count(count1));

// التجاوز إلى 16 بت
counter #(.WIDTH(16)) u2 (.clk(clk), .reset(reset), .count(count2));

معلمات متعددة

يمكنك الحصول على معلمات متعددة:

module fifo #(
  parameter DEPTH = 16,
  parameter WIDTH = 8
)(
  input clk, wr_en, rd_en,
  input [WIDTH-1:0] data_in,
  output [WIDTH-1:0] data_out
);
  reg [WIDTH-1:0] memory [0:DEPTH-1];
endmodule

Localparam

الـ localparam مشابه ولكنه لا يمكن تجاوزه من الخارج:

module example;
  localparam STATE_IDLE = 2'b00;
  localparam STATE_RUN = 2'b01;
  localparam STATE_STOP = 2'b10;
  // هذه القيم ثابتة داخل هذا الـ module
endmodule

استخدم localparam للثوابت التي لا ينبغي أن تتغير.

challenge icon

التحدي

أضف بارامتر يسمى WIDTH بقيمة افتراضية هي 4.

ما يجب فعله:

  1. أضف بارامتر باسم WIDTH
  2. اضبط قيمته الافتراضية على 4
  3. يوضع البارامتر داخل #( ) بعد اسم الـ module

ورقة مرجعية

تسمح المعاملات (Parameters) بتهيئة مثيلات الوحدة (module instances) بشكل مختلف دون إعادة كتابة الكود.

الإعلان عن المعاملات

module counter #(
  parameter WIDTH = 8  // default value
)(
  input clk,
  output reg [WIDTH-1:0] count
);
  always @(posedge clk) count <= count + 1;
endmodule

تجاوز المعاملات عند إنشاء المثيل (Instantiation)

counter u1 (.clk(clk), .count(count1));          // uses default (8)
counter #(.WIDTH(16)) u2 (.clk(clk), .count(count2)); // overridden to 16

معاملات متعددة

module fifo #(
  parameter DEPTH = 16,
  parameter WIDTH = 8
)( ... );

Localparam (ثابت غير قابل للتجاوز)

localparam STATE_IDLE = 2'b00;
localparam STATE_RUN  = 2'b01;

استخدم localparam للثوابت الداخلية التي يجب عدم تغييرها من خارج الوحدة.

جرّب بنفسك

module counter #(
  // أضف المعامل WIDTH هنا بالقيمة الافتراضية 4
  
)(
  input clk,
  input reset,
  output reg [WIDTH-1:0] count
);

endmodule
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس الأساسيات