چگونگی استفاده از ساختار Configuration در VHDL

ساختارهای پیکره بندی یا Configuration یکی از مفاهیم پیشرفته در زبان VHDL هستند، و در صورت استفاده صحیح می‌توانند بسیار مفید باشند.
چگونگی استفاده از ساختار Configuration در VHDL

مقدمه

این نوشتار از پایگاه دانش هگزالینکس به بررسی نحوه استفاده از ساختارهای پیکره بندی یا Configuration‌ برای ایجاد انواع متفاوتی از یک ماژول تست بنچ، بدون نیاز به مدیریت چندین نسخه از فایل تست بنچ، می‌پردازد. ما همچنین در مورد سایر کاربردهای ساختارهای پیکره بندی هنگام طراحی با زبان VHDL صحبت خواهیم کرد.

با وجود اینکه ساختارهای Configuration بخشی از استاندارد VHDL از اولین نسخه این زبان هستند. اما هنوز هم، بسیاری از طراحان FPGA ، هرگز از آن‌ها استفاده نکرده و احتمالاً استفاده نخواهند کرد. شاید دلیل آن این باشد که تعداد کمی از مهندسان نحوه عملکرد Configuration ها را درک کرده‌اند. البته این مسأله مایه تأسف است، زیرا استفاده از ساختار Configuration واقعاً چندان پیچیده نیست. من در این مقاله تمام تلاش خودم را به کار گرفته‌ام تا نحوه کار با Configuration ها را به زبانی ساده توصیف کنم و مزایای ویژه‌ای را که با استفاده از آن‌ها حاصل می‌شود، تشریح کنم. امیدوارم در انتهای کار شما چگونگی استفاده از ساختار Configuration در VHDL را فرا بگیرید.

ساختارهای Configuration یکی از مفاهیم پیشرفته در زبان VHDL هستند، و در صورت استفاده صحیح می‌توانند بسیار مفید باشند. این ساختارها به طراح اجازه می‌دهند که برای یک Entity واحد چندین معماری (Architecture) متفاوت تعیین کند. به عبارت دیگر، به کمک ساختار Configuration می‌توان محاسبات داخلی و نحوه عملکرد یک ماژول تغییر داد در حالی که پوسته و ظاهر بیرونی و اینترفیس‌های آن بدون تغییر باقی می‌ماند.

برای اینکه یک ماژول طراحی شده توسط VHDL به خوبی اجرا شود الزامی به استفاده Configuration وجود ندارد، از این رو استفاده از آن‌ها برای شروع فرایند یادگیری زبان VHDL توسط مبتدیان توصیه نمی‌شود.

