FPGA पर IBM PC बनाना

मुझे लगता है कि FPGA के साथ काम करने वाले कई लोगों ने सोचा - और नहीं कि आपके कंप्यूटर को पूरी तरह से उस पर बनाना है, एक x86 प्रोसेसर, बाह्य उपकरणों और अधिक के साथ? 8-बिट कंप्यूटरों को अक्सर FPGA में लागू किया जाता था, लेकिन यहाँ एक पूरा पीसी है ...

सफल संचालन के लिए, x86 प्रोसेसर के अलावा, आपको सभी कार्यान्वित इंटरप्ट (एसडी कार्ड पर "डिस्क" तक पहुंच सहित), एक वीजीए-संगत वीडियो कार्ड का BIOS, सभी बाह्य उपकरणों, एक मेमोरी कंट्रोलर, एक टाइमर और बहुत कुछ के साथ एक BIOS की भी आवश्यकता है। पहली नज़र में लगता है कि यह कार्य बहुत अधिक जटिल है, लेकिन फिर भी, इसे ZetCPU परियोजना में हल किया गया था।

सीमाओं में से - केवल 16-बिट मोड 12.5Mhz पर काम करता है, गणितीय गणक के बिना।

लोहा


शुरू करने के लिए, हमें FPGA के साथ एक डिबग बोर्ड की आवश्यकता है। मुझे वास्तव में टेरासिक DE2-115 बोर्ड ( एल्टर साइक्लोन IV पर 115k। LE के साथ) पसंद आया। एक चिप के खुदरा मूल्य से कम छात्र की कीमत $ 299 है।

बोर्ड पर बहुत सारे बिल्ट-इन आयरन हैं - 2 जिसमें 8MB SDRAM मेमोरी, 256KB SRAM, 1MB फ्लैश मेमोरी, 2 PHY 1Gb इथरनेट, VGA, LED / स्विच / बटन, SD कार्ड स्लॉट और बहुत कुछ कनेक्ट करने के लिए VideoDAC है। लेकिन इस परियोजना में सभी का उपयोग नहीं किया जाता है (केवल एसडी कार्ड, फ्लैश, एसडीआरएएम और वीडियोडैक)।

इसके अलावा, परियोजना को $ 59 के छात्र मूल्य के साथ DE0 नैनो पर लॉन्च किया जा सकता है, लेकिन केवल पाठ मोड वहां काम करेगा।

हम लॉन्च करते हैं


इंस्टॉलेशन में कई गैर-स्पष्ट बिंदु हैं जो निर्देशों में वर्णित नहीं हैं:



अब आप एक मॉनिटर, PS / 2 कीबोर्ड को बोर्ड से जोड़ सकते हैं - और इसे :-)
आप प्रोसेसर में अपने निर्देश जोड़ सकते हैं, आपकी परिधीय, किसी भी निर्देश का कार्यान्वयन verilog स्रोत में देख सकते हैं ...

पूर्णांक विभाजन का एक उदाहरण कार्यान्वयन
module zet_div_uu(clk, ena, z, d, q, s, div0, ovf); // // parameters // parameter z_width = 16; parameter d_width = z_width /2; // // inputs & outputs // input clk; // system clock input ena; // clock enable input [z_width -1:0] z; // divident input [d_width -1:0] d; // divisor output [d_width -1:0] q; // quotient output [d_width -1:0] s; // remainder output div0; output ovf; reg [d_width-1:0] q; reg [d_width-1:0] s; reg div0; reg ovf; // // functions // function [z_width:0] gen_s; input [z_width:0] si; input [z_width:0] di; begin if(si[z_width]) gen_s = {si[z_width-1:0], 1'b0} + di; else gen_s = {si[z_width-1:0], 1'b0} - di; end endfunction function [d_width-1:0] gen_q; input [d_width-1:0] qi; input [z_width:0] si; begin gen_q = {qi[d_width-2:0], ~si[z_width]}; end endfunction function [d_width-1:0] assign_s; input [z_width:0] si; input [z_width:0] di; reg [z_width:0] tmp; begin if(si[z_width]) tmp = si + di; else tmp = si; assign_s = tmp[z_width-1:z_width-d_width]; end endfunction // // variables // reg [d_width-1:0] q_pipe [d_width-1:0]; reg [z_width:0] s_pipe [d_width:0]; reg [z_width:0] d_pipe [d_width:0]; reg [d_width:0] div0_pipe, ovf_pipe; // // perform parameter checks // // synopsys translate_off initial begin if(d_width !== z_width / 2) $display("div.v parameter error (d_width != z_width/2)."); end // synopsys translate_on integer n0, n1, n2, n3; // generate divisor (d) pipe always @(d) d_pipe[0] <= {1'b0, d, {(z_width-d_width){1'b0}} }; always @(posedge clk) if(ena) for(n0=1; n0 <= d_width; n0=n0+1) d_pipe[n0] <= d_pipe[n0-1]; // generate internal remainder pipe always @(z) s_pipe[0] <= z; always @(posedge clk) if(ena) for(n1=1; n1 <= d_width; n1=n1+1) s_pipe[n1] <= gen_s(s_pipe[n1-1], d_pipe[n1-1]); // generate quotient pipe always @(posedge clk) q_pipe[0] <= 0; always @(posedge clk) if(ena) for(n2=1; n2 < d_width; n2=n2+1) q_pipe[n2] <= gen_q(q_pipe[n2-1], s_pipe[n2]); // flags (divide_by_zero, overflow) always @(z or d) begin ovf_pipe[0] <= !(z[z_width-1:d_width] < d); div0_pipe[0] <= ~|d; end always @(posedge clk) if(ena) for(n3=1; n3 <= d_width; n3=n3+1) begin ovf_pipe[n3] <= ovf_pipe[n3-1]; div0_pipe[n3] <= div0_pipe[n3-1]; end // assign outputs always @(posedge clk) if(ena) ovf <= ovf_pipe[d_width]; always @(posedge clk) if(ena) div0 <= div0_pipe[d_width]; always @(posedge clk) if(ena) q <= gen_q(q_pipe[d_width-1], s_pipe[d_width]); always @(posedge clk) if(ena) s <= assign_s(s_pipe[d_width], d_pipe[d_width]); endmodule 


हम परीक्षा पास करते हैं


मैं स्क्रीन प्रतियों के लिए अग्रिम माफी चाहता हूं:








अगला प्रोग्रामिंग है। संकलन और निष्पादन की गति उदासीनता को जन्म देती है ...




निष्कर्ष

मुझे उम्मीद है कि लेख ने आपको FPGA की शक्ति पर विश्वास किया और वेरिलॉग का अध्ययन करना जारी रखा।
और किसी को अब अपने पीसी-लाठी बनाने के लिए एक सपना सच हो सकता है :-)

प्रश्न / टिप्पणी?

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


All Articles