مقدمه
ماژول Barrel Shifter یک مدار دیجیتال است که قابلیت شیفت متغییر دادههای ورودی را بدون استفاده از مدارات ترتیبی دارد. مدار Barrel Shifter کاملا ترکیبی است و در معماری آن، به جای استفاده از فلیپ فلاپ یا سایر المانهای حافظه از مالتیپلکسر استفاده میشود. ماژول Barrel Shifter به شکل گستردهای در پردازندهها مورد استفاده قرار میگیرد. اما IP Core آماده برای آن در FPGA وجود ندارد.
در این آموزش از پایگاه دانش هگزالینکس قصد داریم تا به نحوه پیادهسازی ماژول Barrel Shifter بپردازیم. معماری این ماژول را به صورت کاملاً دقیق بررسی میکنیم. منابع مصرفی و ملاحظات طراحی را مرور میکنیم و تکنیکهای پیشرفته طراحی برای کاهش منابع مصرفی و افزایش انعطاف پذیری طرح را آموزش میدهیم. پس تا انتها همراه ما باشید.
معرفی ماژول Barrel Shifter
احتمالا شما هم هنگام پیادهسازی یک الگوریتم روی FPGA به مداری که نیاز به انجام شیفت متغیر داشته باشد، برخورد کردهاید. مدار Barrel Shifter یک مدار ترکیبی است که قابلیت انجام شیفت متغیر چند بیتی را به تعداد دلخواه در یک کلاک فراهم میآورد. معماری یک Barrel Shifter که قابلیت شیفت به راست را دارد در شکل (۱) نشان داده شده است. که در آن Y
، X
و S
به ترتیب بیانگر ورودی، خروجی و سیگنال شیفت است.
فرض کنید X
یک سیگنال بدون علامت n بیتی باشد که به عنوان ورودی وارد ماژول Barrel Shifter میشود. در این صورت سیگنال Y
و S
به ترتیب n و ((n)log2)ceil بیتی خواهند بود. سیگنال Y
درواقع خروجی ماژول است که با توجه به مقدار S
شیفت داده شده است. تابع ceil به معنای گرد کردن به بالا است. یعنی متغیر ورودی به نزدیکترین عدد صحیح ورودی که بزرگتر یا مساوی ((n)log2) باشد، گرد میشود. به عنوان مثال همانطور که در شکل بالا نشان داده شده است. سیگنالهای X
و Y
هر دو ۸ بیتی هستند و سیگنال S
دارای ۳ بیت است.
یک Barrel Shifter عملیات شیفت را به ((n)log2)ceil طبقه تقسیم میکند. فرض کنید Si بیت شماره i-ام سیگنال S
باشد. در این صورت با توجه به مقدار Si ، یک شیفت صفر یا 2Si -1 بیتی در طبقه i-ام صورت میگیرد.
میتوان نشان داد که تعداد مالتی پلکسرهای دو به یک برای پیادهسازی ماژول Barrel Shifter برابر با n×Log2(n) است. بنابراین هر چه تعداد بیتهای سیگنال ورودی کمتر باشد. ساختار و پچیدگی مدار پیادهسازی شده کاهش مییاید. نکتهای که باید به آن توجه شود این است که در حالت کلی ماژول Barrel Shifter یک مدار یکطرفه است و تنها قابلیت شیفت به یک جهت (شیفت به راست یا چپ) را دارد. سوال اینجاست که آیا میتوان مداری طراحی کرد که امکان شیفت در هر دو جهت را به صورت همزمان دارا باشد؟
ماژول Barrel Shifter دو طرفه
برخی مواقع لازم است که یک مدار قابلیت شیفت دو طرفه داشته باشد. بعنوان مثال مداری را در نظر بگیرید که در آن به جای شیفت ورودی به اندازه ۸ بیت به سمت راست، نیازمند مداری هستیم که قابلیت شیفت ۳ بیت به سمت راست و ۳ بیت به سمت چپ را دارا باشد. پیاده سازی چنین مداری در ابتدا ممکن است کمی سخت به نظر برسد. اما ما در اینجا با یک تکنیک ساده این کار را به شما آموزش میدهیم. اولین راه حلی که برای طراحی مدار Barrel Shifter دو طرفه ممکن است به ذهن شما برسد راهکاری متشکل از:
- دو مدار Barrel Shifter یک طرفه
- و یک مدار اضافی برای کنترل عملیات شیفت است.
اما یک راهکار جالب برای جایگزین کردن Barrel Shifter دو طرفه خصوصاً زمانی که مجموع ماکزیمم شیفت به چپ و راستهای مورد نیاز از n کمتر باشد، این است که تمامی مقادیر شیفتهای مورد نیاز را به اعداد نامثبت نگاشت میکنیم. برای این کار تمامی شیفتهای مورد نظر را از مقدار شیفت ماکزیمم (مثلا مقدار Svmax) کم میکنیم. در این صورت در این مدار Barrel Shifter دو طرفه را میتوان با یک مدار Barrel Shifter که فقط شیفت به راست میدهد، جایگزین کرد. در انتها نیز خروجی مدار را باید به اندازه این حداکثر شیفت مجاز Svmax به سمت چپ شیفت داد. تا تاثیر نگاشت فوق جبران شود. به این ترتیب عمل شیفت به دو فاز تقسیم میشود:
- شیفت به راست اعداد نگاشت شده با استفاده از barrel shifter یک طرفه
- شیفت به چپ ثابت خروجی به تعداد Svmax بیت
نکته جالبی که باید به آن اشاره کرد این است که یک LUT شش ورودی قابلیت پیادهسازی دو مالتی پلکسر دو به یک دارد. لذا در شکل فوق هر دو مالتی پلکسر مجاور با یک LUT شش ورودی قابل پیادهسازی هستند.
پیادهسازی ماژول Barrel Shifter
در ادامه باهم معماری و کدهای HDL یک مدار Barrel Shifter یک طرفه را مرور میکنیم.
در سمت راست شکل (۲) بلوک دیاگرام یک Barrel Shifter را نشان داده شده است. ورودی یک سیگنال ۸ بیتی با نام inp
است. و خروجی نسخه شیفت یافته ورودی است و outp
نام گذاری شده است. میزان این شیفت با توجه به تعداد مشخص شده روی پورت ورودی shift
تعیین ميشود. این مقدار میتواند بین صفر تا هفت باشد. مدار از سه Barrel Shifter مستقل تشکیل شده است. این سه مدار کاملا مشابه هستند و تنها ورودیهای متفاوت دارند.
در سمت چپ شکل (۲) مدار ساده یک طبقه Barrel Shifter را نشان داده شده است. این مدار قادر است سیگنال ورودی ۸ بیتی را به اندازه صفر یا یک بیت به سمت چپ شیفت دهد. اگر شیفت برابر یک باشد ('shift='1'
) آنگاه یک مقدار '0'
در کم ارزشترین بیت ورودی قرار داده میشود و سایر بیتها یک بیت به سمت چپ شیفت داده میشوند. اگر شیفت برابر صفر باشد (shift='0'
) باشد. آنگاه ورودی و خروجی با هم برابر خواهند بود یعنی (inp=outp
) میشود.
توجه شود که اولین Barrel Shifter تنها یک '0'
به اولین مالتی پلکسر متصل شده است. در حالی که مالتی پلکسر دوم دارای دو و سومی دارای چهار '0'
است. برای بردارهای بزرگتر، تعداد '0'
ها به همین صورت افزایش پیدا میکنند. اگر مقدار shift="001"
باشد. فقط اولین Barrel Shifter باعث اعمال یک شیفت در مدار میشود. از سوی دیگر اگر شیفت shift="111"
، آنگاه هر سه طبقه باعث اعمال شیفت روی ورودی میشوند. شما میتوانید عملکرد این مدار را با استفاده از یک testbench ساده بررسی کنید.
-- copyright 2019 Hexalinx.com -- simple 8 bit barrel shifter / shift zero or one bit library ieee; use ieee.std_logic_1164.all; entity barrel is generic (N: integer := 8); port ( inp: in std_logic_vector (N-1 downto 0); shift: in std_logic; outp: out std_logic_vector (N-1 downto 0)); end barrel; architecture behavior of barrel is begin process (inp, shift) begin if (shift='0') then outp <= inp; else outp(0) <= '0'; for i in 1 to inp'high loop outp(i) <= inp(i-1); end loop; end if; end process; end behavior;
-- copyright 2019 Hexalinx.com -- simple 8 bit barrel shifter / shift from zero to seven bit library ieee; use ieee.std_logic_1164.all; entity barrel is generic (N: integer := 8); port ( inp: in std_logic_vector (N-1 downto 0); shift: in std_logic_vector (2 downto 0); -- log2(N)-1 outp: out std_logic_vector (N-1 downto 0)); end barrel; architecture behavior of barrel is begin process (inp, shift) variable temp1: std_logic_vector (N-1 downto 0) := (others => '0'); variable temp2: std_logic_vector (N-1 downto 0) := (others => '0'); begin ---- 1st shifter ----- if (shift(0)='0') then temp1 := inp; else temp1(0) := '0'; for i in 1 to inp'high loop temp1(i) := inp(i-1); end loop; end if; ---- 2nd shifter ----- if (shift(1)='0') then temp2 := temp1; else for i in 0 to 1 loop temp2(i) := '0'; end loop; for i in 2 to inp'high loop temp2(i) := temp1(i-2); end loop; end if; ---- 3rd shifter ----- if (shift(2)='0') then outp <= temp2; else for i in 0 to 3 loop outp(i) <= '0'; end loop; for i in 4 to inp'high loop outp(i) <= temp2(i-4); end loop; end if; end process; end behavior;
جمع بندی
شاید پیادهسازی ماژول Barrel Shifter در بسیاری از کاربردها مورد نیاز نباشد. اما چالش طراحی یک مدار ترکیبی برای شیفتهای متعدد کار با ارزشی است. در این آموزش ما به شکل خلاصه شما را با مفهوم مدارات شیفت دهنده ترکیبی و معماری داخلی آنها آشنا کردیم. سپس یک تکنیک ساده برای تبدیل Barrel Shifter یک طرفه مدار Barrel Shifter دو طرفه را دارد، معرفی کردیم. در نهایت نیز پیادهسازی آن را باهم بررسی کردیم. پیشنهاد میکنیم برای تمرین هم که شده مدار Barrel Shifter دو طرفه را پیاده سازی کنید، تا لذت یادگیری دو جندان شود.