قابلیت های Verilog
استفاده از قابلیتهای زبانی 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];