تصميم معالج فيريلوج


الجزء الأول
الجزء الثاني
الجزء الثالث
الجزء الرابع
الجزء الخامس

نقوم بتصميم كمبيوتر ليتل مان في فيريلوج.

المقالة حول LMC كانت على حبري.

جهاز محاكاة عبر الإنترنت لهذا الكمبيوتر هنا .

نكتب وحدة RAM / RAM تتكون من أربع (N = 2) أربع كلمات (M = 4) كلمات. يتم تحميل البيانات في ذاكرة الوصول العشوائي من data_in في adr عند النقر فوق الزر:
module R0 #(parameter N = 2, M = 4) ( input RAM_button, // input [N-1:0] adr, // input [M-1:0] data_in, //   output [M-1:0] RAM_out //   ); reg [M-1:0] mem [2**N-1:0]; //  mem always @(posedge RAM_button) //    mem [adr] <= data_in; //     data_in assign RAM_out = mem[adr]; // RAM_out    endmodule 

كمولد خارجي ، قم بتوصيل مؤقت 555 CMOS (يعمل من 3.3V).
نقوم بتوصيل المؤقت 555 بالعداد ، وربط العداد بإدخال عنوان RAM :
 module R1 #(parameter N = 2, M = 4) ( input timer555, RAM_button, //input [N-1:0] adr, input [M-1:0] data_in, output [M-1:0] RAM_out ); reg [1:0]counter; //  always @(posedge timer555) //    counter <= counter + 1; //    1 wire [N-1:0] adr; assign adr = counter; //       reg [M-1:0] mem [2**N-1:0]; always @(posedge RAM_button) mem [adr] <= data_in; assign RAM_out = mem[adr]; endmodule 

هنا ، عند وصف العداد وذاكرة الذاكرة ، يتم استخدام التعيينات غير المحظورة <= يتم النظر في عوامل التعيين على موقع marsohod.org هنا
وصف العداد موجود على marsohod.org هنا

أضف وظيفة التنزيل إلى العداد.
يتم التنزيل باستخدام الأمر Counter_load :
 //input Counter_load; wire [3:0] branch_adr; //   assign branch_adr = data_in; always @(posedge timer555) begin if(Counter_load) //  "Counter_load"    "branch_adr" counter <= branch_adr; else counter <= counter + 1; end 


في وحدة منفصلة ، قم بإنشاء سجل 4bit (البطارية):
 module register4 ( input [3:0] reg_data, input reg_button, output reg [3:0] q ); always @(posedge reg_button) q <= reg_data; endmodule 

قم بإضافة المجمع ، معدد الإرسال MUX2 والمجمّع الإجمالي إلى الدائرة العامة.
يضيف المصمم إلى الرقم في أرقام Acc البطارية من الذاكرة.
يتم إعطاء مدخلات إشارة معدد الإرسال أرقام data_in و sum .
بعد ذلك ، يتم تحميل الرقم من معدد الإرسال MUX2 في بطارية Acc :
 module R2 #(parameter ADDR_WIDTH = 2, DATA_WIDTH = 4) ( input timer555, Counter_load, RAM_button, input MUX_switch, input Acc_button, input [3:0] data_in, output [3:0] Acc, output [DATA_WIDTH-1:0] RAM, output reg [1:0] counter ); wire [1:0] branch_adr; assign branch_adr = data_in[1:0]; //Counter always @(posedge timer555) begin if(Counter_load) counter <= branch_adr; else counter <= counter + 1; end wire [ADDR_WIDTH-1:0] adr; assign adr = counter; //RAM reg [DATA_WIDTH-1:0] mem [2**ADDR_WIDTH-1:0]; always @(posedge RAM_button) mem [adr] <= Acc; assign RAM = mem[adr]; //sum wire [3:0] sum; assign sum = Acc + RAM; //MUX reg [3:0] MUX2; always @* // Always @* —  «» MUX2 = MUX_switch ? sum : data_in; //Accumulator register4 Acc_reg( .reg_data(MUX2), .reg_button(Acc_button), .q(Acc) ); endmodule 

