نحوه-رابط-صفحه-Mojo-V3-FPGA-با-یک-ماژول-LCD-16x2

نحوه رابط صفحه Mojo V3 FPGA با یک ماژول LCD 16×2

در این مقاله، جزئیات رابط کاربری یک ماژول LCD 16×2 با FPGA مورد بحث قرار خواهد گرفت. در مقاله های قبلی، بلوک های ساختمانی مورد نیاز برای رابط FPGA را با یک ماژول LCD 16×2 مشترک بررسی کردیم. ما دیدیم که بلوک های اصلی ساختمان ROM، برخی DFF ها چند برابر هستند. علاوه بر این، برای کنترل این بلوک های ساختمانی به یک FSM (دستگاه محدود کننده حالت) احتیاج داشتیم. در این مقاله، به جزئیات طراحی FSM خواهیم پرداخت. سپس، کد Verilog را برای بلوک های مختلف خواهیم نوشت و از تابلوی Mojo V3 برای تأیید طراحی خود استفاده خواهیم کرد.

پیشنهاد ما: دوره آموزش FPGA  در آموزشگاه فنی سازان با مدرک رسمی و معتبر

نمودار بلوک سیستم در FPGA

نمودار بلوک رابط FPGA-LCD در شکل زیر نشان داده شده است:

نمودار-بلوک-سیستم

همانطور که مشاهده می کنید، FSM دارای دو ورودی (addr_reg و cnt_reg) و پنج خروجی (s1، s2، RS، RW و E). ورودی های FSM به ما امکان می دهد وضعیت بلوک های “مسیر 1” و “مسیر 2” را کنترل کنیم. خروجی “” ” s1مسیر 1″ را کنترل می کند و به تبع آن داده های روی پین های DB7-DB0  اعمال می شوند. خروجی “” s2بلوک “مسیر 2” را کنترل می کند و می تواند برای تولید تاخیر زمانی لازم مورد استفاده قرار گیرد. خروجی های “” RS ، “RW” و “” E شکل موج های مناسبی را برای پین های کنترل LCD ایجاد می کنند.

مقاله مرتبط: آشنایی با طرح های القایی برای مبدل ها

حالت “آماده به کار” در FPGA

در حالت “آماده به کار”، به خروجی ها مقدار دهی اولیه داده می شود.

الگوریتم-FPGA

در حالت “آماده به کار” ، خروجی های “” RW ، “RS” و “” E در  مقدار دهی های استارت می زنند. خروجی های “” s1 و “” s2 برابر با 2 هستند به طوری که DFF های “مسیر 1” و “مسیر 2” در لبه ساعت بعدی تنظیم مجدد شوند (شکل 1). توجه داشته باشید ورودی اضافی (“شروع”) برای FSM است.  این به یک دکمه فشار روی نمونه متصل خواهد شد. تنظیم ورودی ” start روی منطق بالا ، روند چاپ روی LCD را آغاز می کند.

حالت  ” lcd_init”

در این حالت ، ماژول LCD اولیه سازی می شود. برای این منظور، چهار فرمان (x38  0،  0x0C ، 0x06 و0x01) که در آدرس های 0 تا 3 رام ذخیره می شوند، باید روی پین های داده LCD قرار گیرند. به همین دلیل است که نمودار حالت شکل 2، عبارت addr_reg = 3 را به عنوان شرط انتقال از “” lcd_init به حالت بعدی درج می کند (“lcd_print”).

اصطلاح دیگر برای شرایط انتقال حالت cnt_reg = 3،550،000 است. هر بایت از ROM باید برای مدت زمان کافی (71 مایل در این طراحی) روی پین های داده LCD استفاده شود. شرط cnt_reg = 3،550،000 اطمینان می دهد که LCD زمان کافی (71 میلی ثانیه) برای خواندن پین های داده دارد. بنابراین، شرایط addr_reg = 3 && cnt_reg = 3،550،000 بدان معنی است که چهارمین دستور ذخیره شده در ROM برای حدود (ms71) روی LCD اعمال می شود. وقتی این شرایط برآورده شود، LCD با موفقیت آغاز می شود و می توانیم داده های پیام را روی DB7-DB0 قرار دهیم.

قبل از بررسی بلوک ASM بالا، ببینیم که چگونه شماره آستانه برای cnt_reg تعیین می شود. نمودار زمان بندی برای نوشتن ماژول LCD در شکل 5 نشان داده شده است.

