Verilog căn bản: Bài 9: Cấu trúc always và initial

Lu ROm

Administrator
Staff member
25 Tháng bảy 2014
481
119
43
32
One piece
vimach.net
1, Giới thiệu
Ở các bài trước nhiều lần mình có nhắc khối always, initial. Vậy khối always là gì, cấu trúc và cú pháp như thế nào sẽ đực giới thiệu ở bài này. Như một bài toán ta luôn có một khối chính cho cả chương trình đó là module. Trong module chúng ta nhiều module con và mỗi module con có thể là một khối lớn hoặc chia ra thành những khối nhỏ. Mỗi khối nhỏ đó ta sẽ chứa đựng nó trong một khối khác gọi là khối alwáy (theo cách mình hiểu).Dưới đây là ví dụ chia nhỏ FULL ADDER thành những khối always khác. Đa số chúng ta sẽ chia hai khối mạch tuần tự và mạch tổ hợp. Trường hợp dưới rất ít khi dùng chỉ là ví dụ thôi :v.
full_adder_gate_design.png

2,Khối always
- Khối always được dử dụng để mô tả sự kiện xảy ra trong các điều kiện. nhất định ví dụ if, case....
- Là cấu trúc chính trong khuôn mẫu RTL (Register Transfer Level).Khối always có thể được dùng trong chốt, flip flop hay các kết nối logic.Tất cả các khối always trong một module thực thi một cách liên tục. nh. Nếu các lệnh của khối always nằm trong phạm vi khối begin… end thì được thực thi liên tục, nếu nằm trong khối fork… join, chúng được thực thi đồng thời (chỉ trong mô phỏng). Khối always thực hiện bằng mức, cạnh lên/xuống của một or nhiều tín hiệu (các tín hiệu cách nhau bởi từ khóa OR).(Copy trong sách :v)
-- Cú pháp chính của một khối always:
Mã:
always @(sensitivity_list)
begin
  local_variable_declarations;
  statements;
end
** Giải thích:
- sensitivity_list: là độ nhạy hay xung clock.
- local_variable_declarations: Khai báo các biến chỉ sử dụng trong khối begin-end.
- Statements: Các câu lệnh của bạn.
B, Phân loại.
- Khối always gồm 2 loại chính : always@(posedge Clock)always@(*).
-- always@(posedge Clock) : always tích cực ở sườn lên xung clock hoặc always@(negedge Clock) always tích cực ở sườn xuống xung clock. Khối always được sử dụng trong mạch tuần tự hoặc Register. Chỉ dùng phép gán non-blocking trong khối always@(posedge Clock). Gía trị của biến thay đổi trong khối always@(posedge Clock) phụ thuộc vào xung clock( sườn lên hoặc sườn xuống)
=Dví dụ:
Mã:
always @( posedge Clock ) 
begin
B< = A;
C< = B;
D< = C;
end
2.png

-- always@( * ) Blocks: dùng trong mạch tổ hợp hoặc các cổng logic.Chỉ dùng phép gán blocking. Dò sự thay đổi theo mức cổng nghĩa là đầu ra thay đổi khi đầu vào thay đổi. Có hai cách viết hoặc là để (*) hoặc bạn phải liệt kê tất cả các đầu vào của khối.
=DVí dụ
Mã:
wire Trigger , Pass ;
reg A, C;

always @( * ) begin
A = 1’b0;
C = 1’b1;
if ( Trigger ) begin
A = Pass ;
C = Pass ;
end
end
hoặc
cCxR0OZl4n-EoX28lRC_pAJWpuCfPcPCpuRLFqh54Kk=w504-h291-no

Mã:
always @(A) begin
C = A & B;
end

3, Khối initial
- Tương tự khối always nhưng khối initial chỉ thực thi một lần từ lúc bắt đầu( không bắt buộc phải là đầu tiên) của quá trình mô phỏng. Khối này là tiêu biểu để biến khởi chạy và chỉ định dạng sóng tín hiệu trong lúc mô phỏng. Khối initial chỉ dành cho thực hiện mã testbench.Khi chương trình tổng hợp khối initial sẽ được bỏ qua.

** Cú pháp khối initial
Mã:
initial <statements>
//OR
initial begin
<statement>
<statement>
<statement>
end
//OR
initial <delay_or_event_control> begin
//delay_or_event_control could be a delay, an edge, or level
<statement>
<statement>
<statement>
end
^_^ ví dụ
Mã:
module tb ();
parameter CYCLE = 100;
reg clk, reset_n;
//create the clock
initial begin
clk = 0;
forever #(CYCLE/2) clk = ~clk;
end
//time the release of reset
initial begin
reset_n = 0; //initalize reset aserted
#(3*CYCLE) @(posedge clk); //wait 3 clock cycles and one pos edge
@(negedge clk); reset_n = 1; //at the next negedge, release reset_n
end
endmodule
5.png