معمولاً ساختارهای Configuration‌ به یکی از دلایل زیر مورد استفاده قرار می‌گیرند:

  • آزمایش مستقیم: جایگزین کردن ماژول‌هایی که رفتاری مشابه دارند، ولی با الگوریتم‌ها یا الگوهای متفاوتی پیاده سازی شده‌اند را می‌توان به عنوان پایه‌ای ترین کاربرد ساختارهای Configuration‌ در نظر گرفت. نوشتن چندین تست بنچ برای چندین ماژول که port map یکسانی دارند کار زمانبری است، در حالی که با استفاده از ساختارهای Configuration‌ می‌توان از یک تست بنچ واحد برای تست همه پیاده سازی‌ها استفاده کرد.
  • هنگام استفاده از ‌BFM به جای زیر ماژول اصلی: در پروژه‌های بزرگ معمولاً زیر ماژول‌های سیستم همگی با هم آماده نمی‌شوند، اما در عین حال امکان توقف فرایند تست و تجمیع کل سیستم و انتظار برای آماده شدن زیر ماژول آماده نشده نیز وجود ندارد. در چنین مواردی از مجموعه‌ای از رَویه‌ها استفاده می‌شود که به کمک آن، امکان دسترسی به اینترفیس‌های آن زیر ماژول یا زیر سیستم به روشی بسیار ساده فراهم آورده می‌شود. این رَویه‌ها اصطلاحاً‌ Bus Functional Model-BFM نامیده می‌شوند. به کمک ساختارهای Configuration‌ می‌توان به سادگی زیر ماژول‌های نهایی نشده را با BFM‌ جایگزین کرد. البته با توجه به الگوهای جدید ارزیابی و صحه گذاری در سال‌های اخیر، استفاده از BFM به شدت کاهش پیدا کرده است.
  • آزمایش رفتارهای غیر معمول: اگر قصد این را دارید که با اعمال خطا به یک بخش خاص از طرح خودتان رفتار آن را در شرایط کاری خاص و خارج از کنترل بررسی کنید، می‌توانید ماژولی را که قبل از ماژول تحت تست (dut) قرار می‌گیرد با ماژولی که رفتاری غیر معمول و همراه با خطا دارد، جایگزین کنید، در حالی که اینترفیس‌ها و نحوه تبادل داده بین آن‌ها بدون تغییر است. این روش از تست در مواردی که هدف بررسی رفتار غیر متعارف یک ماژول هنگام قرار گرفتن در شرایط پیش بینی نشده باشد، بسیار مفید و موثر است. این تست‌ها اغلب برای بررسی قابلیت اطمینان ماژول‌های حساس انجام می‌شود.
  • تسریع فرایند شبیه سازی: جایگزین کردن یک کد RTL نسبتاً بزرگ با یک کد RTL کوچکتر و یا حتی یک کد RTL خالی به منظور سرعت بخشیدن به فرایند شبیه سازی یکی دیگر از کاربردهای مهم و پر استفاده از ساختارهای Configuration است. به صورت کلی هر چه تعداد سیگنال‌ها و مدارات پیاده سازی شده بیشتر باشد، سرعت شبیه سازی کمتر می‌شود. هنگام بررسی عملکرد و دیباگ یک سیستم می‌توان با جایگزینی برخی از ماژول‌های بزرگ و پیچیده با یک ماژول کوچکتر فرایند شبیه سازی را با سرعت بیشتری روی بخش‌هایی از سیستم که نیاز به خطایابی دارند، اجرا کرد. 

طرح اولیه

اجازه بدهید کار را با بررسی یک طرح اولیه شروع کنیم، و بعد از آن، به معرفی کامل ساختار Configuration و شیوه استفاده از آن بپردازیم. در حقیقت نکته ظریفی که به آن اشاره کردم، یکی از مزایای Configuration ها محسوب می‌شود. این یعنی شما به عنوان طراح در تمام فازهای پیاده سازی قادر به استفاده از Configuration هستید و می‌توانید بر اساس طرح فعلی خودتان از آنها استفاده کنید. در عمل شما فقط نیاز دارید با فراخوانی مستقیم، یک کامپوننت را به طرح پایه خودتان اضافه کنید. این مسأله در ادامه برای شما شفاف می‌شود، پس فعلاً کمی صبر داشته باشید.

طرح اولیه‌ای که در نظر گرفتم، شامل یک تست بنچ و یک ماژول مقایسه کننده است. همانطور که احتمالاً می‌دانید، در ادبیات پیاده سازی سخت افزاری، ماژولی که قرار است تست شود، تحت عنوان ماژول در حال تست (dut) مخاطب قرار داده می‌شود.

ماژول مقایسه کننده (DUT)

ماژولی که با کدهای VHDL زیر توصیف شده است، یک مقایسه کننده است که در آن برابر بودن مقدار دو ورودی بررسی می‌شود. اگر ورودی‌های a و b برابر باشند در این صورت مقدار خروجی q برابر با ‘1’‌ می‌شود. در صورتی که این شرط برقرار نباشد، مقدار q برابر با ‘0’ خواهد بود.

entity comparison is
  port (
    a : in integer;
    b : in integer;
    q : out boolean
  );
end comparison;
 
architecture rtl of comparison is
begin
 
  q <= a = b;
 
end architecture;

ماژول تست بنچ

