Verilog Cheat Sheet: דף עזר מהיר
עודכן לאחרונה
מבנה מודול ופורטים
מודול הוא אבן הבניין הבסיסית: יש לו שם ורשימת פורטים.
| תחביר | משמעות |
|---|---|
module adder(...); ... endmodule | הגדרת מודול והגוף שלו |
input clk; | פורט קלט |
output q; | פורט פלט |
output reg q; | פלט שמוזן מבלוק always |
input [7:0] data; | אפיק קלט של 8 ביט (ווקטור) |
inout sda; | פורט דו-כיווני |
adder u1 (.a(x), .b(y), .sum(s)); | יצירת מופע של מודול עם פורטים לפי שם |
טיפוסי נתונים
wire מייצג חיבור; reg מחזיק ערך שקוד פרוצדורלי מציב בו.
| רכיב | מה הוא עושה |
|---|---|
wire w; | net שמוזן על ידי assign או פלט של מודול |
reg r; | מחזיק ערך שהוצב בתוך בלוק always/initial |
wire [3:0] bus; | ווקטור של 4 ביט (ביטים 3 עד 0) |
reg [7:0] count; | רגיסטר של 8 ביט |
bus[2] | בחירת ביט יחיד |
bus[3:1] | בחירת טווח של ביטים (part-select) |
reg mem [0:255]; | זיכרון: מערך של רגיסטרים |
parameter WIDTH = 8; | קבוע עם שם עבור המודול |
ליטרלים מספריים
הפורמט הוא <size>'<base><value>: הגודל בביטים, והבסיס כ-b/o/d/h.
| תחביר | משמעות |
|---|---|
4'b1010 | בינארי של 4 ביט, ערך 10 |
8'hFF | הקסדצימלי של 8 ביט, ערך 255 |
8'hff | אותו דבר: ספרות הקסדצימליות לא תלויות באותיות גדולות או קטנות |
16'd255 | עשרוני של 16 ביט, ערך 255 |
3'o7 | אוקטלי של 3 ביט, ערך 7 |
8'b1010_1100 | קווים תחתונים מקבצים ספרות לקריאות |
1'bx | ערך ביט לא ידוע (x) |
1'bz | ערך ביט בעכבה גבוהה (z) |
אופרטורים
אופרטורים ברמת הביט, לוגיים, השוואה וצמצום.
| אופרטור | מה הוא עושה |
|---|---|
& | ^ ~ | AND, OR, XOR, NOT ברמת הביט |
&& || ! | AND, OR, NOT לוגיים (מחזירים ביט אחד) |
== != < > <= >= | אופרטורי השוואה |
<< >> | הזזה שמאלה וימינה |
+ - * / % | אופרטורים אריתמטיים |
&bus | צמצום AND (AND של כל הביטים) |
|bus | צמצום OR (OR של כל הביטים) |
^bus | צמצום XOR (זוגיות של כל הביטים) |
{a, b} | שרשור; {4{1'b1}} משכפל ל-4'b1111 |
השמה רציפה
assign מזין wire באופן רציף: השתמשו בו ללוגיקה צירופית.
| תחביר | משמעות |
|---|---|
assign y = a & b; | הזנת y ב-AND של a ו-b |
assign sum = a + b; | חישוב סכום באופן רציף |
assign y = sel ? a : b; | אופרטור טרנרי: מרבב (multiplexer) 2 ל-1 |
assign {c, s} = a + b; | לכידת הנשא והסכום יחד |
assign y = ~en; | הזנת wire מאות הפוך |
בלוקים פרוצדורליים
always ו-initial מריצים פקודות; רשימת הרגישות קובעת מתי.
| תחביר | משמעות |
|---|---|
always @(*) begin ... end | לוגיקה צירופית (כל שינוי בקלט) |
always @(posedge clk) | הרצה בכל עליית שעון (סדרתי) |
always @(negedge clk) | הרצה בכל ירידת שעון |
always @(posedge clk or posedge rst) | בלוק מתוזמן עם reset אסינכרוני |
initial begin ... end | הרצה פעם אחת בזמן 0 (testbenches, בסימולציה בלבד) |
begin ... end | קיבוץ של כמה פקודות |
#10 | השהיה של 10 יחידות זמן (בסימולציה בלבד) |
השמה חוסמת מול לא חוסמת
השתמשו ב-= ללוגיקה צירופית וב-<= ללוגיקה סדרתית מתוזמנת.
| תחביר | משמעות |
|---|---|
a = b; | חוסמת: מתבצעת לפי הסדר, מיד |
a <= b; | לא חוסמת: קודם קוראים את כל הצדדים הימניים, ואז מציבים |
always @(*) y = a & b; | לוגיקה צירופית: השתמשו בהשמה חוסמת = |
always @(posedge clk) q <= d; | Flip-flop: השתמשו בהשמה לא חוסמת <= |
ערבוב של = ו-<= באותו בלוק | הימנעו מזה: מקור נפוץ לבאגים |
בקרת זרימה
תנאים והסתעפויות מרובות בתוך בלוקים פרוצדורליים.
| תחביר | משמעות |
|---|---|
if (cond) ... else ... | משפט תנאי |
if (a) x = 1; else x = 0; | if/else בשורה אחת |
case (sel) ... endcase | הסתעפות מרובה לפי ערך |
2'b00: y = a; | פריט case |
default: y = 0; | פריט case לברירת מחדל |
for (i = 0; i < 8; i = i + 1) | לולאה (לרוב בתוך generate או בסימולציה) |
repeat (4) @(posedge clk); | חזרה על פקודה N פעמים |
תבניות נפוצות
אבני בניין שכותבים שוב ושוב, וגם משימות ל-testbench.
| תבנית | תחביר |
|---|---|
| D flip-flop | always @(posedge clk) q <= d; |
| רגיסטר עם reset | always @(posedge clk) if (rst) q <= 0; else q <= d; |
| מונה | always @(posedge clk) count <= count + 1; |
| רגיסטר המצב של FSM | always @(posedge clk) state <= next_state; |
| לוגיקת המצב הבא של FSM | always @(*) case (state) ... endcase |
| הדפסת ערך | $display("q = %b", q); |
| הדפסה בכל שינוי | $monitor("t=%0t q=%b", $time, q); |
| סיום הסימולציה | $finish; |
כל רכיבי התחביר של Verilog שאתם צריכים, בעמוד אחד. ה-Verilog cheat sheet הזה הוא דף עזר מהיר לשפת תיאור החומרה: הגדרת מודולים ופורטים, בחירת טיפוסי נתונים, כתיבת לוגיקה צירופית וסדרתית, ותבניות ה-always שמתארות מעגלים אמיתיים.
התחביר כאן הוא Verilog סטנדרטי (IEEE 1364) ועובד בסימולטורים נפוצים כמו Icarus Verilog ו-Verilator. העתיקו את מה שאתם צריכים, או נסו בזמן אמת בעורך האונליין של Verilog: כתבו מודול, הריצו עליו סימולציה וראו את הפלט בדפדפן.
שאלות נפוצות על ה-Verilog cheat sheet
האם ה-Verilog cheat sheet הזה חינמי?
מה ההבדל בין wire ל-reg?
wire מייצג חיבור פיזי וחייב להיות מוזן באופן רציף, על ידי פקודת assign או פלט של מודול, ולכן משתמשים בו ל-nets צירופיים. reg שומר את הערך שלו עד שקוד פרוצדורלי משנה אותו, ולכן משתמשים בו לכל מה שמוצב בתוך בלוק always או initial. למרות השם, reg לא תמיד הופך לרגיסטר בחומרה; המשמעות היא רק שהערך נקבע באופן פרוצדורלי.מה ההבדל בין השמה חוסמת להשמה לא חוסמת?
=) מתבצעת מיד ולפי הסדר, כמו פקודה רגילה בתכנות, ולכן משתמשים בה ללוגיקה צירופית בבלוקי always @(*). השמה לא חוסמת (<=) מחשבת קודם את כל הצדדים הימניים ורק אז מעדכנת את כל הצדדים השמאליים יחד, וכך מתארת נכון flip-flops, ולכן משתמשים בה בבלוקים מתוזמנים מסוג always @(posedge clk). ערבוב של השתיים באותו בלוק הוא מקור קלאסי לבאגים בסימולציה.