شکل-5.-از-روش-HITACHI-استفاده-شده

توجه داشته باشید که سیگنال “” E باید پس از tAS به منطق بالا برود. برای PWEH در منطق بالا باقی مانده و سپس انتقال به منطق پایین tH قبل از عملیات نوشتن بعدی انجام شود. در این مقاله، tAS ، PWEH و tH به ترتیبms 10 ،58 ms  و 3 ms هستند. شکل موج برای سیگنال “” E همانطور که در شکل 6 نشان داده شده است.

این شکل همچنین تعداد معادل شمارش برای هر تأخیر زمانی را نشان می دهد. توجه داشته باشید که فرکانس ساعت صفحه Mojo V3 50 مگاهرتز (مدت زمان = 20 نانومتر) است. همانطور که در شکل 4 نشان داده شده است، مقدار “” cnt_reg را بررسی می کنیم تا یک مقدار مناسب برای  E تنظیم شود. برای مثال، هنگامی که سیگنال “cnt_reg” از 500000 بزرگتر و کمتر از 4،4،000،000 باشد ، سیگنال E باید منطقی باشد.

باز هم، خروجی های “” s1 و “” s2 بر اساس مقدار سیگنال ” cnt_reg” تعیین می شوند. اگر “cnt_reg” کمتر از 3550،000 (معادل 71 ms) باشد ، ما به انتهای عملیات نوشتن نرسیده ایم (شکل 6 را ببینید). بنابراین، داده های اعمال شده بر روی LCD نباید تغییر کنند (s1 = 0) و شمارنده باید حساب شود (s2 = 1). اما، وقتی ” cnt_reg” بیشتر از 3550،000 (معادل 71 ms) باشد، ما به پایان عملیات نوشتن فعلی رسیده ایم. در این حالت، داده های آدرس بعدی ROM باید بر روی LCD (s1 = 1) اعمال شود و شمارنده در 0 (S2 = 2)  مجددا تنظیم شوند. (شکل 1 را ببینید).

همانطور که قبلاً بحث شد، در  چهار دستور پیکربندی LCD داریم که در آدرس های 0 تا 3 رام ذخیره می شوند. هنگامی که دستور چهارم (addr_reg = 3) برای 71 ms (cnt_reg = 3،550،000) روی LCD اعمال می شود، باید به حالت “” lcd_print برویم که داده های پیام را به LCD ارسال می کند. این با آخرین شش ضلعی در بلوک ASM حاصل می شود.

توجه داشته باشید که ورودی “” RS  از ماژول LCD مشخص می کند که آیا DB7-DB0 باید به عنوان یک کد دستورالعمل (RS = 0) یا به عنوان داده (RS = 1) رفتار شود. از این رو، در حالت “” lcd_init ، پین RS باید از نظر منطقی کم باشد. پین RW مشخص می کند که آیا ما به ماژول می نویسیم (RW = 0) یا از آن می خوانیم (RW = 1). در هر دو حالت “” lcd_init و “” lcd_print ، ما یک عملیات نوشتن را انجام می دهیم و RW باید منطقی باشد.

حالت ” lcd_print”

حالت ” lcd_print ” کاملاً شبیه حالت ” lcd_init ” است با این تفاوت که RS باید منطقی باشد (زیرا اکنون DB7-DB0 باید به عنوان یک داده به جای یک کد دستورالعمل رفتار شود). علاوه بر این ، مقادیر آستانه بررسی شده برای سیگنال addr_reg باید تغییر کند زیرا این پیام در آدرس های 4 تا 19 رام ذخیره می شود. با این تغییرات ، بلوک ASM را در شکل 7 نشان می دهیم.

سرانجام، با اتصال همه این بلوکهای ASM ، نمودار ASM را که در شکل 8 نشان داده شده است، بدست می آوریم.

کد Verilog در FPGA

ایجاد توصیف Verilog از سیستم، کار ساده ای است. بیایید نگاهی به کد بلوک های ساختمانی مختلف بیندازیم:

مسیر 1

برای بلوک “مسیر 1” ، به رام 8✕20 نیاز داریم:

//Path 1: ROM

wire [7:0] rom_data [19:0];

assign rom_data[0] = 8’h38;

assign rom_data[1] = 8’h06;

assign rom_data[2] = 8’h0C;

assign rom_data[3] = 8’h01;

assign rom_data[4] = ” “;