همانطور که در کد زیر می‌بینید، ماژول مقایسه کننده در تست بنچ فراخوانی شده است. روش فراخوانی این ماژول، فراخوانی کامپوننت (component instantiation) است و نه فراخوانی مستقیم (entity or direct instantiation). حتماً به این نکته وجه داشته باشید که متأسفانه برای استفاده از Configuration ها نمی‌توان از روش فراخوانی مستقیم استفاده کرد و شما همواره باید از روش فراخوانی کامپوننت استفاده کنید. پس حتماً این مسأله را به خاطر بسپارید تا با خطا روبرو نشوید.

architecture sim of comparison_tb is
 
  signal a : integer;
  signal b : integer;
  signal q : boolean;
 
  component comparison
    port (
      a : in integer;
      b : in integer;
      q : out boolean
    );
  end component;
 
begin
 
  DUT : comparison
  port map (
    a => a,
    b => b,
    q => q
  );
 
  SEQUENCER_PROC : process     
  begin
  -- ...
  -- Download the example project to see the full testbench

در آخرین بخش تست بنچ یک sequencer process داریم که به صورت پیاپی مقادیر a و b را تغییر می‌دهد و سپس آن‌ها را به همراه مقدار خروجی q در کنسول سیمولاتور گزارش می‌کند. ناگفته پیداست که هنگام مقایسه دو عدد ممکن است یکی از سه حالت زیر اتفاق بیافتد، پس ما در عمل سه سناریوی تست داریم:

  • مقدار a بزرگتر از b باشد
  • مقدار a کوچکتر از b باشد
  • مقدار a و b‌ برابر باشند

برای اینکه تست بنچ کوتاه تر باشد، فرایند انتهایی تست بنچ را حذف کردم، چون خیلی ساده و ابتدایی است. اما در صورت تمایل می‌توانید کل فایل‌های پروژه را از اینجا دانلود کنید.

شما برای شبیه سازی این کد می‌توانید از هر ابزاری که در اختیار دارید استفاده کنید، اما من پیشنهاد می‌کنم از ModelSim استفاده کنید. برای شبیه سازی کد در محیط ModelSim فقط نیاز دارید دستور vsim را با نام تست بنچ کامپایل شده یعنی work.comparison_tb به عنوان آرگومان ورودی، فراخوانی کنید. بعد از اجرای شبیه سازی با توجه به گزارش تولیدی ModelSim ، در صفحه کنسول مشاهده خواهید کرد که پیغام true فقط زمانی که دو ورودی a و b با هم برابر باشند، نمایش داده می‌شود. دقت کنید که این شبیه سازی فعلاً بدون استفاده از Configuration ها اجرا می‌شود.

ModelSim> vsim work.comparison_tb ; run 100 ns
# vsim work.comparison_tb 
# Loading std.standard
# Loading work.comparison_tb(sim)
# Loading work.comparison(rtl)
# ** Note: a = 10, b = 5, q = false
#    Time: 10 ns  Iteration: 0  Instance: /comparison_tb
# ** Note: a = 5, b = 5, q = true
#    Time: 20 ns  Iteration: 0  Instance: /comparison_tb
# ** Note: a = 5, b = 10, q = false
#    Time: 30 ns  Iteration: 0  Instance: /comparison_tb

استفاده از ساختار Configuration

تا اینجای کار ما یک ماژول مقایسه کننده به نام comparison و یک تست بنچ به نام comparison_tb داریم که  به خوبی کار می‌کنند. در ادامه تصمیم داریم دو ماژول مقایسه کننده دیگر برای بررسی بزرگتر و کوچکتر بودن داده‌های ورودی نسبت به هم به طرح اضافه کنیم و هر کدام از آن‌ها را نیز مستقلاً شبیه سازی کنیم.

برای اجرایی کردن این تصمیم کارهایی که به صورت معمول انجام می‌دهیم به این صورت است:

  1. طراحی یک ماژول مقایسه کننده جدید به نام greater_than و یک تست بنچ جدید به نام greather_than_tb
  2. طراحی یک ماژول مقایسه کننده جدید به نام less_than و یک تست بنچ جدید به نام less_than_tb

