قابلیت های Verilog

نوع خبر: مطالب مفید کاربردی
تاریخ: 1398/07/09

استفاده از قابلیتهای زبانی Verilog برای سیمکشی آرایهای از ماژولهای یکسان

آیا تا به حال شده که آرایهای از ماژولهای یکسان را بخواهید در Verilog مشابه شکل زیر سیم کشی کنید. هرچند که این مثال ساختگی است ولی مشابه یک معماری آرایه ضرب کننده است. با کمی تامل معلوم میشود که کد نویسی آن کمی دردسر دارد.

 

ابتدا بیاید یک ردیف آن را پیاده کنیم:

روش دستی:

module row(A, B, R)

input [3:0] A;

input B;

output [3:0] R;

block b1 (A[3], B, R[3]);

block b2 (A[2], B, R[2]);

block b3 (A[1], B, R[1]);

block b4 (A[0], B, R[0]);

endmodule

با استفاده از قابلیت زبان Verilog:

module row(A, B, R)

input [3:0] A;

input B;

output [3:0] R;

block b [3:0] (A, B, R);

endmodule

اوه...!! چه اتفاقی افتاد؟ ما 4 بلوک را یکباره تعریف کردیم.

: چگونه سیم کشی و پورتها وصل شده اند؟

قانون 1: پورت ورودی انتظار n بیت دارد و شما یک بردار n  بیتی دادهاید، پس این سیگنال به همه ماژولها کامل وصل میشود. مثل سیگنال B در خط مشخص شده

block b [3:0] (A, B, R);

سیگنال B یک بیتی است و ماژول block یک بیت میخواهد، پس B به همه ماژولها وصل میشود (همانند شکل 2).

قانون 2: پورت ورودی/خروجی انتظار n بیت دارد و شما یک بردار m*n بیتی دادهاید (که m تعداد ماژولهاست)، در آنصورت ماژول اول n بیت اول را میگیرد، ماژول دوم n بیت دوم و الی آخر. در کد مشخص شده سیگنال A و R این گونه وصل شده اند. بیتهای سیگنال A از صفر تا 3 به ترتیب به ماژولهای صفر، 1، 2 و 3 وصل میشود.

تا اینجا یک ردیف را ساختیم، حال کل آرایه را میخواهیم بسازیم. اجازه دهید شکل قسمت اول را به صورت زیر ترسیم کنیم:

 

module row(A, B, Rin, Rout)

input [3:0] A;

input B;

input [3:0] Rin;

output [3:0] Rout;

block b [3:0] (A, B, Rin, Rout);

endmodule

همانند ماژول row است که قبلا پیاده کردیم با این تفاوت که هر ردیف خروجی ردیف قبلی را به عنوان Rin می گیرد. حال کل آرایه را مینویسیم:

module array(A, B, R)

input [3:0] A;

input [3:0] B;

output [3:0] R;

row array_row [3:0] (A, B, Rin, Rout);

assign R = Rout;

endmodule

آیا به همین راحتی درست شد! چه چیزی اشتباه است؟

در خط مشخص شده سیگنال A مطابق قانون اول به همه ماژولها میرود و B مطابق قانون 2 توزیع میشود. اما برای Rin و Rout که در واقع اتصال خروجی Rout ردیف (ماژول) قبلی به ورودی Rin ردیف (ماژول) بعدی است از ترفند زیر استفاده می کنیم:

module array(A, B, R)

input [3:0] A;

input [3:0] B;

output [3:0] R;

wire [15:0] Rin;

wire [15:0] Rout;

 

assign Rin[3:0] = 4’b0000;

assign Rin[15:4] = Rout[11:0];

row array_row [3:0] (A, B, Rin, Rout);

assign R = Rout[15:12];

endmodule

برای ردیف (ماژول) اول Rin صفر است:

assign Rin[3:0] = 4’b0000;

این خط هم رابطه بین خروجی ردیف قبلی و ورودی ردیف بعدی را ایجاد میکند:

assign Rin[15:4] = Rout[11:0];

خروجی نهایی هم از آخرین ردیف (ماژول) گرفته میشود:

assign R = Rout[15:12];