בנימין אברמוב ר"ד
Transcription
בנימין אברמוב ר"ד
הרצאה 21.10.12 -1 VHDL ד"ר בנימין אברמוב תוכן ההרצאות נמצא באתר/http://www.abramovbenjamin.net : המצגת העיקרית ממנה נלמד הקורס.BVHDL : אתר להורדה/http://www.altera.com : להוריד את סביבת העבודה.Quartus II Subscription Edition Software Version 12.0 Service Pack 2 for Windows : להוריד גם את modelsim :עבור הסימולציות. מייל של הקורס[email protected] : במהלך הרצאה זו נלמדו השקפים הראשונים העוסקים ב -מדע כדאי לכתוב ב VHDL -וכיצד השפה התפתחה. לא מצאתי לנכון לסכם משהו מדברים אלו – עמכם הסליחה. |1 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 31.10.12 – 2 משפחות רכיבים: המשפחה הבסיסית היא (Programmable Logic Device) PLDהמכילה את.PAL , PLA , GAL PLD : את כל אלו ראינו במעגלים ספרתיים הבנויים על סכום מכפלות או מכפלת סכומים. הצעד הבא במשפחה הם הרכיבים הקרויים .CPLDהרעיון הוא הגדלה של השערים (עשרות אלפי שערים במקום מאות). בנוסף מוכנסים FFלכל מאקרו-תא המכיל מספר שערי ANDו .OR-רכיבים אלו מאפשרים תכנות רב פעמי של עשרות אלפי תיכנותים .השלב האחרון במשפחה הם רכיבי ה .FPGA-ה"-שחקנים" המובילים בייצור רכיבי ה FPGA-הם,Xilinx (60%) : ) Altera (35%ו.)5%( Others - מבנה רכיב :FPGA הרכיב בנוי מבלוקים המחוברים לעולם החיצוני באמצעות .)In/out Bit( IOB/IOE יש לנו משאבים המאפשרים דגימת אות פנימה באמצעות ( FFשניים זמינים תמיד). כל הסיליקון חצוי באמצעות קווים הנקראים .(Global Interconnect) GI הם בעלי יכולת דחיפה גבוהה ומטרתם להזין צרכנים רבים. ה GI-מחלק את הרכיב לחלקים גדולים הנקראים ) LA (Logic Arrayובתוכם יש )Block( LABולהם קווים LI ו (Logic Element) LE-כל אלו מחולקים גם הם למקטעים שבשפתם יש אפשרות תכנות .יחידה בסיסית LEמורכבת מ FG -ו.FF- רוב המערכות שמכילות רכיבי FPGAמכילות גם זכרון. לשם כך הדרגה הבאה היא ) – SoC (System on Chipאלו רכיבי FPGAעם זכרון. ברכיבים אלו יש לנו שורות של זכרונות המחולקים למקטעים (בד"כ .)4kbמערכים אלו הם גולמיים ( - SRAMיודעים רק לשמור) המוקפים בלוגיקה .ע"י הדו-שיח בניהם ניתן להפוך את הזכרון לכל סוג אחר ROM , RAM , FIFO , LIFOוכו'. השלב האחרון הוא ) – SoPC (System on Programmable Chipאלו מכילות גם מעבד בתוכן המתפקד כבקרה על הכל. הבקרה היא גם דינאמית .יש שתי גישות לתיכון המעבד: * גישה אחת היא – Hardcoreבתוך אזור מסוים של הרכיב יש מעבד אחד (או יותר) והם לא גמישים. * גישה שנייה היא – Softcoreניתן לתכנן את המעבד לפי מספר קונפיגורציות ומקבלים מהחברה את המעבד הניתן לשתילה בתוך הרכיב .ניתן לשתול עד 16מעבדים באופן כזה שהם יתפקדו בתקופה מירבית ביניהם. דבר אחרון שנעשה בשנים האחרונות (לאחר שבלענו את המערכת השלמה בתוך השבב) קשור לפעולות .DSP לכן מפתחים תשתיות של מכפלות (פעולה דומיננטית ביותר לביצוע קונבולוציות ושאר פעולות DSPשכיחות) מלוטשות שכל תפקידם הוא להכפיל בלבד (היתרון הוא יכולת גבוהה יותר ומהירות בעת ביצוע הפעולות). (מכפל בודד היום מסוגל לבצע הכפלה של 78ביטים במחזור שעון אחד בתדר של .)!!!800Mb/sלמערכים אלו יש ריבוי שעונים המנוהלים במערכות PLLו .DCM (Digital Clock Manager)-באמצעות מבנים אלו יש לנו שליטה על הפאזה של השעון ומבטיחים נקודות דגימה יציבות של אותות. |1 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 31.10.12 – 2 פותחים בשקף .12 מספר שקף: 23 24 25 27 28 29 30 31 32 36-37 38-39 40 46 |2 הערות שונות: השוואה בין שפות תיכנות לשפות .HDLבשפות תיכנות הפקודות מתבצעות על כתובות ובצורה סדרתית. הביטוי בשפת HDLמתאר פעולת חיבור Adderופעולת כפל .יש לנו לופ חומרתי הזוי ולכן הדבר לא מתאפשר. יש לנו שני מבנים התלויים זה בזה הפועלים במקביל וזה מה שפוסל את הדבר( .הבעיה ב)A- הדוגמא בשפת Cנכונה אך אינה חכמה במיוחד (בלשון המעטה) .המקרה ב HDL-לא נכון כי שמים ל D-שני דברים יחדיו (על אותו החוט) ולכן הדבר לא אפשרי. שוני בסדר הפעולות בשפת תיכנות יגרור שוני בתוצאות בניגוד ל.HDL- השפה לא רגילה לגדלים Der der DER :זהים. דוגמא צורות כתיבה הערות כותבים עם-- : מילים שמורות בשפה. צורה לכתיבה הערות שלא יתייחסו אליהם בתהליך הסינתזה אך כן בתהליך הקומפילציה. הגדרת פרמטרים. דוגמא. המצבים הקיימים )* .(Modesקיים מצב נוסף המשמש לכתיבה עם מערכות לא ספרתיות שלא מופיע במצגת. המצב חוצץ מאפשר לכתוב נתונים החוצה וגם לקרוא נתון שכתבנו החוצה למשך החישובים שלנו בתוך הבלוק. הרעיון הוא לאפשר לקבל ערך שהוצאנו במידה ויש בו צורך בשער כלשהו בתוך הבלוק .אחרת נקבל שגיאת קומפילציה. המצב inoutמאפשר לקבל ערך מבחוץ לבפנים בניגוד ל Buffer-שבו נשתמש כאשר הוא מוציא ערך אבל אנו רוצים את הערך שלו מתוך הבלוק .הפורט inoutדורש בקרת נתונים*** .להוסיף סרטוט של ***inout סוגי פרמטרים .(Types) .בוליאן מאפשר פעולות מסוג אמת/שקר וביט מאפשר פעולות מסוג .0/1 זה לא אותו דבר .נציין כי הסוג של תוצאה זהה לסוג של מרכיביו .הסוג integerמאפשר תוצאה שהיא ערך שלם. VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 7.11.12 – 3 סוגי פעולות וכלליהן: בהרצאה קודמת למדנו על המבנה הכללי של הכתיבה ועל המצבים ).(Modes ראינו כי חשוב לציין את סוג המשתנה ) (Typeהיות והוא מתורגם לחוטים ממשיים. נתמצת את הסוגים המרכזיים והפעולות הכלליות באופן הבא: Shift V V Relation V V V V V V logical V V V V V Arithmetic V V V Type \ Operation Boolian bit bit_vector integer std_logic std_logic_vector הסוגים boolianו bit-מיוצגים ע"י קו חשמלי אחד .הערכים שניתן להשים בהם הם 'true','false' :ו '0','1'-בהתאמה. הסוג integerמתורגם אוטומטית ל bus-של קווים – 32קווים. הסוג std_logicהוא קם קו אחד (נדבר בהמשך) ו.std_logic_vector- הפעולות שנדון עליהן הן :פעולות אריתמטיות ,פעולות לוגיות ,פעולות השוואה ופעולות הזזה. הפעולות האריתמטיות :חיבור ,חיסור ,כפל ,חילוק ,חזקה ,ערך מוחלט ,מוד ו-שארית. הסימנים בהתאמה.rem , mod , abs , ** , / , * , - , + : פעולות חיבור ,חיסור וכפל ניתנות לביצוע בין שני סוגים עם אותה כמות הביטים. פעולת חלוקה בעייתית עקב עלות גבוהה של משאבים ומהווה צוואר בקבוק של המערכת .לרוב היא תבוצע רק ב.int- פעולת חזקה לא נתמכת בצורה מלאה בפעולות סינתזה אלא רק( 2**m :שקול להזזה) ו( m**2 -כפל) .כל השאר בעייתיים. פעולת ערך מוחלט נתמכת באופן מלא. פעולות modו rem-מתקבלות כתוצאה מחילוק .כאשר נכתוב a mod b :אם aשלילי נקבל תוצאה שלילית ואם bשלילי נקבל remשלילי .לצרכי יישום המערכת נשתמש באופרנד קבוע ,חזקה של ,2כהמחלק שלנו.x mod n : הפעולות הלוגיות הבאות not , or , and , nor , nand , xor , xnor :ניתנות לביצוע באופן כללי. בכתיבה מבצורה הבאה x s1 or s2 or s3 or s4 :הפעולות מבוצעות משמאל לימין באופן סדרתי. כדי לשנות את הצורה נשתמש בסוגריים כגון. x s1 or s2 or s3 or s4 : פעולות עם שלילה לא יבוצעו על שלוש כניסות אלא רק על ,2אחרת התכנית לא תעבור קומפילציה. פעולות השוואה הן .<= , >= , < , > , /= , = :התרגום בהתאמה :שוויון ,אי-שוויון ,קטן ,גדול ,קטן שווה ,גדול שווה. ברגע שמבצעים פעולת השוואה מקבלים חזרה ערך boolianלכן בביטוי d s1 op s2 :ידוע כי dהוא בוליאני וs2 , s1- הם שני אופרנדים מאותו הסוג (כלשהו רק לא intכפי שמסומן בטבלה). פעולות הזזה הקיימות( sll :הזזה שמאלה ובביט הכי קטן יהיה אפס)( sla ,הזזה שמאלה כאשר הביט MSBהוא סימן). ( srlהזזה ימינה) וכנ"ל .sra :סיבובים( rol :סיבוב שמאלה) ( rorסיבוב ימינה). ניתן לבצע פעולה s a sll b :כאשר bהוא intהמייצג כמה פעמים יש להזיז. |1 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 7.11.12 – 3 להלן תכנית: הקבועים mו n-הם מספרים שלמים ותמיד הולכים מה MSB-כלפי ה.LSB- מותר ,אך לא כדאי ,שימוש בערכים שליליים .מומלץ ש n-יהיה אפס. ;)a: in bit_vector (m down to n הכתיבה a: bit_vector 1 to 8 ; :מעידה על כך שה MSB-תמיד יהיה המספר הראשון (. )1 נכתוב גם b: bit_vector 9 dwon to 2 ; :ו. c: bit_vector 7 dwon to 0 ; - כעת הפעולה c a; :משמעה. c 7 =a 1 : הפעולה c a and c; :משמעה. b 8 a 2 and c 6 ; , b 9 a 1 and c 7 ; : ניתן לבצע פעולות ברמות ביטים בודדים ע"י שימוש באינדקס .ניתן גם להשתמש בפעולות על חתיכה מהווקטור באמצעות אינדקסים .למשל. a 2 to 4 b 8 down to 6 xor c 2 down to 0 : חשוב לשמור על הסינטקס בתוך האופרנדים ,אם הראשון כתוב ב down to-אז גם השני. השמת קבועים: שמים קבועים בשלב האתחול והם נכנסים לרגיסטרים באמצעות קווי הבקרה. ערכים מסוג bitיכתבו .'1' , '0' :ערכים מסוג בוליאני יהיו אמת/שקר .ערכים מסוג intיהיו דצימלים כגון .10 אם נרצה בסיס שונה יש לכתוב base#const# :כגון - 16#ABCD# :מספר הקסדצימלי ABCDעל בסיס .16 לא נשתמש בבסיסים "מרתקים" כגון 5 ,9וכו'... ערכים קבועים מסוג bit_vectorנכתבים כמחרוזות ) (stringמה שחשוב הוא שמספר הביטים יהיו כמספר האובייקט המוגדר כגון . "0100111100" :מותר לציין שמדובר בווקטור בינארי ע"י הכתיבה. b"0100111100" : בסיסים המותרים לשימוש הם אוקטלי והקסדצימלי .למשל אוקטלי יכתב . x O"1234567"; :הקסדצימלי. x X"1AFC"; : מה שחשוב הוא שהערך שמתקבל כקבוע חייב להיות כפולה של 3או 4לפי הבסיסים. כתיבה נוחה שקולה היא . "01001000" "0100_1000" :הקומפיילר לא מתרגש מזה וזה נוח יותר לקריאה. השמות לתוך מחזורות: נניח שיש לנו ; . a,b,c,d: bitוגם e: bit_vector 3 down ot 0 ; :נרצה לבצע השמה של a,b,c,dלתוך .e נוכל לכתוב . e 3 a; e 2 b; e 1 c; e 0 d; :נוכל גם( e a,b,c,d ; :זאת השמה לפי מיקום). הסדר בצורות אלו משנה לנו ומשמעותי .ניתן להכניס גם קבועים. e a,"0",c,"1" ; : ניתן לכתוב . e 17 a,22 b,16 down to 9 "1",2:1:23:8 c , others d ; :כך שולטים בצורה גדולה יותר. פעולת שרשור מחזורות נעשית באופן הבא: ; e: bit_vector 7 down ot 0 ;"e "1" & b & 8 & O"6" & a & d & "0 חשוב להקפיד להשים את אותה כמות הביטים שממנה מורכב – eמשתנה ההשמה. |2 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 14.11.12 – 4 הסוגים Std_Logic :ו:Std_logic_vec- זכרונות סטטיים ניתנים לקריאה בכל עת בעוד שזיכרונות דינמיים דורשים ריענון מדי פעם אחרת הערכים שנקרא לא יהיו מדויקים ולעיתים לא נכונים. כדי לממש ביט inoutנעזר בחוצץ 3מצבים ) (3 state bufferשהוא למעשה Transmission gateשראינו במעגלים ספרתיים. ערך המוצא יכול לקבל 1 , 0או .High-Z 9ערכים המזוהים במצב :std_logic -Uערכים שלא אותחלו. –Xהתנגשות בין 0ו 1-לוגים משני בלוקים אשר יצאתם מתחברת וברור כי הם מוצאים ערכים הפוכים. – 0,1ערכים תקינים. –Wמצב התנגשות חלשה. –L,Hרמה לוגית נמוכה/גבוהה לא תקינה. ' – '-ערך ( .don’t careערכים שאינן משפיעים מבחינתנו) .כלי סינתזה לא אוהבים אותו בד"כ כי עלינו מוטלת החובה להחליט מה לעשות עם כל ביט ולא לצפות מהמערכת לבצע זאת בשבילנו. כדי להבין את משמעות ה don’t care-נניח busמשותף למספר צרכנים .כאשר יש צרכן שלא נבחר נוכל להשים את ערך זה בכניסתו כאשר נתכנת אותו למצב .disableהיתרון בכך הוא שערך תקין הנמצא בכניסה לבלוק במדובר – קשה מאוד להבחנה בחוץ אם הוא נכנס או לא בעוד שאם נכנס ערך don’t careנוכל לזהותו במידה והוא נכנס. נצטמצם לערכים ' 'X' , '0' , '1' , 'Zהמותרים לסינתזה. דוגמא של מצב נדיר הדורש שימוש ב:'X'- If(S/=R) than q R, elseif (S='0') than ;'q 'X ;endif לגבי אי השוויון בכניסות אין כל בעיה כי זה בהחלט יתכן. במצב של elseifאנו מכסים את המצב הלא-רצוי בכדי למנוע התנגשות .למעשה יש לנו פה מימוש של SR-FFכאשר הצירוף ''00 הוא הצירוף האסור .לכן אנו מגדירים אותו להיות ' 'Xהמתאר מצב-לא-מוגדר .נציין כי אין צורך בתנאי ' S='0' && R='0מאחר ומדובר במקרה elseifהמדבר על מצב בו הביטים לא מקיימים את התכונה המתוארת ב if(…)-ולכן ברור כי הם שווים. בערך ' 'Zמשתמשים במצבים נדירים בלבד כי אין להכניסו לתוך מערכת אלא הוא רק ביציאה. ENB i3 ENB Dout i2 Decoder ENB i1 ENB |1 2 ערכי יציאה מותרים הם: .1000 , 0100 , 0010 , 0001 צירופים אחרים יגררו מצב של התנגשות .בכל צירוף ,שאר היציאות שאינן 1יקבלו ערך של .High-Z i0 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 14.11.12 – 4 ספריות הרחבה לשימוש ב:std_logic- ;Library IEEE ;Use IEEE.std_logic_1164.all עם ספריות אלו נוכל להשתמש בכל הפעולות על אובייקטים אלו מלבד פעולות אריתמטיות. הספרייה שאחראית על זה היא.use IEEE.std_logic_arith.all : כאשר מבצעים פעולות signאו unsignיש משמעות ולכן נוסיף את הספריות הבאותuse IEEE.std_logic_unsigned.all : או .use IEEE.stdlogic_signed.allאם נשתמש למשל בשורה if(c>x"04") than :כאשר " c=X"80חייבים להשתמש בסימן כי הערך הנ"ל שלילי .חשוב להתייחס לאותם הקווים החשמליים לכל אורך הדרך במערכות מרובות דרגות .לכן נעבוד עם פורמט אחד לכל תתי המערכות. בסה"כ נכתוב את כל הספריות הבאות: ;Library IEEE ;use IEEE.std_logic_1164.all ;use IEEE.std_logic_arith.all ;use IEEE.std_logic_unsigned.all בדיקת תכנון :Test-Bench (TB) - בדומה למעבדות – שבהן הכנסנו אותות חיצוניים – נבצע זאת גם כאן. נכתוב בלוק UUT , DUTאו MUTבהתאם לגודל אשר יימצא בתוך ה.TB- עלינו לכתוב את ה entity-של ה TB-ולהצהיר על ה DUT-כ.component - כעת עלינו להצהיר סיגנלים הנכנסים לתוך ה component-הנ"ל ) (TG – Test generatorויוצאים למוניטור כלשהו. את כל הסיגנלים נאתחל בעת ההצהרה על מנת לא לקבל את ' 'Uבהרצה. איתחול סיגנל בעת ההצהרה נראה באופן הבא.signal s: type:=init_value; : אחרי Beginמחברים את הסיגנלים אל ה DUT-ב.Port map- מחוללי האותות יכולים להיות כל דבר .כדי לנדנד שעון בתכנון נכתוב.clk not clk after 5ns; : המילה afterשמורה בזיכרון .ניתן להגדיר זמנים מקנ"מ של שניות ועד ל.fs- נציין כי השמה זו היא השמה מתמשכת ) (Continuous assignmentאשר אינה ניתנת לסינתזה אך זה לא מעניין אותנו. כדי ליצור נדנוד כלשהו של כל אות באפן חד פעמי נכתוב.s1 '0', '1' after 10ns , '0' sfter 20ns , …. : נוכל להמשיך כך כמה שנרצה. |2 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 21.11.12 – 5 בלוק ה:Process- שפת VHDLכוללת מנגנון מובנה סגור הנקרא processולו ניתן לתת תוויות ותיאור התהליך. אופן הכתיבה הוא: E1: process ( ) is begin ;end process E1 כאשר E1הוא השם (אנו בוחרים) ובתוך הסוגריים נכנסת רשימת רגישות ) (sensitivity listהמאפשרת גישה למשאבים שלו בלבד .פעולה זו פועלת במקביל ליתר התהליכים בקוד .הרשמה כוללת סיגנלים שהשינוי שלהם משפיע על הפעולות שבתוך הבלוק. לכן יש לכלול רק את הסיגנלים שמשפיעים על הפעולות ,סיגנלים אחרים לא יכנסו. הבלוק הנ"ל הוא יוצא דופן בשפה המתבצע בצורה סדרתית עפ"י הרצף הכרונולוגי של הפעולות הרשומות בו. יחד עם זאת כל הבלוק עצמו פועל במקביל ליתר התהליכים .זמן הביצוע של processהוא אפס מכיוון שמדברים על מודל אידילי ללא זמן השהייה. ניתן למיין processלשני סוגים: חומרה צירופית (א-סינכרונית) ללא התערבות של שעון. חומרת סדרתית (סינכרונית) ובה מעורב שעון.הסוגים משליכים לכללי הכתיבה של התהליך .באסינכרונים רשימת הרגישות כוללת את כל הסיגנלים שקוראים ערך שלו בין להשמה בין להשאלה או תנאי – את כולם יש לכלול ברשימת הרגישות .בתהליך סינכרוני כל הסיגנלים שנכנסים מייצגים – FF כולם בעלי זיכרון. בדוגמא המופשטת להלן ניתן לראות כי מי שנכנס לרשימת הרגישות הוא כל מי שלא תלוי בשעון כולל השעון: שעון נכנס ושני הקווים Setו.Reset (clr)- Q SET in1 D in2 clk Q CLR היות ובשירשור של FFמקובלת ליצור קו קבוע שמאתחל את כולם -תמיד יש לכלול את .resetאין צורך גם ב set-כי הreset- של דרגה אחת נכנס ל set-של הדרגה הבאה. ;s a and b במקרה של שתי השמות לאותו הערך כגון: ;s a or b במקרה של decoderעם ביטים בכניסה שנסמן dinואת הביטים במוצא נסמן , doutנכתוב את dinבתוך רשימת הרגישות. בתוך הבלוק נכתוב dout others '0' ; :ובשורה הבאה . dout conv_integer din '1'; :זו היא השמה כפולה ,למרות שהכתיבה חסרת משמעות ,רק הפעולה האחרונה תבוצע. אבל בתחילה קיבלנו אפס ורק לאחר מכן שמנו מספר .הריאליזציה היא שבתחילה הכנסנו ל dout -את 00000000 :ולאחר מכן כאשר מתקבל בכניסה ערך ,למשל ,3נקבל שינוי ל.00001000 - |1 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 21.11.12 – 5 דוגמא למימוש Xorבשני שלבים: E1: process a, b, c is begin ;s1 a xor b ;s 2 s1 xor c ;end process E1 עפ"י האמור לעיל ,כל משתנה שמשנה ערך במוצא צריך להיכלל ברשימת הרגישות ,לכן גם .s1 במקרה שנוסיף אותו ניפול בבעיות סימולציות (בעיה של "ביצה ותרנגולת" בלתי פתירה). לכן במקרים מעין אלו יש לחלק לשני Processואין מעבר. בעיה הקשורה לרשימת הרגישות: E1: process a is begin ;s a xor b ;end process E1 לכאורה אין bברשימת הרגישות .המעבד מבין זאת בכך שיש משמעות לכך שהוא לא הוכנס .לכן הוא רוצה לקמפל את התהליך באופן כזה ששינויי bלא ישפיעו .לכן הוא יכניס את aלתוך ה Xor-בצורה ישירה אבל bיחסם .כדי לבצע זאת המעבד יחבר את הכניסה הזאת ל Latch-כאשר ה enb-שלו יקבע ע"י aבאופן הבא: a S Q Q SET D b CLR Q Q SET D CLR יש לנו פעמיים ( Xor 16כי המשתנים הם בעלי 16ביטים) וגם שני Lacthבעלי 4שערים לפחות כל אחד מהם. הכפלנו את החומרה פי 8מהרצוי וקיבלנו התנהגות לא נכונה. המסקנה היא להכניס לרשימה את כל הסיגנלים הרצויים! |2 VHDL -סיכום ועריכה מאת שי ידרמן 21.11.12 – 5 הרצאה E1: process clk , arst is begin if then elseif : בתוך בלוק באופן כלליif אופן הכתיבה של : אסינכרוניenb עםFF דוגמא למימוש של then else end if; end process E1; E1: process clk , arst is begin if arst '0 ' then : אסינכרוניenb עםFF דוגמא למימוש של q '0 '; elseif clk' event and clk 1'1 then q d; end if; end process E1; . במקום השורה הארוכהelseif rising_edge clk then דרך אחרת היא לכתוב . יגיב לאחד מהתנאים וזהוFF-ה :T-FF נכתוב E1: process clk , arst is begin if arst '0 ' then q '0 '; elseif rising_edge clk then if t '1' then q not q; end if; end if; end process E1; .הקוד כשר סיכום ועריכה מאת שי ידרמן- VHDL |3 21.11.12 – 5 הרצאה :JK-FF-דוגמא ל E1: process clk , arst is begin if arst '0 ' then q '0 '; elseif rising_edge clk then if J / k then q J; elseif J '1' then q not q; end if; end if; end process E1; :) לא צריך להיכלל ברשימת רגישות כי הוא תלוי בשעוןreset- סינכרוני (כעת הreset עםFF-דוגמא ל .) השעון וכל המשתנים שאינם תלויים בו ובלוק משתמש בהם בתנאים:(נזכור כי הגדרנו את המשתנים שנכנסים לרשימה E1: process clk is begin if rising_edge clk then d SET Q clk if srst '0 ' then CLR q '0 '; else q d; end if; end if; end process E1; סיכום ועריכה מאת שי ידרמן- D reset Q תלוי בשעון כיreset-ה המוצא ישתנה או שלא בהתאם אליו אבל רק לכן.בעליית השעון .אומרים שיש תלות VHDL |4 28.11.12 – 6 הרצאה :Process המשך :Mux המבנה הבא מייצג E1: process x, y is begin if a b then s x; else s y; end if; end process E1; Multiplexer x S1 y S2 D C ENB a=b . a b : שהואselect עםmux יש לנו כאן : נקבל את הסכמה הבאה.Latch בפועל לא יכנס השוויון הנ"ל באופן ישיר אלא ע"י Multiplexer x S1 D SET CLR D S2 Q C Q ENB y D SET CLR a D SET CLR b D SET CLR Q Q Q Q Q Q .)select אמורה להיותMUX- של הENB (באיור הנ"ל כניסת סיכום ועריכה מאת שי ידרמן- VHDL |1 הרצאה 28.11.12 – 6 דוגמא נוספת – processסינכרוני: E1: process clk , rst , ld , adat is begin if rst '0 ' then ; s others '0 ' elseif rising_edge clk then ;s din elseif ld '1' then ; s adat ;end if ;end process E1 המעבד יסמלץ את הדוגמא הנ"ל אך ישנה בעיה אחרת .יש לנו כאן שימוש בלוגיקה סינכרונית ב elseif-הראשון ושימוש בלוגיקה א-סינכרונית בשני .ל Q-ניתן לגשת בשני דרכים ,או בצורות א-סינכרוניות ( setו )reset-או באמצעות השעון (סינכרוני). אי אפשר יחד ולכן הפקודה פסולה .העדיפות היא לגישה האסינכרונית .כל מה שלא מיושם בדרך זו יוכל להתיישם בצורה סינכרונית. לכן המודל עובר סימולציה אך לא סינתזה. דוגמא נוספת: E1: process clk , rst , data is begin if rst '0 ' then ;s data elseif rising_edge clk then ;s din ;end if ;end process E1 הבעיה כאן שפוסלת את הפקודה היא שהבקשה הזויה .מנסים לבצע טעינה אסינכרונית לתוך .Q למה רוצים לבצע זאת וכמה זה הולך לעלות לנו? התשובות לא כ"כ חיוביות.. 0 1 2 D 3 )Data(4 reset |2 VHDL -סיכום ועריכה מאת שי ידרמן 28.11.12 – 6 הרצאה : עם בקרת ספירה מעלה ומטה, עם אפשור ספירה, אסינכרוניreset עם,11 דוגמא לכתיבת מונה עד E1: process clk , rst is begin if rst '0 ' then count others '0 ' then elseif rising_edge clk then din Add/ sub Up/ down Multiplexer S1 D S2 1 0 enb C ENB count load rst if load '1' then count din; elseif rising_edge enb '1' then if up _ ndwn '1' then count count 1; else count count 1; end if; end process E1; E1: process clk , rst is begin if rst '0 ' then :)דוגמא חולנית במיוחד (לשון המרצה q1 '0 '; elseif rising_edge clk then q1 d1; q 2 d 2; end if; end process E1; .reset- לא מושפע מq2 מוגדר לחלוטין אך המוצאq1 המוצא. עבור שתי היציאות,FF 2 רוצים לכתוב כאן .)(נציין כי הסיבות ליצור דבר כזה צריכות להיות מאוד מדויקות היות ולא מקובל לדרוש דבר כזה ויש1 הואreset כן מקבל משמעות נוספת והיא כאשרreset . שומר על הערך שלוreset שבוq2- לFF יש לנו כאן ניסיון לכתוב : בנפרדprocess כדי להתגבר על זה יש לכתוב.)עליית שעון הכניסה כן עוברת למוצא (מופיע באיור E1: process clk is begin if rising_edge clk then q 2 d 2; end if; end process E1; סיכום ועריכה מאת שי ידרמן- d2 0 1 q2 rst VHDL |3 הרצאה 28.11.12 – 6 דוגמא אחרונה למימוש שני :FF E1: process clk is begin if rising_edge clk then if srst '1' then ;' q1 '0 ;else q1 d1 ;q 2 q1 ;end if ;end if ;end process E1 התכוונו לממש את המעגל הבא: q2 q1 Q Q SET Q D Q CLR SET din srst D CLR clk הבעיה היא ש q2-נכלל במסגרת הרגישה ל .reset-לא כתוב מה לעשות איתו כאשר resetהוא .1 נקבל: d2 Q Q SET CLR D 0 1 srst Q Q SET din srst D CLR clk שוב יש לנו לוגיקה זיבלית .הפתרון הוא להעביר את הפקודה ; q2 q1או לפני הלולאה הפנימית או אחריה .אז הכל יהיה בסדר. סיכום: בלוגיקה יש לנו שני עולמות – אסינכרונית (עדיפות ראשונה) וסינכרונית .יש להתייחס רק לאירוע אחד (עלייה או ירידה) בלבד. אין להתייחס (ולתכנת) למספר שעונים שונים הנכנסים לשעון של אותו ה.FF- |4 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 5.12.12 – 7 כלים נוספים בכתיבה התנהגותית: נלמד איך להתנות ביצוע של פעולה מסוימת המבוצעת באמצעות תהליך ).(process בשונה מלולאת ifאנו פותחים באופן הבא בו נבדק סיגנל אחד בלבד ביחס לערכים הקבועים של אותו הסיגנל: case sig is ;when "001" ......... ;when "010" ......... ;when "001" c1|c2|c3|c4|c5 ......... ;when 1 to 11 ......... ;when 11 downto 1 ......... ;when others ......... ;end case בקטע קוד זה מופיעות כל צורות הכתיבה התקניות .חשוב לפרט על כל הערכים שהסיגנל יכול לקבל. לאחר החץ כותבים את כל המצבים שאנו רוצים שסיגנל יקבל ערכים לפיהם כגון. s1 a b; : דוגמא: ; s2 ......... ; s2 ......... ; s2 ......... ; s2 ......... case s1 is "when "00 "when "01 "when "10 "when "11 ;end case הקומפיילר לא יעביר את זה כי הסיגנל הוא מסוג std_logicהמכיל 9ערכים לכל ביט ולכן יש 11צירופים. ;when others s2 ......... יש לנו 77צירופים שלא מכוסים ולכן נוסיף את השורה: הבעיה היא מה לכתוב בתנאי של מקרה זה .היות והדבר לעולם לא קורה במערכת אמיתית (כל המקרה ממומש באמצעות )mux נוכל לכתוב s 2 y; :למשל .נניח כי זה הוא גם הערך שמתקבל כאשרwhen "11" s 2 y; : אז נעדיף לחבר ולכתוב: case s1 is ;when "00" s2 ......... ;when "01" s2 ......... ;when "10" s2 ......... ;when others s 2 y ;end case זה הוא פתרון אך קטע קוד זה אינו ברור בעליל לכל נפש ולכן מקובל להשתמש במילה שמורה NULLבאופן הבא: ;when others NULL השימוש ב NULL-מותנה בכך שיש לנו זכרונות מכיוון שאי-עשייה היא פעולה הדורשת זיכרון. |1 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 5.12.12 – 7 לולאות: קיים כלי חזק מאוד המאפיין לנו כתיבת קוד התנהגותי המשמש תיאור של מערכות הפועלות בצורה איטרטיבית. לצורך כך קיימות לולאות – יש לנו 3סוגים של לולאות שונות. נדבר היום על לולאת :for for i in n to m loop )( m downto n ;end loop נציין כי הגדרת משתנה האינדקס היא לוקלית ,אין צורך להגדיר אותו בחוץ והוא מת מיד בתום הלולאה. חייב להתקיים. m n : ניתן גם להשתמש בפקודות next :ו exit-המשמשות כ count-time-ו break-בהתאמה. בפקודה nextקופצים לסוף הלולאה אם התנאי מתקיים .בפקודה exitנקפוץ גם על השורה end loopונצא לגמרי מהלולאה. מקובל להשתמש בתוויות ללולאות (במערכות גדולות) ואז נוסיף L1: for in n to m loop :וגם בשורה האחרונה. דוגמא: L1: for . . . . loop L2: for . . . L3: for . . . ;End loop L3 ;End loop L2 ;End loop L1 באיזה שלב שנכתוב את הפעולות nextו exit-אנו נצא מהלולאה המכוננת המסוימת שבה הם נמצאים. הערות: .1נזכור כי בקלות ניתן לשרוף משאבים ע"י שימוש בריצות ארוכות מדי. . 2חשוב להבין את טיב החומרה הכתובה בלולאות אחרת הקומפיילר לא יעבד אותה מכיוון שהכל ממומש לחומרה. דוגמא לכתיבת :priority encoder E1: process din is begin ; dout others '0 ' for i in din'renge loop ; dout i din i ; exit when din i '1' ;end loop ;end process E1 |2 VHDL -סיכום ועריכה מאת שי ידרמן 5.12.12 – 7 הרצאה :נציין צורות כתיבת נוספות . כפי שהוגדרs – מחזיר את הטווח של הסיגנלs'renge .s – מחזיר את הטווח בצורה הפוכה של הסיגנלs'reverserenge .s – מחזיר את האורך שלs'length . – מחזיר את הערך הנמוך ביותר בטווחs'low . – מחזיר את הערך הגבוה ביותר בטווחs'high . – מחזיר את הערך השמאלי ביותר בטווחs'left . – כנ"ל עם הערך הימני ביותר בטווחs'right signal s : stdlogic_vector 15 downto 0 ; :shift left register דוגמא למימוש E1: process clk , rst is begin if rst '0 ' then s others '0 ' ; elseif rising_edge clk then if enb '1' then for i in s'reverserenge loop if i s 'low then s i sin; else s i s i 1 ; end if; end loop; end if; end if; end process E1; :ניתן לכתוב בצורה יעילה וקריאה יותר את הלולאה האחרונה באמצעות השורה הבאה s s s'high-1 downto s'low & sin ; סיכום ועריכה מאת שי ידרמן- VHDL |3 12.12.12 – 8 הרצאה :הערה בנוגע להקצאת זיכרון המתבצעת ע"י המחשב בזמן סימולציה של תוכנית int בתים (המון!) מומלץ לעבוד כמה שיותר עם סוגים זולים כגון8 היות והקצאת הזיכרון לביט בודד בסימולציה של תוכנית היא הערכים9 וידוע כי הביטים לא אמורים כלל לקבל ערכים מסוים מתוךstd_logic- ניתן במצבים שמשתמשים ב.boolian או . s to_01ZX s1 ; : באופן הבאto_01ZX , to_01Z , to_01 :שהכרנו לכתוב המרה שמקלה על הזיכרון .to אבל יכול לקבל רק את הערכים הנקובים בפונקציהS והוא מושם לתוךstd_logic הוא מסוגS1 הסיגנל .פעולה זו מאפשרת לזיכרון להקצות פחות מקום העת ההרצה וחוסכת זמן במהלך הסימולציה :Generic Constant – קבועים כלליים :לאחר השורה הראשונה ניתן להגדיר קבועים באופן הבא entity e_name is generic ( cont1: type:= init_value ; const2: type := init_value; . . . ) port ( ); end entity e_name; :כל קבוע מקבל סוג ומספר התחלה כגון entity gcnt is generic (side : integer : = 100 ) port ( clk : in std_logic ; rst : in std_logic ; din : in std_logic_vector ((size-1) downto 0 ) ; ld : in std_logic ; en : in std_logic ; dout : in std_logic ((size-1) downto 0 ) ); end entity gcnt; architecture arc_ gcnt of gcnt is signal out: std_logic_vector (dout'range); begin process (clk , rst) is begin if (rst = '0') then out (others '0'); elseif rising_edge (clk) then if (ld = '1') then out din; elseif (en ='1') then out af+1; end if; end if; end process; dout count; end architecture; סיכום ועריכה מאת שי ידרמן- VHDL |1 12.12.12 – 8 הרצאה Port map - אם הוא נכנס בתוך ה. הולך להיות בכל התכנית יש לאתחל אותו בהגדרתוGeneric-אם ה .אפשר להשאיר ריק :Generate לולאת . עבור פעולות גדולות יותרcomponent המטרה היא לכתוב באופן כללי יותר .component פעמיםn לא נכתוב. ביטים2 שלAdder ביטים באמצעותn שלadder נניח שרוצים לממש Carry_out- וCarry_in כל הבלוקים המשורשרים אליו הם בעלי,carry_in בלוק ראשון הוא ללא, מקרים3 נציין כי יש לנו : נכתוב.n+1- בערך הביט הCarry_out :והבלוק האחרון מחליף g1: for i in a'reverse_range generate g2: if (i=a'low) ganarate u1: fa port map ( a a(i) , b b(i) ci '0', s s(i), co c(i) ); end_ganarate g2; g3: if (i=a'high) generate u1 : fa port map ( a a(i) , b b(i) , ci c(i-1) , s s(i) , co s(i+1) ); end_ganarate g3; g4: if (i/= a'low and i/= a'high) generate u1 : fa port map ( a a(i) , b b(i) , ci c(i-1) , s s(i) , co c(i) ); end_ganarate g4; end_ganarate g1; סיכום ועריכה מאת שי ידרמן- VHDL |2 הרצאה 12.12.12 – 8 ניתן לפשט את התמונה ולחסוך את ההתמודדות עם מקרי הקצה .עלינו להגדיל את שרשרת ה ,Carry -לקבוע אותה כ 11-ביט במקום 11ואז נוכל לדלג על הרבה שלבים ע"י שנכתוב פשוט (מחוץ למסגרת :)Generate g1 ;'c(0) '0 ;)s(16) c(16 כעת עלינו לכתוב רק את ה port map-הראשון. ניתן התייחסות ל generic-בתוך חומרה באופן הבא: נניח ויש לנו חומרה כלשהי ,sואנו רוצים להתייחס למשתנה כללי אז יש להשים .Registerמבצעים זאת כך: "generic ( kind_of_output: string:= "registered"); -- "unregistered ) "g1: if (kind_of_output ="unregistered ;dout s ;end generate g1 g2: if (kind_of_output ="registered" ) generate process (din) is begin if rising_edge (clk) then ;dout s ;end if ;end process ;end generate g2 :Wait Statement השימוש ב wait-בא במקום רשימת הרגישות ומתבצע בתוך התהליכים בלבד .הם לא יבואו יחד .יש לנו 4צורות לשימוש בהם: - wait; .1עצירה של תהליך לנצח .נשתמש בו לביצוע חד פעמי של תהליך ללא אפשרות חזרה. - wait for time units; .2עצירה למשך זמן מסוים ,כאשר ב time-נכתוב את הזמן שלנו וב units-את יחידות הזמן. wait on s1,s2,….,sn; .3מחכים עד לשינוי לכל כיוון של לפחות אחד מהסיגנלים המופיעים ברשימה. wait until (cond.); .4מחכים עד למילוי התנאי הכתוב בסוגריים. כאשר משתמשים ב wait-כל הסיגנלים שלפניו מתעדכנים גם אם העצירה היא ל"-אפס" זמן. נציין כי ב VHDL-ניתן להגדיר משתנה מסוג timeשכל תפקידו הוא לקבוע משך זמן.signal t : time; : הפונקציה Nowמחזירה את ערך הזמן הנוכחי .ניתן להשתמש באופן הבא( .t1 now; :כאשר t1מוגדר סוג .)time ניתן להגדיר אותה בתור תנאי. if (now_t1) > 100 ns then : ניתן לשלב בין הצורות .wait on rst until rising_edge(clk) for 1 us; :מחכים לשילוב של שינוי ב reset-יחד עם עליית שעון או עד ,1usמה שבא קודם. |3 VHDL -סיכום ועריכה מאת שי ידרמן הרצאה 19.11.11 – 9 מבני מערכות: באיור הבא יש לנו מבנה כללי של מערכת ספרתית. השכבה המקווקות היא שכבת החומרה ) (Hardwareהנשלטת ע"י מערכת תוכנה ).(Software תפקיד החומרה הוא עיבוד נתונים דרך ה .Operational Unit-אלו הם רכיבים "דלי מוח" הנשלטים ע"י ה.Control Unit- הבקר שולח מילות בקרה המאפשרות שליטה מלאה על ה OU-דרך ה Control-והחומרה מעדכנת את הבקרה באמצעות קווי המצב ( .)Statusכלפי חוץ – כשעולים לשכבת התוכנה ) – (Softwareיש לנו את הבקרה החיצונית external controlואת דיווח מצב .external status din Data Path )(OU control ext.cntrl. FSM )(CU status microC/ user etc. ext.statu s. dout החומרה ניתנת לסיווג למכונות מילי ) (mealyומקרים פרטיים של .moore להלן תרשים זרימה של מכונת המצבים: (הקו המקווקו קיים רק ב.)Mealy- next state in out next state logic current state state Reg.x output logic ב moore-מבקשים בקשה ,המערכת מתכנסת ומוציאה מוצא במצב הבא .ב mealy-המוצא נכנס גם לכניסה. ב mealy-המוצא הוא פונקציה של הכניסה והמצב הנוכחי ,לכן בשינוי הכניסה ,המוצא משתנה מיד ועימו גם המצב הנוכחי ואז פעם נוספת משתנה המוצא עקב היותו תלוי בשניהם .לכן יש לנו סכנה בקבלת שרשרת של תגובות במוצא. ב VHDL-כותבים את ההתנהגות של המכונה (ולא טבלאות כפי שראינו במל"ס) .להלן תיאור מכונת מצבים פשוטה: _write mem y2 y2 x1 y1 idle x1 x2 y1 x1 y1 y2 x1 x2 _read mem y2 x2 אנו נכתוב מעל ה entity-את הסוג של הגדרת המצבים שלנו באמצעות typeבאופן הבאtype fsm_st is ( ) : כאשר בסוגריים נכתוב את המצבים .)idle , read mem , write mem) :מגדירים גם את האותות.signal ns , cs : fsm_st ; : מקובל לרשום את הערך הנמוך ביותר בתחילת הסוגריים ולאחריו את הערכים בסדר גדל .המבנה הקלאסי של מכונת המצבים מתואר בסכמה לעיל .ה state Reg-הוא לוגיקה ישירה .ה NS-הם לוגיקה צירופית המקבלת הוראות מה לעשות ובאיזה מצב אנחנו .כנ"ל לגבי ה .Output-נזכור כי עוסקים בלוגיקה צירופית ולכן יש לכסות את כל המצבים אחרת נקבל -latchים. חובה להגדיר את המצב ההתחלתי שבו המכונה מתעוררת .בעמוד הבא מופיע תיאור המלא. |1 VHDL -סיכום ועריכה מאת שי ידרמן 19.11.11 – 9 הרצאה type fsm_st is (idle , read mem, write mem); signal ns , cs : fsm_st; begin state_reg : process (clk , rst) is begin if (rst <= '0') then cs <= idle; elseif rising_edge (clk) then cs<=ns; endif; end process state_reg; common_logic: process (cs , x) is -- הלוגיקה עבור המצב הבא והמוצא זהה ולכן כותבים תהליך פעם אחת begin ns<=cs; -- שורה זו תורמת לקיצור הכתיבה בכך שהמצב הבא יקבל תמיד את הערך המצב הנוכחי בהתאם לקייסים y[2]<= '0' ; y[1]<='0'; case cs is when idle => if ( x[1]='1') then ns <=read_mem; y[2] <='1'; elseif ns<=idle; y[1]<='1'; endif; when read_mem => if (x[2]='1') then ns <=write_mem; y<='11'; elseif (x[1] = '0') then ns<=idle; y[1]<='1'; else ns<=read_mem; y[2]<='1'; endif; when write_mem => ns<=idle; y[2]<='1'; end case; end process; סיכום ועריכה מאת שי ידרמן- VHDL |2