به این ترتیب چهار فایل hdl جدید می‌نویسیم، البته بخش‌ زیادی از کدها مشابه هستند، بنابراین به صورت مکرر از کپی و پیست خطوط مشابه استفاده می‌کنیم. اما این کار برای ماژول‌های بزرگ و پیچیده بسی زمان بر و خسته کننده است. راه حل پیشنهادی ما استفاده از ساختار Configuration است. با کمک این ساختار ما به صورت زیر عمل می‌کنیم.

  1. یک ماژول مقایسه کننده جدید به نام greater_than طراحی می‌کنیم و
  2. سپس یک فایل hdl جدید با نام compartion_config.vhd طراحی می‌کنیم و با اعلان پیکره بندی‌های متفاوت درون این فایل، تست بنچ اولیه را با کمک این فایل اجرا می‌کنیم.

دیاگرام زیر یک مرور کلی بر طرح فعلی و کاری که قصد انجام آن را داریم، می‌اندازد. همانطور که گفتم ما تا به اینجا ما با کمک روش فراخوانی کامپوننت، فقط یک نمونه از ماژول مقایسه کننده (کامپوننت dut) را درون تست بنچ فراخوانی کردیم، و قصد تغییر آن را هم نداریم. در ادامه ما از Configuration برای تغییر ارتباطات یا اتصالات ماژولی که در تست بنچ داریم، استفاده خواهیم کرد، و به مشکل موثر از آن بهره خواهیم برد.

چگونگی استفاده از ساختار Configuration در VHDL
دیاگرام کلی از فرایندی که قرار است اجرا شود

اگر هیجان زده هستید و منتظر هستید تا ببینید دقیقاً استفاده از Configuration‌ ها در کد به چه صورت است، بیش از این شما را در این برزخ سیاهی نگه نمی‌دارم. شما کدهای آن را در ادامه در سه زیر بخش بعدی مشاهده خواهید کرد. همانطور که گفتم، ما هر سه اعلان مورد نیاز را در یک فایل VHDL انجام می‌دهیم و نام این فایل را comparison_conf.vhd می‌نامیم.

اما قبل از اینکه به سراغ فایل comparison_conf.vhd برویم اجازه بدهید تا گام اول را اجرا بکنیم و دومین ماژول آماده برای تست را طراحی کنیم. کد زیر یک ماژول جدید با نام greater_than را نشان می‌دهد که آن خطی از کد نسبت به کد اولیه comparison تغییر کرده، برجسته شده است. در واقع این ماژول جدید پیاده سازی دیگری از اپراتور مقایسه گر برای حالت بزرگتر است.

entity greater_than is
  port (
    a : in integer;
    b : in integer;
    q : out boolean
  );
end greater_than;
 
architecture rtl of greater_than is
begin
 
  q <= a > b;
 
end architecture;

حالت تساوی

برای یکدست شدن کار یک بلوک Configuration خالی به نام eq برای بررسی حالت تساوی در ابتدای فایل configuration_conf.vhd اضافه می‌کنم. از نظر مداری این بخش اضافی هیچ کاری انجام نمی‌دهد و روی مدارت منطقی طراحی شده تغییراتی اعمال نمی‌کند، و فقط به ما اجازه می‌دهد که تست بنچ را در سیمولاتور را به روشی مشابه سایر Configuration ها برای مقایسه کننده ای که در ابتدای کار طراحی کرده بودیم، آغاز کنیم.

configuration eq of comparison_tb is
  for sim
  end for;
end configuration;

حالت بزرگتر