assign rom_data[5] = ” “;

assign rom_data[6] = “H”;

assign rom_data[7] = “E”;

assign rom_data[8] = “L”;

assign rom_data[9] = “L”;

assign rom_data[10] = “O”;

assign rom_data[11] = ” “;

assign rom_data[12] = “W”;

assign rom_data[13] = “O”;

assign rom_data[14] = “R”;

assign rom_data[15] = “L”;

assign rom_data[16] = “D”;

assign rom_data[17] = “!”;

assign rom_data[18] = ” “;

assign rom_data[19] = ” “;

assign data = rom_data[addr_reg];

این مشخص می کند که ” rom_data ” یک آرایه ی دو بعدی از سیم است. توجه داشته باشید که در Verilog، بُعد دوم آرایه پس از نام آرایه آمده است. مقادیر مورد نظر به آرایه اختصاص داده می شود و سرانجام، خروجی ROM به “داده” اختصاص می یابد. “داده” خروجی طراحی است و به DB7-DB0 ماژول LCD وصل خواهد شد.

رجیسترها و مولتی پلکسر “مسیر 1” را می توان با کد زیر شرح داد:

مسیر 2

بلوک “مسیر 2” به شرح زیر است:

eg [21:0] cnt_reg, cnt_next;

//Path 2: Registers

always@(posedge clk, posedge rst)

begin

            if(rst)

                    cnt_reg <= 21’h0;

             else

                    cnt_reg <= cnt_next;

              end

//Path 2: Mux

always @*

           case(s2)

                2’b00:

                      cnt_next = cnt_reg;

                 2’b01:

                       cnt_next = cnt_reg + 1’b1;

                2’b10:

                        cnt_next = 21’h0;

                 default:

                        cnt_next = cnt_reg;

                endcase

FSM

برای توصیف FSM در Verilog HDL ، می توانیم از عبارت ” localparam ” برای تعریف ثابت های نمادین که نمایانگر حالت های FSM هستند استفاده کنیم. FSM ما سه حالت دارد. این حالت را می توان با ” localparam ” زیر شرح داد:

localparam [1:0]                                idle      = 2’b00,

                                                                 lcd_init  = 2’b01,

                                                                 lcd_print = 2’b10;

برای ذخیره حالت سیستم ، یک ثبات دو بیتی تعریف می کنیم:

eg [1:0] state_reg, state_next;

//State Registers

always@(posedge clk, posedge rst)

begin

         if(rst)

                  state_reg <= idle;

          else

                 state_reg <= state_next;

          end

سپس ، باید مدار ترکیبی را تعیین کنیم که وضعیت بعدی FSM را تعیین کند. این قسمت از کد را می توان بر اساس شش ضلعی های نمودار ASM نوشت:  توجه داشته باشید که کد زیر شرایط انتقال حالت را که قبلاً از آن گرفته شده ساده کرده است.

//Next State Logic

always @*

begin

           case(state_reg)

                idle:

                       if(start)

                               state_next = lcd_init;

                        else

                                state_next = idle;

           lcd_init:

                     if(addr_reg == 5’h03 && cnt_reg == 3550000)

                           state_next = lcd_print;

                     else

                            state_next = lcd_init;

             lcd_print:

                    if(addr_reg == 5’h19 && cnt_reg == 3550000)

                             state_next = idle;

                       else

                             state_next = lcd_print;

                    default:

                           state_next = idle;

                      endcase

                    end

سرانجام، ما باید کد Verilog را برای خروجی های FSM بنویسیم. این قسمت از کد را می توان بر اساس بیضی شکل 8 نوشت، که نشان دهنده تکالیف شرطی FSM است.

//Output Logic

always @*

begin

                    case(state_reg)

                                idle:

                                       begin

                                               s1 = 2’b10;

                                               s2 = 2’b10;

                                               RW = 0;

                                               RS = 0;

                                               E = 0;

                                                end

lcd_init:

begin

s1 = 2’b00;

s2 = 2’b01;

RS = 0;

RW = 0;

E = 0;

        if (cnt_reg >= 500000)

E = 1;

         if (cnt_reg >= 3400000)

E = 0;

if (cnt_reg == 3550000)

begin

s1 = 2’b01;

s2 = 2’b10;

   end

   end

lcd_print:

begin

s1 = 2’b00;

s2 = 2’b01;

RS = 1;

RW = 0;

E = 0;

if (cnt_reg >= 500000)

