אופרטורים נוספים
| אופרטור | משמעות |
|---|---|
| קטן מ | |
| קטן או שווה ל | |
| גדול מ | |
| גדול או שווה ל | |
| שווה ל | |
| לא שווה ל | |
| וגם לוגי | |
| או לוגי | |
| היפוך לוגי |
תנאים
תנאי הוא די פשוט רק שאנו מחליפים את הסוגריים המסולסלים במילים המשונות כך:
if (condition) begin
<statement>;
end
else if (condition2) begin
<statement>;
end
else begin
<statement>;
end
module mux(
input logic A,
input logic B,
input logic sel,
output logic Q
);
always_comb begin
if (sel == 1'b0) begin
Q = A;
end
else begin
Q = B;
end
end
endmodule
התנאי מאפשר לנו להשוות בין מספר ערכים עבור אותו משתנה כך:
case (<signal/expression>)
<value1>: begin
<statement>;
end
<value2>: begin
<statement>;
end
default: begin
<statement>;
end
endcase
module case_example (
input logic A,
input logic B,
input logic [1:0] w,
output logic Y
);
always_comb begin
case (w)
2'b00: Y = A & B;
2'b01: Y = A | B;
2'b10: Y = A ^ B;
default: Y = ~B;
endcase
end
endmodule
ישנם שני סוגים של בלוקים של והם . ההבדל ביניהם הוא שב- הערכים ו- בלבד נחשבים ל- וב- הערך גם הוא(בנוסף לאחרים) נחשב ל-.
casez (w)
2'b1?: A = B + C; // if we get 10 we do A=B+C and also, if we get 11 we do the same
2'b01: A = B ^ C;
default: A = B - C;
endcase
הבלוק נועד ללוגיקה קומבינטורית ללא זיכרון.
אם אנו משנים ערך אך לא נותנים אופציה לכל מצב, המהדר מניח שאנו רוצים לשמור את הערך הקודם של המשתנה אך זה לא אפשרי בלוגיקה קומבינטורית שכן זה דורש התלוי בשעון.
כדי שלא יהיו לנו בעיות, תמיד נשים או אם אנו יוצרים תנאים בתוך .
זיכרון ובלוקים סינכרוניים
ראינו בלוקים קומבינטוריים שמיישמים מעגלים צירופיים. כעת נרצה לממש גם מעגלים סינכרוניים התלויים בשעון. לשם כך יש לנו את הבלוק .
always_ff @(posedge clock) begin
<sync statement>;
end
logic a, in;
always_ff @(posedge clock) begin
a <= in;
end
האופרטור פה משמש כהשמה לא חוסמת. כלומר, השמה המיועדת ספציפית ללוגיקה עם שעון אשר "דוגמת" את כל הערכים בכניסות בזמן עליית השעון ומעדכנת את כל היציאות בו-זמנית.
אם נרצה לעשות אתחול לשעון נוכל לעשות זאת בשני דרכים:
- אתחול א-סינכרוני:
always_ff @(posedge clock, posedge reset) begin if (reset == 1'b1) begin <reset statement>; end else begin <sync statement>; end end - אתחול סינכרוני:
always_ff @(posedge clock) begin if (reset == 1'b1) begin <reset statement>; end else begin <sync statement>; end end
logic a, in;
always_ff @(posedge clock, posedge reset) begin
if (reset == 1'b1) begin
a <= 1'b0;
end
else begin
a <= in;
end
end

נראה איך המעגל הזה נבנה ב- בשתי דרכים.
module my_module (
input logic clock,
input logic reset,
input logic A,
output logic B
);
logic and_out, or_out;
always_ff @(posedge clock, posedge reset)
begin
if (reset == 1'b1) begin
A <= 1'b0;
B <= 1'b1;
end
else begin
A <= or_out;
B <= and_out;
end
end
always_comb begin
and_out = A & B;
or_out = A | B;
end
endmodule
הדרך השנייה והפחות מומלצת היא ללא הפרדה בין הבלוקים:
module my_module (
input logic clock,
input logic reset,
input logic A,
output logic B
);
always_ff @(posedge clock, posedge reset)
begin
if (reset == 1'b1) begin
A <= 1'b0;
B <= 1'b1;
end
else begin
A <= A | B;
B <= A & B;
end
end
endmodule
עוד קצת על ניסויים
כשנרצה ליצור שעון נוכל לבנות בלוק אשר יהפוך את השעון שלנו כל שניות כך:
initial begin
Clock = 1'b0;
end
// ...
always begin
#10 Clock = ~Clock;
end
בנוסף, יש לנו בלוח חזרתיות אשר מתנהג כך:
repeat (num_of_times) begin
<statement>;
end
initial begin
repeat(4) begin
@(posedge clock);
end
end
נסתכל עכשיו על דוגמה ל- מלא:
module my_module_tb;
logic clock, reset;
logic A, B;
my_module inst(.clock(clock), .reset(reset), .A(A), .B(B));
always_begin
#10 clock = ~clock;
end
initial begin
clock = 1'b0;
reset = 1'b1;
@(posedge clock);
#7
reset = 1'b0;
repeat(2) begin
@(posedge clock);
end
end
endmodule
דוגמה: מונה פשוט
logic [3:0] next_counter, current_counter;
always_ff @(posedge clock, posedge reset) begin
if (reset == 1'b1) begin
current_counter <= 4'b0;
end
else begin
current_counter <= next_counter;
end
end
always_comb begin
next_counter = current_counterr + 1;
end
ניתן לעשות את זה גם בדרך דומה:
logic [3:0] current_counter;
always_ff @(posedge clock, posedge reset) begin
if (reset == 1'b1) begin
current_counter <= 4'b0;
end
else begin
current_counter <= current_counter + 1;
end
end