دومین بلوک Configuration برخلاف بلوک قبلی یک تغییر جزئی روی مدارات منطقی اعمال می‌کند. ما الزاماً باید هنگام فراخوانی یک بلوک Configuration قوانین زبان VHDL را به طور کامل رعایت کنیم. ما باید فراخوانی بلوک را با کلمه کلیدی Configuration آغاز کنیم، و بعد برای آن یک نام انتخاب کنیم در مثال پیش رو این نام gt (کوتاه شده واژه greater than) در نظر گرفته شده است. این نام بعداً برای تمایز قرار دادن بین پیکره بندی‌های متفاوت استفاده می‌شود. بعد از آن نام Entity را که قرار است به عنوان تاپ ماژول استفاده شود، و این Configuration درون آن فراخوانی شود، تعیین می‌کنیم. در مثال ما این تاپ ماژول همان ماژول تست بنچ یعنی comparison_tb می‌باشد.

configuration CONFIGURATION_NAME of INSTANTIATING_ENTITY is
  for INSTANTIATING_ARCH 
    for INSTANCE_NAME : COMPONENT_NAME
      use entity LIBRARY_NAME.ENTITY_NAME(ARCHITECTURE_NAME);
    end for;
  end for;
end CONFIGURATION_NAME;
configuration gt of comparison_tb is
  for sim
    for DUT : comparison
      use entity work.greater_than(rtl);
    end for;
  end for;
end configuration;

و در نهایت نوبت به مشخص کردن Architecture می‌رسد که با توجه به تست بنچ ما آن را sim نام گذاری کردیم. برای مشخص کردن نام معماری از نوع خاصی از حلقه for استفاده شده است. با استفاده از این حلقه یک کامپوننت جدید جایگزین dut اولیه می‌شود. در مثالی که ما در حال بررسی آن هستیم کامپوننتی که در تست بنچ با برچسب dut فراخوانی شده است، با کامپوننت greater_than جایگزین می‌شود.

حالت کوچکتر

سومین و آخرین بلوکی که باید در فایل Configuration_conf.vhd اعلان کنیم، بلوک کد مربوط به ماژول کوچکتر یا less_than است. کد زیر نحوه اضافه کردن یک Configuration جدید با نام lt را نشان می‌دهد. این بلوک شباهت زیادی به بلوک قبلی دارد زیرا بازهم قرار است یک نمونه از کامپوننت greater_than جایگزین dut شود، با این تفاوت که بخش port map نیز به آن اضافه شده است. این بخش قرار است علاوه بر معماری dut نحوه ارجاع ورودی‌های تست بنچ به ورودی‌های dut را نیز تغییر دهد.

configuration lt of comparison_tb is
  for sim
    for DUT : comparison
      use entity work.greater_than(rtl)
        port map (
          a => b,
          b => a,
          q => q
        );
    end for;
  end for;
end configuration;

اگر کمی موشکافانه به خطوطی از کد که برجسته شده‌اند نگاه کنید، به سادگی متوجه می‌شوید که پورت‌ها برعکس ارجاع داده‌ شده‌اند، و ورودی‌های a و b را جا به جا شد‌اند. در واقع ما به جای نوشتن یک ماژول جدید، با جا به جا کردن سیگنال‌های ورودی ماژول greater_than‌ رفتار آن را به اپراتور مقایسه گر less_than تغییر دادیم.

شبیه سازی ساختارهای Configuration

برای شبیه سازی Configuration ها در ModelSim هیچ دستور ویژه‌ای نداریم. فقط کافیست شبیه سازی با استفاده از نام Configuration به عنوان تاپ ماژول اجرا شود، ابزار سیمولاتور به صورت اتوماتیک Entity و Architecture مورد نظر را با توجه تنظیمات اعمال شده روی Configuration شناسایی و فراخوانی می‌کند.

چگونگی استفاده از ساختار Configuration در VHDL
کتابخانه‌ها در ModelSim

اگر نگاهی به تب library در محیط سیمولاتور ModelSim داشته باشید، مشاهده می‌کنید که بعد از کامپایل نام هر سه Configuration در این بخش وجود دارد. همانطور که در شکل هم می‌بینید عناصر کتابخانه‌ای که با توجه به Configuration ها ایجاد شده است از نوع Config هستند، در حالی که در عمل شبیه یک Entity رفتار می‌کنند.