E = 1;

if (cnt_reg >= 3400000)

E = 0;

if (cnt_reg == 3550000)

begin

s1 = 2’b01;

s2 = 2’b10;

    end

   end

default:

begin

s1 = 2’b10;

s2 = 2’b10;

RW = 0;

RS = 0;

E = 0;

end

endcase

end

پروژه Mojo

اکنون می توانید نسخه ای از پروژه Mojo Base را بگیرید و بخش های کد بالا را به آن اضافه کنید. به یاد داشته باشید که باید ورودی ها و خروجی های ماژول سطح بالا Verilog را تغییر دهید.

کد نهایی خواهد بود:

module mojo_top(

    // 50MHz clock input

    input clk,

    // Input from reset button (active low)

    input rst_n,

    // cclk input from AVR, high when AVR is ready

    input cclk,

    // Outputs to the 8 onboard LEDs

    output[7:0]led,

    // AVR SPI connections

    output spi_miso,

    input spi_ss,

    input spi_mosi,

    input spi_sck,

    // AVR ADC channel select

    output [3:0] spi_channel,

    // Serial connections

    input avr_tx, // AVR Tx => FPGA Rx

    output avr_rx, // AVR Rx => FPGA Tx

    input avr_rx_busy, // AVR Rx buffer full

//My Inputs and Outputs

                                                     input start,

                                                     output [7:0] data,

                                                     output reg RS, RW, E

                                                     );

wire rst = ~rst_n; // make reset active high

// these signals should be high-z when not used

assign spi_miso = 1’bz;

assign avr_rx = 1’bz;

assign spi_channel = 4’bzzzz;

assign led[7:0] = 5’h00;

localparam [1:0] idle      = 2’b00,

                                                                                                              lcd_init  = 2’b01,

                                                                                                              lcd_print = 2’b10;

reg [1:0] state_reg, state_next;

reg [4:0] addr_reg, addr_next;

reg [21:0] cnt_reg, cnt_next;

reg [1:0] s1, s2;

//State Registers

always@(posedge clk, posedge rst)

begin

                                                                 if(rst)

                                                                                    state_reg <= idle;

                                                                 else

                                                                                    state_reg <= state_next;

end

//Next State Logic

always @*

begin

                                                                 case(state_reg)

                                                                                    idle:

                                                                                    if(start)

                                                                                                state_next = lcd_init;

                                                                                    else

                                                                                                state_next = idle;

                                                                                    lcd_init:

                                                                                    if(addr_reg == 5’h03 && cnt_reg == 3550000)

                                                                                                state_next = lcd_print;

                                                                                    else

                                                                                                state_next = lcd_init;

                                                                                    lcd_print:

                                                                                    if(addr_reg == 5’h19 && cnt_reg == 3550000)

                                                                                                state_next = idle;

                                                                                    else

                                                                                                state_next = lcd_print;

                                                                                     default:

                                                                                                state_next = idle;

                                                                                    endcase

end

//Output Logic

always @*

begin

                                                                                    case(state_reg)

                                                                                    idle:

                                                                                                begin

                                                                                                s1 = 2’b10;

                                                                                                s2 = 2’b10;

                                                                                                RW = 0;

                                                                                                RS = 0;

                                                                                                E = 0;

                                                                                                end

                                                                                    lcd_init:

                                                                                                begin

                                                                                                s1 = 2’b00;

                                                                                                s2 = 2’b01;

                                                                                                RS = 0;

                                                                                                RW = 0;

                                                                                                E = 0;

                                                                                                if (cnt_reg >= 500000)

                                                                                                            E = 1;

                                                                                                if (cnt_reg >= 3400000)

                                                                                                            E = 0;

                                                                                                if (cnt_reg == 3550000)

                                                                                                begin

                                                                                                            s1 = 2’b01;

                                                                                                            s2 = 2’b10;

                                                                                                end

                                                                                                end

                                                                                    lcd_print:

                                                                                                begin

                                                                                                s1 = 2’b00;

                                                                                                s2 = 2’b01;

                                                                                                RS = 1;

                                                                                                RW = 0;

                                                                                                E = 0;

                                                                                                if (cnt_reg >= 500000)

                                                                                                            E = 1;

                                                                                                if (cnt_reg >= 3400000)

                                                                                                            E = 0;

                                                                                                if (cnt_reg == 3550000)

                                                                                                begin

                                                                                                            s1 = 2’b01;

                                                                                                            s2 = 2’b10;

                                                                                                end

                                                                                                end

                                                                                    default:

                                                                                                begin

                                                                                                s1 = 2’b10;

                                                                                                s2 = 2’b10;

                                                                                                RW = 0;

                                                                                                RS = 0;

                                                                                                E = 0;

                                                                                                end

                                                                                    endcase

