חזור לתיקייה: סדנה

1 - SystemVerilog I

חיפוש בתיקיה
Ctrl K
לחץ כאן או הקש Ctrl K כדי לחפש בכל התיקיה
  • מודול - module
  • סוגי שמירת מידע
  • חוט/ביט - logic
  • קבוצות של ביטים - vector
  • פעולות על וקטורים
  • הרכבת מודולים
  • מודולים בסיסיים
  • הפקודה generate

1 - SystemVerilog I

00440252

מערכות ספרתיות ומבנה המחשב

רשימות הרצאה לקריאה בשבת

SystemVerilog I

הופק מתוך תקיית התואר של שקד

uni-folder.vercel.app

אנו יכולים לייצג שערים לוגיים שראינו במספר דרכים, בין אם שרטוט ובין אם טבלת אמת. אנו הולכים ללמוד פה דרך נוספת לתאר מעגלים לוגיים - שפות תיאור חומרה.
זוהי אינה שפת תכנות. זוהי דרך לתאר את המחשב על מרכיביו הבסיסיים ביותר.

logic Z;
assign Z = X ~& Y;
logic Z;
always_comb
	if (X) Z = ~Y;
	else   Z = 1;

הדרך שבה אנו לוקחים "קוד" בשפת תיאור חומרה והופכים אותו לחומרה אמיתית היא יחסית דומה לדרך שבה מהדר מבצע הידור לשפת תכנות.
קוד המקור מתורגם ל-NetlistNetlistNetlist ומשם לחומרה. (מה זה NetlistNetlistNetlist נראה בהמשך)

שפת תיאור החומרה שאנו נראה בסדנאות היא SystemVerilogSystemVerilogSystemVerilog, שהיא השפה שלרוב מתמשים בה בתעשייה(בחשמל כמובן ולא במדמח)
כעת, בואו נתחיל מהבסיס:

מודול - modulemodulemodule

כל דבר שאנו רוצים לתאר יהיה מודול. זוהי בעצם קופסה שמקבלת קלט ופולטת פלט(זה בייסיקלי פונקציה)
​1 - SystemVerilog I 2026-05-18 08.48.15.excalidraw.svg
כל מודול מתחיל במילה modulemodulemodule ולאחריו שם. כל מודול מסתיים במילה endmoduleendmoduleendmodule והרי דוגמה:

module my_module(
	output logic out1,
	output logic out2,
	...,
	input logic inN
);

	... // declarations
	... // description of f

endmodule

שימו כי אין נקפ"ץ אחרי endmoduleendmoduleendmodule.

סוגי שמירת מידע

חוט/ביט - logiclogiclogic

סוג המידע logiclogiclogic מייצג חוט חשמל(ביט 1). אנו יכולים להגדירו כך:

logic a, b, c, d;
logic e;

משתנים מסוג logiclogiclogic יכולים להיות מהסוגים הבאים:

  • 000 - אפס, ground,falseground, falseground,false וכו'
  • 111 - אחד, power,truepower, truepower,true וכו'
  • XXX - או לא מאותחל או התנגשות
  • ZZZ - לא מחובר

כשאנחנו רואים XXX זה לאו דווקא רע אבל זה יכול להיות רע. את הערך ZZZ אנחנו לא נרצה לראות.

קבוצות של ביטים - vectorvectorvector

במשמעות שלנו, וקטור הוא לא כמו וקטור באלגברה - אלא הוא פשוט אוסף של מספרים.

logic [7:0] w1;

פה יצרנו וקטור(מערך) של 8 ביטים כאשר w1[7]w1[7]w1[7] הוא ה-MSBMSBMSB.

תרגיל

כתבו מעטפת למודול muxmuxmux.

module mux4to1(
	output logic O,
	input  logic D0,
	input  logic D1,
	input  logic D2,
	input  logic D3,
	input  logic E,
	input  logic [1:0] S
);
	... // declarations
	... // description of a mux
endmodule