اجرای تست بنچ برای حالت تساوی

ما پیش تر نام Configuration برای بررسی مساوی بودن دو عدد ورودی را eq نامیدیم. برای شبیه سازی آن می‌توانیم بعد از دستور vsim نام Configuration کامپایل شده را به جای نام تاپ ماژول به عنوان آرگومان ورودی استفاده کنیم. یعنی کافیست تایپ کنیم.

vsim work.eq Instead of vsim work. comparison‌_tb
ModelSim> vsim work.eq ; run 100 ns
# vsim work.eq 
# Loading std.standard
# Loading work.eq
# Loading work.comparison_tb(sim)
# Loading work.comparison(rtl)
# ** Note: a = 10, b = 5, q = false
#    Time: 10 ns  Iteration: 0  Instance: /comparison_tb
# ** Note: a = 5, b = 5, q = true
#    Time: 20 ns  Iteration: 0  Instance: /comparison_tb
# ** Note: a = 5, b = 10, q = false
#    Time: 30 ns  Iteration: 0  Instance: /comparison_tb

شکل بالا خروجی کنسول سیمولاتور ModelSim را نشان می‌دهد. همانطور که انتظار می‌رفت، از ماژول comparison‌ استفاده شده و مقدار true برای خروجی q زمانی که شرط a=b برقرار است، گزارش شده است.

چگونگی استفاده از ساختار Configuration در VHDL
فراخوانی ماژول مقایسه کننده اول به عنوان dut

همچنین بعد از شروع شبیه سازی، به سادگی می‌توان قرار گرفتن نام ماژول compassion(rtl) در مقابل عبارت dut در تب sim را مشاهده کرد. البته، نتایج مشابه زمانی است که تست بنچ را مستقیماً اجرا کردیم، و این بدان معناست که این Configuration هیچ کاری انجام نداده است.

اجرای تست بنچ برای حالت بزرگتر

برای اجرای Configuration مربوط به ماژول greater_than ، باید بلوک Configuration دوم که gt نام دارد را درون کتابخانه work هنگام اجرای شبیه سازی مشخص می‌کنیم، یعنی در کنسول عبارت vsim work.gt را تایپ کنیم:

ModelSim> vsim work.gt ; run 100 ns
# vsim work.gt 
# Loading std.standard
# Loading work.gt
# Loading work.comparison_tb(sim)
# Loading work.greater_than(rtl)
# ** Note: a = 10, b = 5, q = true
#    Time: 10 ns  Iteration: 0  Instance: /comparison_tb
# ** Note: a = 5, b = 5, q = false
#    Time: 20 ns  Iteration: 0  Instance: /comparison_tb
# ** Note: a = 5, b = 10, q = false
#    Time: 30 ns  Iteration: 0  Instance: /comparison_tb

در خروجی کنسول و در تب sim ، ما می‌توانیم ببینیم که این بار dut در حال اجرا، ماژول greater_than (rtl) است. مشاهده می‌کنید که مقدار ture برای خروجی q زمانی که a بزرگتر از b باشد، گزارش می‌شود.

چگونگی استفاده از ساختار Configuration در VHDL
فراخوانی ماژول مقایسه کننده دوم به عنوان dut

اجرای تست بنچ برای حالت کوچکتر

هنگامی که سومین بلوک Configuration‌ را برای ماژول less_than اجرا می‌کنیم، تب sim کاملاً مشابه مثال قبل است. دلیل آن این است که ما همچنان در حال استفاده از ماژول greater_than هستیم. اما می‌توانیم از گزارش زیر بفهمیم که رفتار آن تغییر کرده. این بار q زمانی true می‌شود که a کوچکتر از b باشد.