end

//Path 1: ROM

wire [7:0] rom_data [19:0];

  assign rom_data[0] = 8’h38;

  assign rom_data[1] = 8’h06;

  assign rom_data[2] = 8’h0C;

  assign rom_data[3] = 8’h01;

  assign rom_data[4] = ” “;

  assign rom_data[5] = ” “;

  assign rom_data[6] = “H”;

  assign rom_data[7] = “E”;

  assign rom_data[8] = “L”;

  assign rom_data[9] = “L”;

  assign rom_data[10] = “O”;

  assign rom_data[11] = ” “;

  assign rom_data[12] = “W”;

  assign rom_data[13] = “O”;

  assign rom_data[14] = “R”;

  assign rom_data[15] = “L”;

  assign rom_data[16] = “D”;

  assign rom_data[17] = “!”;

  assign rom_data[18] = ” “;

  assign rom_data[19] = ” “;

  assign data = rom_data[addr_reg];

//Path 1: Registers

always@(posedge clk, posedge rst)

begin

                                                                 if(rst)

                                                                                    addr_reg <= 5’b0;

                                                                 else

                                                                                    addr_reg <= addr_next;

end

//Path 1: Mux

always @*

                                                                 case(s1)

                                                                                    2’b00:

                                                                                    addr_next = addr_reg;

                                                                                    2’b01:

                                                                                    addr_next = addr_reg + 1’b1;

                                                                                    2’b10:

                                                                                    addr_next = 5’b0;

                                                                                    default:

                                                                                    addr_next = addr_reg;

                                                                 endcase

//Path 2: Registers

always@(posedge clk, posedge rst)

begin

                                                                 if(rst)

                                                                                    cnt_reg <= 21’h0;

                                                                 else

                                                                                    cnt_reg <= cnt_next;

end

//Path 2: Mux

always @*

                                                                 case(s2)

                                                                                    2’b00:

                                                                                    cnt_next = cnt_reg;

                                                                                    2’b01:

                                                                                    cnt_next = cnt_reg + 1’b1;

                                                                                    2’b10:

                                                                                    cnt_next = 21’h0;

                                                                                    default:

                                                                                    cnt_next = cnt_reg;

                                                                 endcase

endmodule

شماتیک و پرونده UCF

حال می توان محدودیت های جدیدی را، به محدودیت تعریف شده توسط کاربر (UCF) پروژه Mojo Base اضافه کرد تا پین های FPGA را که به ورودی ها یا خروجی های ماژول سطح بالا متصل هستند، مشخص کنیم. چندین خط اول در پرونده UCF زیر در پروژه Mojo Base گنجانده شده است. با این وجود ، 12 خط آخر پین های FPGA متصل به سیگنال های DB7-DB0 ، start ، RS ، RW و E را در این کد مشخص می کنند.

#Created by Constraints Editor (xc6slx9-tqg144-3) – 2012/11/05

NET “clk” TNM_NET = clk;

TIMESPEC TS_clk = PERIOD “clk” 50 MHz HIGH 50%;

# PlanAhead Generated physical constraints

NET “clk” LOC = P56 | IOSTANDARD = LVTTL;

NET “rst_n” LOC = P38 | IOSTANDARD = LVTTL;

NET “cclk” LOC = P70 | IOSTANDARD = LVTTL;

NET “led<0>” LOC = P134 | IOSTANDARD = LVTTL;

NET “led<1>” LOC = P133 | IOSTANDARD = LVTTL;

NET “led<2>” LOC = P132 | IOSTANDARD = LVTTL;

NET “led<3>” LOC = P131 | IOSTANDARD = LVTTL;

NET “led<4>” LOC = P127 | IOSTANDARD = LVTTL;

NET “led<5>” LOC = P126 | IOSTANDARD = LVTTL;

NET “led<6>” LOC = P124 | IOSTANDARD = LVTTL;

NET “led<7>” LOC = P123 | IOSTANDARD = LVTTL;

NET “spi_mosi” LOC = P44 | IOSTANDARD = LVTTL;