تعني @ @ دائمًا "دائمًا". بعض المُركِّبات لا يفهمون هذا التصميم. يمكن أيضًا كتابة معدد إرسال بدون Always @ * (هنا يتم استخدامه كمثال).


الطرح


من أجل إجراء الطرح ، من الضروري تقديم رقم مطروح في رمز إضافي . يمكنك أن تقرأ عن الجمع والطرح من الأرقام الثنائية في الكتاب المدرسي "الدوائر الرقمية وهندسة الكمبيوتر" (ديفيد م. هاريس وسارة ل. هاريس) في الفصل 1.4.6 علامة الأرقام الثنائية

أضف إلى الوحدة الرئيسية عنصرًا يطرح من الرقم الموجود في البطارية الأرقام المخزنة في الذاكرة:
 wire [3:0] subtract; assign subract = Acc - RAM ; 

استبدل معدد الدخل ثنائي المدخلات بـ 4 مدخلات:
 always @* MUX4 = MUX_switch[1] ? (MUX_switch[0] ? RAM : subtract) : (MUX_switch[0] ? sum : data_in); 

نقوم بتوصيل جهاز الإخراج بالبطارية (4bit'ny register) ، ونقوم أيضًا بتوصيل علامتين للبطارية:

1. العلم "صفر" هو سجل. العنصر 4 أم لا. يتم رفع العلم إذا كانت محتويات الحمار صفر.

2. العلم "صفر أو رقم موجب" هو سجل. العنصر ليس على المستوى العالي للبطارية 4 بت. يتم رفع العلم إذا كانت محتويات الحمار أكبر من أو تساوي الصفر.

 // "" output Z_flag; assign Z_flag = ~(|Acc); // 4-  - // "   " output PZ_flag; assign PZ_flag = ~Acc[3]; 


4 أو لا
وصفنا هنا صمامًا متعدد المدخلات أو ليس ~ (| Acc)
يدعم Verilog أيضًا مجموعة من أنواع البوابة.

يتم تحديد الكلمات الرئيسية التالية للبوابات المنطقية: و (AND) و nand (AND-NOT) أو (OR) و (OR-NOT) و xor (Exclusive OR) و xnor (Exclusive OR-NOT) و buf (Buffer element) لا (نفي ، لا).

في Verilog ، عند استخدام البوابات ، يجب تحديد المدخلات والمخرجات للعنصر ، وكذلك (اختياريًا) اسم البوابة. على سبيل المثال ، يجب أن يحتوي الصمامان و / أو الصمامات على مخرج واحد ومدخلين أو أكثر. لذا ، بالنسبة للصمام ولا يوجد لدينا
ولا اسم list_of_ الوسائط
ولا mynor (out، in0، in1، in2، in3) ؛




أضف ثلاثة فرق

1. تحميل محتويات البطارية في جهاز إخراج البيانات
2. تحميل العنوان في العداد إذا تم رفع العلم "صفر" ( JMP if Acc = 0)
3. تحميل العنوان في العداد إذا تم رفع العلم "صفر أو رقم موجب" ( JMP if Acc > = 0)

 module R3 #(parameter ADDR_WIDTH = 2, DATA_WIDTH = 4) ( input timer555, RAM_button, input JMP, Z_JMP, PZ_JMP, input [1:0] MUX_switch, input Acc_button, input Output_button, input [3:0] data_in, output [3:0] Acc, output [3:0] data_out, output [DATA_WIDTH-1:0] RAM, output Z_flag, PZ_flag, output reg [1:0] counter ); wire [1:0] branch_adr; assign branch_adr = data_in[1:0]; wire Z,PZ; assign Z = Z_flag & Z_JMP; assign PZ = PZ_flag & PZ_JMP; //Counter always @(posedge timer555) begin if(JMP|Z|PZ) counter <= branch_adr; else counter <= counter + 1; end wire [ADDR_WIDTH-1:0] adr; assign adr = counter; //RAM reg [DATA_WIDTH-1:0] mem [2**ADDR_WIDTH-1:0]; always @(posedge RAM_button) mem [adr] <= Acc; assign RAM = mem[adr]; //sum wire [3:0] sum; assign sum = Acc + RAM; //subtract wire [3:0] subtract; assign subtract = Acc - RAM; //MUX reg [3:0] MUX4; always @* MUX4 = MUX_switch[1] ? (MUX_switch[0] ? RAM : subtract) : (MUX_switch[0] ? sum : data_in); register4 Acc_reg( .reg_data(MUX4), .reg_clk(Acc_button), .q(Acc) ); register4 Output_reg( .reg_data(Acc), .reg_clk(Output_button), .q(data_out) ); assign Z_flag = ~(|Acc); assign PZ_flag = ~Acc[3]; endmodule 



نضع الأوامر والعناوين في ذاكرة الوصول العشوائي / ذاكرة الوصول العشوائي ، والبيانات في أخرى.



يمكن تنزيل المخطط من هنا .

في الثمانية أرقام الأولى ، يتم تخزين الأوامر ، في آخر أربعة أرقام يتم تحميل العنوان في العداد.

بشكل عام ، يجب أن يتم تحميل رقم في بطارية Ass بعد تبديل جهاز الإرسال المتعدد MUX (لأوامر ADD و SUB و LDA ) ، وفقًا لتسوس الساعة.

T.O. في جهاز الكمبيوتر لدينا نظام الأوامر التالي

48x - أضف رقمًا من RAM إلى Ass
50x - SUB يطرح الرقم المخزن في ذاكرة الوصول العشوائي من Ass
80x - STA حفظ الرقم من الحمار البطارية إلى ذاكرة الوصول العشوائي في العنوان س
58x - LDA تحميل رقم من العنوان x في Ass
04x - BRA انتقال غير مشروط إلى الخلية بالعنوان x
02x - انتقال BRZ إلى الخلية التي تحمل العنوان x ، إذا كان Ass = 0 (انتقال شرطي)
01x - انتقال BRP إلى الخلية ذات العنوان x ، إذا كان Ass> = 0 (انتقال شرطي)
40x - يقوم INP بتحميل رقم من data_input في Ass
20x - OUT قم بتحميل الرقم من Ass إلى data_out

لن يكون لدينا فريق HLT .

خذ على سبيل المثال خوارزمية العثور على رقمين كحد أقصى من الموقع http://peterhigginson.co.uk/LMC/

تعمل الخوارزمية على النحو التالي: نقوم بتخزين رقمين من data_in في ذاكرة البيانات. اطرح الأول من الرقم الثاني:

  • إذا كانت النتيجة سلبية ، اكتب الرقم الأول في Ass ، اكتب الرقم من Ass في data_out ؛
  • إذا كانت النتيجة إيجابية ، اكتب الرقم الثاني في Ass ، اكتب الرقم من Ass في data_out.

00 INP
01 STA 11
02 INP
03 STA 12
04 SUB 11
05 BRP 08
06 LDA 11
07 BRA 09
08 LDA 12
09 OUT


في نظام الأوامر لدينا ، ستبدو هذه الخوارزمية على هذا النحو

400
80b
400
80c
50b
018
58b
049
58c
200



العنصر NOT في إدخال التحكم في العداد المطلوب لتحميل البيانات في العداد هو ميزة من ميزات برنامج Logisim ؛ في المخططات الحقيقية ، لا يلزم العنصر NOT في إدخال التحكم (على الأقل لا أعرف مثل هذه العدادات).

يمكن تحميل Quartus II من الموقع الرسمي.

عند التسجيل تحت وظيفة وظيفتي الأساسية * ، حدد الطالب.
بعد ذلك ، تحتاج إلى تنزيل برنامج التشغيل للمبرمج (يمكن تثبيت برنامج تشغيل USB-blaster من C: \ altera \ ... \ quartus \ drivers \ usb-blaster).

يمكن تنزيل Logisim هنا .

Source: https://habr.com/ru/post/ar412057/


All Articles