ModelSim> vsim work.lt ; run 100 ns
# vsim work.lt 
# Loading std.standard
# Loading work.lt
# Loading work.comparison_tb(sim)
# Loading work.greater_than(rtl)
# ** Note: a = 10, b = 5, q = false
#    Time: 10 ns  Iteration: 0  Instance: /comparison_tb
# ** Note: a = 5, b = 5, q = false
#    Time: 20 ns  Iteration: 0  Instance: /comparison_tb
# ** Note: a = 5, b = 10, q = true
#    Time: 30 ns  Iteration: 0  Instance: /comparison_tb

خب ما موفق شدیم ارتباط بین تست بنچ و dut را به شکل صحیح برای هر سه مقایسه کننده، برقرار کنیم و بدون تولید چندین کپی از فایل‌های مشابه‌ها تصمیمی را که در ابتدا گرفته بودیم اجرا کنیم. مطمئناً با کمی تفکر و خلاقیت می‌توان از این قابلیت به خوبی در مثال‌های واقعی که همه روزه با آن سر و کار دارید، استفاده کرد.

سایر کاربردهای ساختار Configuration

همانطور که در ابتدای مقاله اشاره شد، شما می‌توانید عناصر مختلف طراحی در کدهای VHDL‌ را با استفاده از بلوک‌های Configuration جایگزین کنید. از این رو بد نیست چندین رویکرد متفاوت برای استفاده از Configuration ها را بررسی کنیم.

فراخوانی چندین کامپوننت در زیرماژول

در مثال‌هایی که تا به اینجا بررسی کردیم، ما ماژول dut در تست بنچ را با استفاده از بلوک‌های Configuration متفاوت جایگزین کردیم. اما در عمل ما محدودیتی برای استفاده از ساختارهای Configuration در زیر ماژول‌ها نداریم و می‌توانیم به جای تاپ ماژول آن‌ها را در زیر ماژول‌ها فراخوانی کنیم.

در مثال زیر با حرکت به پایین در سلسله مراتب طرح هنگام اجرای شبیه سازی به جای جایگزین کردن dut، برخی از کامپوننت‌های داخل dut را جایگزین می‌کنیم.

configuration gt of comparison_tb is
  for sim
    for DUT : top
      for str
 
        for COMPARE_1, COMPARE_2 : comparison
          use entity work.greater_than(rtl);
        end for;
 
        for all : some_component
          use entity work.some_other_entity(rtl);
        end for;
 
      end for;
    end for;
  end for;
end configuration;

در کد بالا، اولین حلقه for دو کامپوننت را که با برچسب‌های COMPARE_1 و COMPARE_2 فراخوانی شده‌اند با یک کامپوننت دیگر جایگزین می‌کند. حلقه for دوم با استفاده از کلمه کلیدی all که به معنای کلیه نمونه‌های فراخوانی شده از کامپوننت some_componnet است. تمامی فراخوانی‌های کامپوننت مد نظر را با کامپوننت جدید جایگزین می‌کند. فکر می‌کنم به کمک این مثال شما با فلسفه استفاده از حلقه for هنگام استفاده از ساختارهای Configuration آشنا شده باشید. در عمل شما قادر هستید چندین نمونه فراخوانی شده از یک کامپوننت را با استفاده از یک حلقه for جایگزین کنید.

تغییر کتابخانه پیش فرض

اغلب ابزارهای طراحی و شبیه سازی ماژول‌های VHDL‌ را به صورت پیش فرض درون کتابخانه work کامپایل می‌کنند و به همین دلیل است که ما معمولاً این کتابخانه را به کدهای HDL‌ اضافه نمی‌کنیم. هر چند برخی از ابزارها مثل Vivado به جای کتابخانه work‌ از کتابخانه پیش فرض دیگری به نام xil_defaultlib‌ استفاده می‌کنند.

بیایید فرض کنیم که شما به جای کامپایل کدها درون کتابخانه پیش فرض از کتابخانه دیگری استفاده کردید در این صورت شما می‌توانید نام کتابخانه را به صورت زیر تغییر دهید. البته قبل از آن لازم است آن کتابخانه را به خود ضمیمه کنید.

library other_lib;
configuration eq2 of comparison_tb is
  use other_lib.all;
  for sim
  end for;