פעולות על וקטורים

  1. בחירת ביט מסויים:
    w1[3]
    
  2. בחירת תת וקטור:
    w1[3:2]
    
  3. הכנסת משתנים לוקטורים:
    vec = {x, y, z};
    
    ניתן בנוסף לחזור על אותו הביט כמה פעמים כך:
    vec = {16{x}}; // 16 copies of x
    
  4. הוצאת משתנים מוקטורים:
    {carry, sum} = vec[1:0];
    
תרגיל

החליפו את ארבעת הביטים(nibblesnibblesnibbles) הגבוהים והנמוכים של w1w_{1}w1​ ושימו אותם ב-w2w_{2}w2​.

logic [7:0] w1;
logic [7:0] w2;
w2 = {w1[3:0], w1[7:4]};
תרגיל

מה הקוד הבא עושה?

logic [7:0] out;
logic [3:0] A;
out = {{4{0}}, A[3:0]};

נשים לב כי אנו לא יודעים האם המספר חיובי או שלילי, אם המספר חיובי אז הכל אחלה(וייייי) אם המספר שלילי, סימנו יתהפך ויהיו מלא בעיות.
הפעולה שביצענו נקראת Unsigned extension.

תרגיל

מה הקוד הבא עושה?

out = {{4{A[3]}}, A[3:0]};

פה אנחנו משכפלים את הביט האחרון ולכן אנו לא משנים את הערך ולא משנים את הסימן.
הפעולה נקראת Signed extension.

הרכבת מודולים

אנחנו לא נרצה לעשות הכל במודול אחד, בדיוק כמו שאנו לא נרצה לעשות הכל בפונקציה אחת. לשם כך אנחנו בעצם נקח מודולים ונשים אותם במודולים אחרים.

פה נראה שתי צורות קריאה למודולים מתוך מודולים אחרים

module_name instance_name1 (
	my_out1,
	my_out2,
	...,
	my_inN
);

פה אנחנו יודעים מה המשתנים לפי סדר הכנסתם. במידה ואנו רוצים לוודא שאנו מכניסים את הדברים נכון נוכל לעשות:

module_name instance_name2 (
	.out1(my_out1),
	.out2(my_out2),
	...,
	.inN(my_in1)
);

מודולים בסיסיים

בהקבלה לפקודות של שפת תכנות שמגיעות עם השפה(כגון ififif או פקודות הספרייה הסטנדרטית) גם ב-SystemVerilog יש לנו מודולים בסיסיים שמגיעים עם השפה והם:

  • AND
  • OR
  • NOT
  • XOR
  • NAND
  • NOR
  • XNOR

ונשתמש בהם כך:

gateName(output, input1, <input2>)
not(O1, A);
nor(O2, A, B);
דוגמה

בואו ניצור Half Adder. אנחנו עוד נראה את זה בהרצאה ובתרגול וכך זה נראה:

התוצאה שאנו מקבלים היא

S=A‾B+AB‾C=ABS=\overline{A}B+A\overline{B} \qquad \qquad C=ABS=AB+ABC=AB

כעת נכתוב את הקוד שיתאים ב-SystemVerilog:

module HA (
	output logic S,
	output logic C,
	input  logic A,
	input  logic B
);

	xor(S, A, B);
	and(C, A, B);

endmodule

הפקודה generategenerategenerate

אם נרצה להחליט בין שני וקטורים A,BA,BA,B ולבחור באחד מהם, בעצם נרצה לבנות muxmuxmux שכזה, נוכל להשתמש ב-muxmuxmux של ביט יחיד מלא פעמים, אבל זה הרבה לכתוב וזה מאוד חזרתי ולכן לא נרצה לעשות זאת. לשם כך נוכל להשתמש בפקודה generategenerategenerate שבעצם יוצרת חומרה בשבילנו. נראה שימוש בה:

module mux2to1_32 (
	output logic [31:0] O,
	input  logic [31:0] A,
	input  logic [31:0] B,
	input  logic        S
);
	genvar i;
	generate
		for (i = 0; i < 32; i++)
		begin
			mux2to1 mux_inst(.O(O[i]), .S(S), .A(A[i]), .B(B[i]));
		end
	endgenerate
endmodule