NET “spi_miso” LOC = P45 | IOSTANDARD = LVTTL;

NET “spi_ss” LOC = P48 | IOSTANDARD = LVTTL;

NET “spi_sck” LOC = P43 | IOSTANDARD = LVTTL;

NET “spi_channel<0>” LOC = P46 | IOSTANDARD = LVTTL;

NET “spi_channel<1>” LOC = P61 | IOSTANDARD = LVTTL;

NET “spi_channel<2>” LOC = P62 | IOSTANDARD = LVTTL;

NET “spi_channel<3>” LOC = P65 | IOSTANDARD = LVTTL;

NET “avr_tx” LOC = P55 | IOSTANDARD = LVTTL;

NET “avr_rx” LOC = P59 | IOSTANDARD = LVTTL;

NET “avr_rx_busy” LOC = P39 | IOSTANDARD = LVTTL;

#My Constraints

NET “start” LOC = P1 | IOSTANDARD = LVTTL;

NET “RS” LOC = P5 | IOSTANDARD = LVTTL;

NET “RW” LOC = P7 | IOSTANDARD = LVTTL;

NET “E” LOC = P9 | IOSTANDARD = LVTTL;

NET “data<0>” LOC = P11 | IOSTANDARD = LVTTL;

NET “data<1>” LOC = P14 | IOSTANDARD = LVTTL;

NET “data<2>” LOC = P16 | IOSTANDARD = LVTTL;

NET “data<3>” LOC = P21 | IOSTANDARD = LVTTL;

NET “data<4>” LOC = P23 | IOSTANDARD = LVTTL;

NET “data<5>” LOC = P26 | IOSTANDARD = LVTTL;

NET “data<6>” LOC = P29 | IOSTANDARD = LVTTL;

NET “data<7>” LOC = P32 | IOSTANDARD = LVTTL;

با داشتن FPGA معمولاً باید مشکل را در پایین ترین سطح طراحی اجرا شود. آنچه در این کد ها مشاهده می شود، دروازه های منطقی و برخی از ساختمان های اساسی مانند افزودنی ها و مقایسه ها هستند. اگرچه این ها می تواند طراحی FPGA را تا حدودی دشوار کنند، اما FPGA چندین مزیت را ارائه می دهد.

در این پروژه، ما بلوک های ساختمان مورد استفاده برای رابط FPGA با یک ماژول LCD 16×2 مشترک را مورد بررسی قرار داده ایم. برای اجرای رابط FPGA-LCD ، یک رام، برخی DFF ها و مالتی پلکسرها لازم است. علاوه بر این، ما برای کنترل بلوک های ساختمان نیاز به یک FSM داریم. ما به جزئیات طراحی FSM پرداختیم و توضیحات Verilog را برای بلوک های ساختمانی مختلف طراحی پیدا کردیم. سرانجام، ما کد خود را در صفحه Mojo V3 بارگذاری کردیم و “” HELLO WORLD! پیام بر روی LCD.

جمع بندی FPGA

از FPGA ها برای به وجود آوردن یک سیستم با کارایی و انعطاف پذیری بالا استفاده می شود. FPGA ها معماری برنامه پذیر دارند و قیمت مناسب و زمان راه اندازی کم و همینطور امکان ایجاد پردازش موازی، چالش های  طراحان مدارهای دیجیتالی را از بین برده است. بعلاوه، استفاده از FPGA ها در طراحی‌ مدار، می توان در فرکانس های کاری بالا با سرعت زیادی پردازش را انجام داد. FPGA ها در حوزه‌های گسترده ای از جمله پردازش تصویر، پردازش سیگنال، سیستم‌های مخابراتی، سیستم‌های انتقال داده­‌های دیجیتال، سیستم‌های جنگ الکترونیک و راداری بکارگیری شوند.

آموزشگاه فنی سازان کلاس های حضوری آموزش FPGA را تحت نظر اساتید با تجربه این حوزه برگزار می کند. کارگاه آموزشی FPGA در آموزشگاه فنی سازان کاملا پیشرفته و مجهز می باشد. کارآموزان زیادی هر ساله از این کلاس ها فارغ التحصیل می شوند. این دوره آموزشی دارای ضمانت یادگیری می باشد و در پایان دوره مدرک قابل تایید از سازمان فنی و حرفه ای به کارآموزان اعطاء می شود.

guest
0 دیدگاه
بازخورد درون متنی
مشاهده همه نظرات