end configuration;

فراخوانی در طرح اصلی به جای تست بنج

من در این مقاله به شما نشان دادم که چطور می‌توانیم با کمک کنسول سیمولاتور شبیه سازی را اجرا کنیم. اما این تنها قابلیتی که در اختیار ما قرار داده شده است، نیست. کدهای زیر نحوه فراخوانی اولین بلوک Configuration که eq نام داشت را در طرح اصلی نشان می‌دهد. روش کار کاملاً مشابه فراخوانی یک کامپوننت است، با این تفاوت که به جای کلید واژه component باید از کلید واژه configuration استفاده شود.

DUT : configuration work.eq
port map (
  a => a,
  b => b,
  q => q
);

جمع بندی

تصور من این است که ساختارهای پیکره بندی بسیار مفید هستند و بهتر است بیشتر از آن‌ها استفاده کنیم. هر زمان که نیاز باشد نسخه‌های متفاوتی از یک طرح را مدیریت کنیم، بد نیست اول بررسی کنیم که آیا این تفاوت بسیار گسترده است یا فقط محدود به چند زیر ماژول است. در صورتی که فقط بخش‌های محدودی تغییر می‌کند مطمئناً استفاده از ساختار‌های پیکره بندی می‌تواند بهتر از کپی کردن چند باره کد تاپ ماژول باشد.

علاوه بر این، یک مورد استفاده مناسب از Configuration ها زمانی است که قرار است نسخه‌های مختلف از یک کد مورد ارزیابی قرار بگیرند. در چنین شرایطی می‌توان آن‌ها را به سادگی درون کتابخانه‌های مجزا کامپایل کرد و بین آن‌ها سوئیچ کرد.

و در نهایت، چگونگی استفاده از ساختار Configuration نسبتاً آسان است. با وجود اینکه یکی از قابلیت‌های پیشرفته زبان VHDL‌ محسوب می‌شود اما دستورالعمل بکارگری آن‌ها در صورت رسیدن به یک درک صحیح، کاملاً سر راست است.

منبع: با اقتباس از vhdlwhiz

اشتراک در
بیشتر بخوانیم
چرا باید FGA یاد بگیریم؟ عمومی

چرا باید FPGA یاد بگیریم؟

پاسخ به این سوأل که چرا باید FPGA یاد بگیریم یک بله یا خیر ساده نیست. در ایران تنها زمین بازی برای علاقمندان به طراحی سخت افزارهای دیجیتال FPGA است.

نکات و تکنیک‌های طراحی با Vivado HLS سنتز سطح بالا

نکات و تکنیک‌های طراحی با Vivado HLS (بخش دوم: کتابخانه‌های Arbitrary Precision)

با بهره گیری از کتابخانه‌های arbitrary precision می‌توان به جای متغیرهای float از متغیرهای fixed point درون کدهای HLS استفاده کرد.

نمایش اعداد اعشاری ممیز ثابت توصیف سخت افزاری

اعداد اعشاری ممیز ثابت (بخش سوم: قوانین پایه محاسبات)

اعداد ممیزثابت همان اعداد اعشاری هستند که با استفاده از یک فاکتور معین مقیاس بندی می‌شوند. این باعث می‌شود قوانین خاصی بر محاسبات ممیز ثابت حاکم شود.

نه باور نادرست در مورد سنتز سطح بالا سنتز سطح بالا

نُه باور نادرست در مورد سنتز سطح بالا

سنتز سطح بالا را می‌توان به عنوان یک ابزار کارآمد با بهره وری قابل قبول برای طراحی سخت افزار در نظر گرفت، هر چند چندین حقیقت ناگفته پیرامون این مفهوم وجود دارد.

عناوین مطالب
    برای شروع تولید فهرست مطالب ، یک هدر اضافه کنید

    2 در مورد “چگونگی استفاده از ساختار Configuration در VHDL”

    دیدگاه‌ خود را بنویسید

    نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

    اسکرول به بالا