Está en la página 1de 163

ĐHBK Tp HCM

BMĐT
GV: Hồ Trung Mỹ

Thiết kế mạch số bằng Verilog

TLTK:
1. Stephen Brown, Fundamentals of Digital Logic with Verilog design
2. Raj Parihar, University of Rochester, USA
3. Slides của trường NTU, Taiwan
4. Slides của trường MIT, USA
1
Nội dung
• Cơ bản về Verilog
• Mô tả mạch tổ hợp
• Mô tả mạch tuần tự
• Mảng và bộ nhớ
• Mô tả máy trạng thái
• Mô tả RTL

2
Tổng hợp và ngôn ngữ mô tả phần cứng
(Synthesis and HDL)
• Ngôn ngữ mô tả phần cứng (HDL = Hardware Description Language) là biểu
diễn độc lập thiết bị của logic số. Có hai HDL thông dụng là VHDL và Verilog.

• Mô tả HDL được biên dịch thành


netlist (danh sách nối dây)

• Tổng hợp tối ưu hóa logic.

• Ánh xạ ra các công nghệ phần


cứng cụ thể

3
Luồng thiết kế phần cứng
Designer
Level Cost
RTL RTL High Low
Simulation Editor

RTL Code

Gate Level Logic


Simulation Synthesizer

Verilog Gate Level Code

Post Gate
Level Place & Route
Simulation
Physical Layout

Tape Out
Low High

Chip 4
TD Mux sang 1

sel sel in1 in2 out


to “select” output 0 0 0 0

in1 0
0 0 1 0

0 1 0 1
out
0 1 1 1
in2 1 1 0 0 0

1 0 1 1

1 1 0 0
if (sel==0) 1 1 1 1

out =in1;
else out =(sel’‧in1) +(sel‧in2)
out =in2;

5
Mô tả cấp cổng (Mô hình cấu trúc)

in1
a1_o
iv_sel a1 o out
in2
1
n1 a2 a2_o

sel iv_sel

Cấp cổng : Ta chỉ thấy các cổng và dây nối trong mã

6
Mô hình luồng dữ liệu (Dataflow model)
in1
module mux2(out, in1, in2, sel); iv_sel a1 a1_o
out
o
in2
output out; 1
a2 a2_o
input in1, in2, sel; n1

sel iv_sel
assign out = sel ? in1: in2;
// assign out = (!sel && in2) || (sel && in1); // toán tử logic
// assign out = (~sel & in2) || (sel & in1); // toán tử từng bit

endmodule

7
Mô tả cấp hành vi (Mô hình hành vi)

in1
a1_o
iv_sel a1 o out
in2
1
n1 a2 a2_o

sel iv_sel

always block
RTL: Ta có thể thấy hành vi cấp cao trong mã

8
Mã Verilog đơn giản

module name in/out port

declaration
syntax
port/wire
declaration

kernel hardware
gate-connection/
behavior

9
Module
• Khối xây dựng cơ bản trongVerilog.
• Module
1. Được tạo ra bằng “khai báo” (không cho phép lồng nhau)
2. Được sử dụng bởi “instantiation“

Giao tiếp được định nghỉa bằng các cổng


Có thể chứa nhiều instances của các module khác
Tất cả các module chạy song song nhau

10
Thực thể hóa module (Module Instantiation)

Adder

instance
example

Adder Adder

Adder_tree

11
Kết nối cổng

– Kết nối cổng module theo danh sách có thứ tự


• FA1 fa1(c_o, sum, a, b, c_i);

– Kết nối không đầy đủ


• FA1 fa3(c_o, , a, b, c_i);

– Kết nối cổng module theo tên


• FA1 fa2(.A(a), .B(b), .CO(c_o),.CI(c_i), .S(sum));
• Được khuyến cáo nên sử dụng
12
Một số định nghĩa module

13
Qui tắc ngôn ngữ Verilog
• Nhạy với chữ in hoa/thường

• Các danh hiệu: (bắt đầu chữ)


– Các ký số 0…9
– Gạch dưới _
– Các chữ in hoa và thường

• Kết thúc dòng bằng “;”

• Chú thích: (tương tự như C)


– Một dòng : // Đây là chú thích 1 dòng
– Nhiều dòng: /* Khi chú thích vượt quá 1 dòng ,
cần phải dùng chú thích kiểu này */

14
Thanh ghi và dây nối
(Register and Net)

• Các thanh ghi (registers)


– Từ khóa: reg, integer, time, real
– Phần tử lưu trữ
– Được gán trong các khối “always”

• Các dây nối (nets)


– Từ khóa : wire, wand, wor, tri
triand, trior, supply0, supply1
– Không lưu trữ giá trị, chỉ là kết nối
– input, output, inout có kiểu mặc nhiên là “wire”
– Được gán trị với gán liên tục assign hoặc gọi module
– Không thể gán trị cho nó trong khối “always”
15
Các biểu thức giá trị và số
• Tập giá trị Verilog gồm 4 giá trị cơ bản:
– 0 biểu diễn logic 0 hoặc điều kiện sai
– 1 biểu diễn logic 1 hoặc điều kiện đúng
– x biểu diễn giá trị logic không biết
– z biểu diễn tổng trỡ cao (hi-Z)

16
Các TD về biểu thức giá trị và số

659 // unsized decimal // underline usage


‘h 837ff // unsized 27_195_000
16’b0001_0101_0001_1111
hexadecimal
32’h12ab_f001
‘o7460 // unsized octal
4af // illegal syntax // X and Z is sign-extended
4’b1001 // 4-bit binary
5’D 3 // 5-bit decimal reg [11:0] a;
3’b01x // 3-bit number with initial
unknown LSB begin
12’hx // 12-bit unknown a = ‘hx; // yields xxx
8’d -6 // illegal syntax a = ‘h3x; // yields 03x
-8’d 6 // phrase as - (8’d6) a = ‘h0x; // yields 00x
end

117
Different ways of number representations in Verilog (1/2)

18
Different ways of number representations in Verilog (2/2)

19
Ghép nối dây :
Cách dễ dàng nhóm các dây

Module B
Module A

3‘o7
Module C
Biểu diiễn Ý nghĩa
{b[3:0],c[2:0]} {b[3] ,b[2] ,b[1] ,b[0], c[2] ,c[1] ,c[0]}
{a,b[3:0],w,3’b101} {a,b[3] ,b[2] ,b[1] ,b[0],w,1’b1,1’b0,1’b1}
{4{w}} {w,w,w,w}
{b,{3{a,b}}} {b,a,b,a,b,a,b}

18
Phát biểu gán liên tục assign
• Cú pháp: assign LHS = RHS;
với LHS (Left Hand Side) là vế trái và RHS là vế phải.
• TD:
wire F;
assign F = A ^ B ; // F = A  B
• LHS phải được khai báo net trước khi sử dụng.
• RHS có thể có kiểu dữ liệu reg, net, hoặc function.
• LHS được định trị bất cứ khi nào RHS thay đổi.
• Kết hợp với các toán tử để mô tả các biểu thức Boole.

21
Các toán tử Verilog (1/2)

22
Các toán tử Verilog (2/2)

23
Bảng chân trị của các toán tử từng bit

24
Thứ tự ưu tiên của các toán tử

25
TD: Các toán tử hữu dụng

26
TD: Toán tử rút gọn
module (in1, in2, out1, out2);
input [2:0] in1;
input in2;
output out1, out2;
wire out1, out2;

assign out1 = |{in1, in2};


assign out2 = ^in1;

endmodule

27
TD: Mạch so sánh độ lớn 4 bit
//4-bit magnitude comparator
module mag_comp(a_lt_b, a_gt_b, a_eq_b, a, b) ;

output a_lt_b, a_gt_b, a_eq_b;


input [3:0] a, b ;

wire a_lt_b, a_gt_b, a_eq_b;


assign a_lt_b = ( a < b ) ;
assign a_gt_b = ( a > b ) ;
assign a_eq_b = (a == b ) ;
endmodule

28
Các tham số
• Khai báo hằng số lúc chạy bằng parameter.
TD: parameter p = 8, real constant = 2.309 ;
• Các tham số với module
• Được dùng để cấu hình các giá trị thiết kế

• defparam: viết đè giá trị tham số


– Đặc tả sự phân cấp đầy đủ.
– Giá trị mới trong phiên bản module dùng #.
– Thứ tự các tham số giống như trong khai báo module
– Không cần gán các giá trị mới vào tất cả các tham số

29
Thủ tục có cấu trúc
• Cung cấp phương tiện để đặc tả sự đồng thời (song song)
– Phần cứng thật hoạt động đồng thời (song song ).
– Đây là khác biệt giữa HDL với các ngôn ngữ lập trình khác.
• các ngôn ngữ lập trình thì tuần tự.

• Phát biểu always và initial


– initial không thể tổng hợp được! Chỉ dùng để mô phỏng.

• Khối phát biểu bằng đầu bằng always hoặc initial được gọi
là các khối thủ tục.

• Sự đồng thời không thấy ở C.

30
Khối always
• Khối always chạy đồng thời.
• Có thể có 1 hoặc nhiều phát biểu gán thủ tục.
– Khi có nhiều phát biểu thì phải để nó trong cặp begin end.
• Phát biểu gán thủ tục chạy tuần tự.
• Danh sách dò (sensitivity list) quyết định khi nào khối
always được đi vào.
• Cú pháp:
always @ (sensitivity_list)
begin
// Một hoặc nhiều phát biểu gán thủ tục
end

31
Các phát biểu gán thủ tục
• Chặn (Blocking)
LHS = RHS ;

• Không chặn (Non-Blocking)


LHS <= RHS ;

• LHS phải có kiểu reg


– Lỗi biên dịch thông dụng là khai báo LHS là net.
– Giá trị LHS được giữ cho đến khi nó được lái lần nữa.

• Các qui tắc RHS : Giống như trong phát biểu gán liên tục
– Có thể là một biểu thức dùng các toán tử.

32
Gán chặn (blocking assignment)
• Cú pháp: LHS = RHS;
• Định trị RHS, gán giá trị vào LHS, tiến hành tiếp.
• Thứ tự thực thi được đặc tả trong phát biểu khối.

• Chỉ CHẶN trong khối đồng thời này.


• KHÔNG CHẶN các khối đồng thời khác.

• NÊN sử dụng trong các mô hình và testbench.


– Mô phỏng hiệu quả.
• Người ta thường dùng phát biểu gán chặn để mô tả
mạch tổ hợp bằng phát biểu always..
33
Gán không chặn (non-blocking
assignment)
• Cú pháp: LHS <= RHS;
• Định trị RHS, định thời biểu gán giá trị vào LHS, tiến hành
tiếp
– Các giá trị được gán vào cuối thời gian mô phỏng hiện hành
• Thứ tự thực thi độc lập với thứ tự phát biểu trong khối
• Được khuyến cáo dùng cho mô tả RTL
– Lập mô hình hành vi phần cứng
• Tránh điều kiện chạy đua
– Cùng danh hiệu được gán các giá trị khác nhau trong quá
trình khác.
• Không được dùng chung các phát biểu chặn và không
chặn trong cùng môt khối always.
34
Thí dụ: Chặn và không chặn
• Gán chặn: định trị và gán xảy ra tức thời!

• Gán không chặn: tất cả các phép gán được trì hoãn cho tới khi
tất cả các vế phải đã được định trị.

• Chú ý: Đôi khi cả hai tạo ra cùng kết quả! Đôi khi không!
35
Tại sao có 2 cách gán giá trị?

36
Các cách gán cho logic tuần tự

37
Sử dụng “không chặn” cho logic tuần tự

38
Sử dụng “chặn” cho logic tổ hợp

39
Các qui tắc gán tín hiệu
• Sử dụng always@(posedge clk) và các gán không chặn (<=)
để lập mô hình logic tuần tự đồng bộ. TD:
always@ (posedge clk)
q <= d; // nonblocking

• Dùng gán liên tục assign để lập mô hình logic tổ hợp đơn giản.
– TD: assign y = a & b;

• Sử dụng always@(*) và các gán chặn (=) để lập mô hình logic


tổ hợp phức tạp hơn.

• Không được gán vào cùng một tín hiệu trong hơn một phát biểu
always hoặc phát biểu gán liên tục.

40
Các phát biểu tuần tự (hay thủ tục)
Các phát biểu hành vi này được dùng trong các khối always và
initial, task và function:
– if , if-else
– case
– for
– repeat
– while
– forever
– fork - join
– wait
– event
– delay
– disable
– assign - deassign
– force - release
41
Các phát biểu điều kiện if
• if (<condition>) Chú ý:
true_statement(s) Nhóm nhiều phát biểu lại bằng
• If (<condition>) cách đặt giữa 2 từ khóa begin và
end
true_statement(s)
TD:
else if (A == B)
false_statement(s) begin
• If (<condition>) F = 1;
true_statement(s) G = 0;
else if (<condition_1>) end
true_statement(s)
else
false_statement(s)
42
Phát biểu case
• Rẽ nhánh nhiều đường và chỉ hợp lệ trong function và cấu trúc
always.
• Cú pháp:
case(expression)
alternative_1 : statement(s)_1;
alternative_2 : statement(s)_2;
...
default: default_statement(s);
endcase
• (các) phát biểu mặc nhiên (default) được thực thi không có giá
trị rẽ nhánh (alternative_n) không khớp với biểu thức
(expression)
43
Phát biểu case – Gán trị mặc nhiên
• Có 2 cách gán trị mặc nhiên (default) vào biến

44
case vs if
• case và if có thể được dùng hoán đổi nhau để cài đặt thực thi điều kiên trong các khối
always.
• case dễ đọc hơn một chuỗi dài các phát biểu if...else
• TD: Mô tả mạch dồn kênh 2 sang 1

45
Phát biểu for (1/2)
• Phát biểu for hoàn toàn tương tự với for trong C.
• Cấu trúc của vòng lặp for:
for (assignment1; expression; assignment 2)
statement;
• Lưu đồ của phát biểu for:
• Thực thi tuần tự như sau:
1. Thực thi assignment1.
2. Định trị expression.
3. Nếu expression có trị đúng ( 0)
thì thực thi statement. Nhảy đến
bước 5.
4. Nếu expression có trị sai (= 0)
thì thoát khỏi vòng lặp.
5. Thực thi assignment2. Nhảy đến
bước 2.
46
Phát biểu for (2/2)
• TD: Mạch cộng song song 2 số nhị phân 8 bit có ngõ cho phép en.
module addfor(s,co,a,b,cin,en); • Phát biểu for của mã bên tương
output [7:0] s; output co; đương với:
Input [7:0] a,b; input en,cin; {c[1],s[0]} = (a[0] + b[0] + c[0]);
reg [8:0] c; reg co; reg [7:0] s; {c[2],s[1]} = (a[1] + b[1] + c[1]);
integer i; ...
always@ (posedge en) {c[7],s[6]} = (a[6] + b[6] + c[6]);
begin {c[8],s[7]} = (a[7] + b[7] + c[7]);
c[0] = cin; // cin = carry in
for (i = 0; i <= 7; i = i + 1) • Phải khai báo biến chạy trong
begin vòng for theo kiểu integer:
{c[i+1],s[i]} = (a[i]+b[i]+c[i]); integer i;
end
co = c[8]; // co = carry out
end
endmodule
47
Phát biểu while
• Cấu trúc của phát biểu while (hoặc vòng lặp while)
while (expression) statement(s);
• Thực thi như sau:
– Nếu expression có trị đúng ( 0) thì thực thi statement (hoặc
khối các phát biểu) và được lặp lại cho đến khi expression có trị
sai (= 0).
– Nếu expression có trị sai (= 0) thì thoát khỏi vòng lặp.
– Nếu expression có trị X hoặc Z thì được xử lý như có trị là 0.

• Thí dụ:
while (Count < 10)
begin
sum = sum + 5;
Count = Count +1;
end
48
Nội dung
• Cơ bản về Verilog
• Mô tả mạch tổ hợp
• Mô tả mạch tuần tự
• Mảng và bộ nhớ
• Mô tả máy trạng thái
• Mô tả RTL

49
Mô tả mạch tổ hợp bằng Verilog

• Bằng phát biểu gán liên tục assign cùng với các
toán tử

• Bằng phát biểu gán trong khối thủ tục always


– Các phép gán chặn xảy ra tuần tự được dùng cho
mạch tổ hợp.
– Các phép gán không chặn xảy ra song song tuần tự
được dùng cho mạch tuần tự.

50
Cách thiết kế mạch tổ hợp
Gồm có các bước sau:
1. Từ mô tả của vấn đề tìm ra hệ có bao nhiêu ngõ vào và bao
nhiêu ngõ ra, kích thước của chúng (1 bit hay nhiều bit) và đặt
tên các ngõ ra và vào này để khai báo trong module.
2. Tìm quan hệ vào và ra qua
1) Phân tích mạch để tìm biểu thức Boole các ngõ ra; hoặc
2) Lập bảng chân trị  dạng chính tắc của ngõ ra; hoặc
3) Hành vi của chúng
– Chú ý: Việc rút gọn hàm Boole chỉ có ý nghĩa khi ta dùng mô hình
cấu trúc mà thôi!
3. Viết mã Verilog cho mạch cần thiết kế bằng các phát biểu thích
hợp.
4. Kiểm chứng lại thiết kế qua quan sát các dạng sóng mô phỏng.

51
Thí dụ: Mô tả các cổng cơ bản

52
Thí dụ: Mô tả các cổng cơ bản (2/2)

53
Các cổng đệm (buffers)
• Chèn vào các cổng đệm đa tầng với các cổng có fan-out
cao để làm giảm bớt điện dung tải và giữ mức điện thế
đúng cho tầng mà nó lái.

54
Các cổng 3 trạng thái (tri-sate gates)
• Với mô hình cấu trúc, các cổng có dạng
gatename (output, input, control);

55
TD dùng cổng 3 trạng thái

B B
select m_out m_out
A A

select 56
TD: Mạch cảnh báo
• Giả sử 4 người có thể đế. Chuông cảnh báo được kích hoạt khi có từ 3
người (A, B, C) tới hoặc người thứ tư (D) đến cùng với (những) người
khác.

57
TD: Mạch cảnh báo (2/4)
• Một cách viết gọn hơn thông qua nhận xét ngõ ra Out viết dưới dạng
chính tắc thứ là:
Out = m(3, 5, 7, 9, 11, 13, 14, 15) với minterm theo A,B,C,D

• Ta có mã mới như sau


module four(A , B , C , D , Out);
input A , B , C , D;
output Out;
reg Out;

always @(A or B or C or D)
begin
case ({A , B , C , D})
3, 5, 7, 9, 11, 13, 14, 15: Out = 1;
default: Out = 0;
endcase
endmodule 58
TD: Mạch cảnh báo (3/4)
• Rút gọn hàm Boole để dùng cho mô hình cấu trúc

59
TD: Mạch cảnh báo (4/4)
• Dùng mô hình hành vi:

module four(A , B , C , D , Out);


input A , B , C , D;
output Out;
reg Out;

always @(A or B or C or D)
If ( ( A && B && C) || (D & ( A | B | C) )
Out = 1;
else
Out = 0;
endmodule
60
Bộ cộng toàn phần (FA) 1 bit (1/4)

61
Bộ cộng toàn phần (FA) 1 bit (2/4)
X
Y s
Cin

• 2 dạng mạch z1
của FA 1 bit
z2
Cout

z3

Mạch dạng 1
Cin
s
X z1
Y
z3
Cout
z2
Mạch dạng 2 62
Bộ cộng toàn phần (FA) 1 bit – Verilog (3/4)
// Mô hình cấu trúc dạng 1 // Mô hình cấu trúc dạng 2
module fulladd (Cin, x, y, s, Cout); module fulladd (Cin, x, y, s, Cout);
input Cin, x, y; input Cin, x, y;
output s, Cout; output s, Cout;
wire z1, z2, z3; wire z1, z2, z3;

xor (s, x, y, Cin); xor (s, Cin, z1);


and (z1, x, y);
xor (z1, x, y);
and (z2, x, Cin);
and (z2, x, y);
and (z3, y, Cin);
and (z3, Cin, z1);
or (Cout, z1, z2, z3);
or (Cout, z3, z2);

endmodule
endmodule

63
Bộ cộng toàn phần (FA) 1 bit – Verilog (4/4)
// Mô hình dataflow // Mô hình hành vi
// dùng gán liên tục // dùng gán chặn
module fulladd (Cin, x, y, s, Cout); module fulladd (Cin, x, y, s, Cout);
input Cin, x, y; input Cin, x, y;
output s, Cout; output s, Cout;
reg s, Cout;
assign s = x ^ y ^ Cin;
assign Cout = (x & y) | (x & Cin) | always @ (x, y, Cin)
(y & Cin); {Cout, s} = x + y + Cin;
/* Hoặc gán như sau:
assign s = x ^ y ^ Cin, endmodule
Cout = (x & y) | (x & Cin) | (y & Cin);
*/

endmodule

64
Bộ cộng n -bit
• Mạch này thực hiện cộng 2 toán hạng n-bit cho kết quả là tổng n-bit cùng với 1 bit
nhớ.
– Mạch được xây dựng từ những FA 1 bit

a) Mạch cộng n bit

b) Mạch cộng/trừ n bit

65
Bộ cộng 4 bit (1)
module adder4 (carryin, x3, x2, x1, x0, y3, y2, y1, y0, s3, s2, s1, s0,
carryout);
input carryin, x3, x2, x1, x0, y3, y2, y1, y0;
output s3, s2, s1, s0, carryout;
fulladd stage0 (carryin, x0, y0, s0, c1);
fulladd stage1 (c1, x1, y1, s1, c2);
fulladd stage2 (c2, x2, y2, s2, c3);
fulladd stage3 (c3, x3, y3, s3, carryout);
endmodule

module fulladd (Cin, x, y, s, Cout);


input Cin, x, y;
output s, Cout;
assign s = x ^ y ^ Cin,
assign Cout = (x & y) | (x & Cin) | (y & Cin);
endmodule
66
Bộ cộng 4 bit (2)
// Mạch cộng 4 bit dùng vector
module adder4 (carryin, X, Y, S, carryout);
input carryin;
input [3:0] X, Y;
output [3:0] S;
output carryout;
wire [3:1] C;

fulladd stage0 (carryin, X[0], Y[0], S[0], C[1]);


fulladd stage1 (C[1], X[1], Y[1], S[1], C[2]);
fulladd stage2 (C[2], X[2], Y[2], S[2], C[3]);
fulladd stage3 (C[3], X[3], Y[3], S[3], carryout);

endmodule
67
Bộ cộng n bit
// Bộ cộng n bit tổng quát (xem cách khác trong sách)
module addern (carryin, X, Y, S, carryout, overflow);
parameter n = 32;
input carryin;
input [n-1:0] X, Y;
output [n-1:0] S; reg [n-1:0] S;
output carryout, overflow; reg carryout, overflow;

always @ (X, Y, carryin)


begin
{carryout, S} = X + Y + carryin;
overflow = (X[n-1] & Y[n-1] & ~S[n-1]) | (~X[n-1] & ~Y[n-1] &
S[n-1]);
end
endmodule
68
Mạch dồn kênh 2 sang 1 (mux 2 to 1)

69
Mạch dồn kênh 2 sang 1 (mux 2 to 1) - Verilog
• Phần chung của các mã sau đây
module mux2to1 (w0, w1, s, f);
input w0, w1, s;
output f;
// Mã verilog thực hiện MUX 2 sang 1 ( 1 trong cách sau)
endmodule

// Dùng always với if


// Dùng gán liên tục với reg f;
// toán tử điều kiện
always @(w0, w1, s)
assign f = s ? w1 : w0; if (s==0)
f = w0;
// Dùng always với toán tử ? else
reg f; f = w1;
/* hoặc
always @(w0, w1, s) if (s) f =w1 else f = w0;
f = s ? w1 : w0; */ 70
Mạch dồn kênh 4 sang 1

71
Mạch dồn kênh 4 sang 1 (mux 4 to 1) - Verilog
• Phần chung của các mã sau đây
module mux4to1 (W, S, f);
input [3:0] W;
input [1:0] S;
output f; reg f; // Không có reg f với gán liên tục
// Mã verilog thực hiện MUX 4 sang 1 ( 1 trong cách sau)
endmodule

// Dùng gán liên tụccase // Dùng if-else // Dùng case


assign always @ (*) always @ (*)
f = (S == 0)? W[0]: if (S == 2'b00) case (S)
(S == 1)? W[1]: f = W[0]; 0: f = W[0];
(S == 2)? W[2]: else if (S == 2'b01) 1: f = W[1];
W[3]; f = W[1]; 2: f = W[2];
// hoặc else if (S == 2'b10) 3: f = W[3];
// assign f = ~S[1]&~S[0] &W[0] | f = W[2]; endcase
~S[1]&[0]&W[0] | S[1]&~S[0]&W[2] | else if (S == 2'b11)
S[1]&S[0] &W[3]; f = W[3];
*/ 72
Mạch giải mã (Decoder)

73
Mô tả mạch giải mã 2 sang 4
• Phần chung của các mã sau đây
module dec2to4 (W, En, Y);
input [1:0] W;
input En;
output [0:3] Y; reg [0:3] Y;
// Mã verilog thực hiện decoder 2 sang 4 ( 1 trong cách sau)
endmodule
// Dùng if và case // Dùng for và if
// Dùng case always @ (W or En) Integer k;
always @ (W or En) If ( En == 0) always @ (W or En)
case ({En, W}) Y = 4’b1000; for (k = 0; k <= 3; k = k+1)
3’b100: Y = 4’b1000; else If ((W == k) && (En == 1))
3’b101: Y = 4’b0100; case (W) Y[k] = 1;
3’b110: Y = 4’b0010; 0: Y = 4’b1000; else
1: Y = 4’b0100; Y[k] = 0;
3’b111: Y = 4’b0001;
2: Y = 4’b0010; /* Hoặc cách khác
default: Y = 4’b0000;
3: Y = 4’b0001; for (k = 0; k <= 3; k = k+1)
endcase default: Y = 4’b0000; if (W == k) Y[k] = En;
endcase */
74
Mạch mã hóa 2n sang n

Bảng chân trị của mạch mã hóa Bảng chân trị của mạch mã hóa
4 sang 2 ưu tiên 4 sang 2

75
// Cách 1: Dùng casex

Mạch mã hóa ưu tiên


4 sang 2

// Cách 2: Dùng for

76
Mạch giải mã
BCD ra 7 đoạn

77
ALU 74381

Bảng hoạt động của ALU

78
Mạch dịch bit (Shifter)
module shifter (W, Shift, Y , k);
input [3:0] W;
input Shift;
output [3:0] Y; reg [3:0] Y;
output k; reg k;
always @ (W or Shift)
begin
if (Shift)
// Cách 2: begin
if (Shift) Y[3] = 0;
Y[2:0] = W[3:1];
begin
k = W[0];
Y = W >> 1;
end
k = W[0];
else
end begin
else Y = W;
begin k = 0;
Y = W; end
k = 0; end
end endmodule

79
Mạch dịch xoay vòng (barrel shifte)
module barrel (W, S, Y );
input [3:0] W;
input [1:0] S;
output [3:0] Y;
wire [3:0] T;

assign {T, Y} = {W, W} >> S;

endmodule

80
Mạch so sánh (Comparator) (1/4)

81
Mạch so sánh (Comparator) (2/4)

82
Mạch so sánh (Comparator) (3/4)

83
Mạch so sánh (Comparator) (4/4)

84
Nội dung
• Cơ bản về Verilog
• Mô tả mạch tổ hợp
• Mô tả mạch tuần tự
• Mảng và bộ nhớ
• Mô tả máy trạng thái
• Mô tả RTL

85
Mạch chốt D

module D_Latch(G, D, Q);


input G, D;
output Q; reg Q;

always @(D or G)
if (G)
Q = D;
G
  endmodule
D     
Q   
Q=D Chốt Q=D Chốt Q=D

86
Latch vs. Flip-Flop

87
Các flip-flop RS, JK và D
• Chú ý: Thực tế người ta dùng nhiều D F/F và JK F/F

88
D Flip-flop

reg

reg

reg

89
JK Flip-flop

;
;

90
Gán chặn và không chặn

 Phần cứng tương ứng  Phần cứng tương ứng

91
TD: Ngõ vào D F/F là mạch tổ hợp
với phát biểu chặn

92
TD: Ngõ vào D F/F là mạch tổ hợp
với phát biểu không chặn

93
D Flip-flop với Reset

94
D Flip-flop với Set

95
D Flip-flop với Set và Reset

96
D Flip-flop với Enable hoặc Load

97
Thanh ghi 4 bit

98
Theo dõi những chốt không chủ ý (1/6)

Hiểu ngầm

99
Theo dõi những chốt không chủ ý (2/6)

100
Theo dõi những chốt không chủ ý (3/6)
Theo dõi những chốt không chủ ý
• Phải đặc tả đầy đủ tất cả các mệnh đề cho phát biểu if và
case.
• Phải đặc tả đầy đủ tất cả các ngõ ra cho mọi mệnh đề của
phát biểu if và case.
• Nếu thực hiện không đúng sẽ có những hiệu ứng phụ không
mong muốn!

101
Theo dõi những chốt không chủ ý (4/6)

102
Theo dõi những chốt không chủ ý (5/6)

103
Theo dõi những chốt không chủ ý (6/6)

104
Thanh ghi dịch tổ hợp (1/2)

105
Thanh ghi dịch tổ hợp (2/2)

106
Thanh ghi dịch SISO (1/2)

107
Thanh ghi dịch SISO (2/2)

108
Thanh ghi dịch SIPO

109
Thanh ghi dịch PISO

110
Thanh ghi dịch PIPO

111
Bộ đếm đồng bộ và bộ đếm bất đồng bộ
(Synchronous counter and Asynchronous counter)

• Bộ đếm đồng bộ (còn gọi là bộ đếm song song): Tất cả


các flip-flop trong bộ đếm có cùng xung nhịp (clock) và thay
đổi trạng thái cùng 1 lúc khi có sự thay đổi cạnh lên của
clock (hoặc cạnh xuống).

• Bộ đếm bất đồng bộ (còn gọi là bộ đếm gợn).Những


chuyển tiếp của flip-flop truyền từ flip-flop này sang flip-flop
kế tiếp cho đến khi tất cả flip-flop đạt đến giá trị ổn định mới
(trạng thái của nó). Mội flip-flop được mắc như mạch chia
đôi tần số.

112
Bộ đếm đồng bộ (1/3)
Bộ đếm lên 3 bit

113
Bộ đếm đồng bộ (2/3)
Bộ đếm lên có ngõ điều khiển nạp (Load) trị đầu

114
Bộ đếm đồng bộ (3/3)
Bộ đếm lên/xuống

115
Bộ đếm bất đồng bộ (1/5)
• Mội flip-flop được mắc mạch chia đôi tần số clock của nó

116
Bộ đếm bất đồng bộ (2/5)
Bộ đếm xuống 4 bit (chia tần số 16)

117
Bộ đếm bất đồng bộ (3/5)

118
Bộ đếm bất đồng bộ (4/5)
Bộ đếm lên 4 bit (chia tần số 16)

119
Bộ đếm bất đồng bộ (5/5)

120
Nội dung
• Cơ bản về Verilog
• Mô tả mạch tổ hợp
• Mô tả mạch tuần tự
• Mảng và bộ nhớ
• Mô tả máy trạng thái
• Mô tả RTL

121
Mảng (Array)
• 1 chiều (1D) và 2 chiều (2D)
– TD: regindex [0:7] ; // mảng 1 D
• 1D không giống như kiểu dữ liệu vector/bus
– TD: wire [7:0] index ;
– Bus là ma trận hàng , trái lại 1D là ma trận cột
• Mảng không thể có kiểu real (số thực)
• Mảng 2D được dùng để mô hình bộ nhớ (RAM/ROM)
Cú pháp: reg [MSB:LSB] mem_name[first_addr: last_addr] ;
– Bộ nhớ được truy cập bằng cách ghi tên bộ nhớ và địa chỉ.
TD: out = mem_name[32] ;
– Không thể truy cập 1 bit bộ nhớ trực tiếp, người ta thường chép nó
vào một biến tạm và truy cập biến này
TD: temp = mem_name[32] ;
b0 = temp[0];

122
Mô hình RAM (1/2)
RAM bất đồng bộ (không có clock)

Đọc bộ nhớ
Ghi bộ nhớ 123
Mô hình RAM (2/2)
RAM đồng bộ

Đọc bộ nhớ

Ghi bộ nhớ 124


Mô hình ROM – với En kích cạnh (1)
module myrom (en, addr, data);
module test(En, A, D); parameter addr_w = 3, data_w = 9;
parameter addr_w = 3, data_w = 9; input en;
input En; input [addr_w:0] addr;
input [addr_w-1:0] A; output [data_w-1:0] data;
output [data_w-1:0] D; reg [data_w-1:0] data;

always @(posedge en)


//Look up constant coefficients case(addr)
myrom u1(En, A, D); 3'b000: data = 0;
3'b001: data = 109;
endmodule 3'b010: data = 107;
3'b011: data = 216;
3'b100: data = 111;
3'b101: data = 220;
3'b110: data = 218;
3'b111: data = 327;
default: data = 'bX;
endcase
endmodule
125
Mô hình ROM – với En kích mức thấp (2)
module test(En, A, D);
parameter addr_w = 3, data_w = 9; //Look up constant coefficients
input En; assign D = !En ? myrom(A) : 9'bZ;
input [addr_w-1:0] A;
output [data_w-1:0] D; endmodule
// ROM model with function
function [8:0] myrom;
input [3:0] addr;
case(addr)
3'b000: myrom = 0;
3'b001: myrom = 109;
3'b010: myrom = 107;
3'b011: myrom = 216;
3'b100: myrom = 111;
3'b101: myrom = 220;
3'b110: myrom = 218;
3'b111: myrom = 327;
default: myrom = 'bZ;
endcase
endfunction
126
Dạng sóng mô phỏng với mô hình ROM
• Cách 1: Mô hình ROM dùng function với ngõ En tích cực thấp

• Cách 2: Mô hình ROM dùng module với ngõ En kích cạnh lên

127
Nội dung
• Cơ bản về Verilog
• Mô tả mạch tổ hợp
• Mô tả mạch tuần tự
• Mảng và bộ nhớ
• Mô tả máy trạng thái
• Mô tả RTL

128
Máy trạng thái (FSM)
Máy trạng thái [hữu hạn] (Finite State Machine) gồm

• Thanh ghi trạng thái (State register)
– Lưu trữ trạng thái hiện hành (current
state hoặc present satet = PS) và
– Nạp trạng thái kế (next sate = NS) ở cạnh
xung clock
– Mạch tuần tự

• Logic trạng thái kế (Next state logic)


– Xác định trạng thái kế
– Mạch tổ hợp

• Logic ngõ ra (Output logic)


– Sinh ra các giá trị ở ngõ ra
– Mạch tổ hợp
129
Máy trạng thái Moore và Mealy
• Trạng thái kế được xác định bởi trạng thái hiện tại và các ngõ vào.
• Có 2 kiểu FSM khác nhau ở logic ra:
– FSM Moore: các ngõ ra chỉ phụ thuộc vào trạng thái hiện tại
– FSM Mealy: các ngõ ra phụ thuộc vào trạng thái hiện tại và các ngõ vào

130
Mạch phát hiện chuỗi bit vào
• Đặc tả mạch
– Thiết kế một mạch mà có ngõ ra là 1 khi ngõ vào (1 bit) có 3 bit 1
liên tiếp và ngõ ra là 0 nếu 3 bit vào liên tiếp không phải chuỗi này

• Kiểu FSM
– FSM Moore hay Mealy?
– Cả hai đều có thể
– Chọn Moore để đơn giản giản đồ trạng thái

• Giản đồ trạng thái (State diagram):


– Trạng thái S0: không phát hiện bit 1 nào
– Trạng thái S1: Phát hiện một bit 1
– Trạng thái S2: Phát hiện hai bit 1
– Trạng thái S3: Phát hiện ba bit 1
131
Mạch phát hiện chuỗi bit vào – Moore FSM (1/2)
module seq3_detect_moore(x, clk, y);
input x, clk;
output y;
reg [1:0] state, nstate; // nstate = next state
parameter S0 = 2'b00, S1=2'b01, S2=2'b10, S3=2'b11;

// State register
always@(posedge clk)
state <= nstate;

// Next state Logic


always@(state or x)
case(state)
S0:nstate = x? S1: S0;
S1:nstate = x? S2: S0;
S2:nstate = x? S3: S0;
S3:nstate = x? S3: S0;
default: nstate = S0;
endcase

// Output Logic
assign y = (state == S3);
endmodule

132
Mạch phát hiện chuỗi bit vào – Moore FSM (2/2)
• Cách 2: Kết hợp “state register” và “next state logic” vào chung 1 always.

133
Dạng sóng mô phỏng với máy trạng thái Moore
 Gán trạng thái nhị phân trực tiếp: S0 = 00, S1 = 01, S2 = 10 và S3 = 11

    

Gai nhiễu Gai nhiễu


Gán trạng thái mã Gray: S0 = 00, S1 = 01, S2 = 11 và S3 = 10

134
Mạch phát hiện chuỗi bit vào – Mealy FSM (1/2)
module seq3a_mealy(x,clk, reset_n, y);
// Mealy machine for a three-1s sequence detection
input x, clk, reset_n;
// Next state logic
// Use blocking assignments "="
output y;
always @(x or pstate)
reg [1:0] pstate, nstate; //present and next states
case (pstate)
parameter S0=2'b00, S1=2'b01, S2=2'b11,
S3=2'b10; // Better!!! No glithces!
S0:nstate = x? S1: S0;
S1:nstate = x? S2: S0;
S2:nstate = x? S3: S0;
// State register logic
S3:nstate = x? S3: S0;
always @(posedge clk or negedge reset_n)
default: nstate = S0;
if (!reset_n)
endcase
pstate <= S0;
else
// Output logic
pstate <= nstate; assign y = x ? (pstate == S3) : 0;
endmodule

135
Dạng sóng mô phỏng với máy trạng thái Mealy
 Gán trạng thái mã Gray: S0 = 00, S1 = 01, S2 = 11 và S3 = 10

136
Mạch phát hiện chuỗi bit vào – Mealy FSM (2/2)
• Cách 2: Kết hợp “state register” và “next state logic” vào chung 1 always.

137
Dạng sóng mô phỏng với máy trạng thái Mealy
 Gán trạng thái nhị phân trực tiếp: S0 = 00, S1 = 01, S2 = 10 và S3 = 11

Gai nhiễu Gai nhiễu


 Gán trạng thái mã Gray: S0 = 00, S1 = 01, S2 = 11 và S3 = 10

138
Các hướng dẫn gán trạng thái
• Hai trạng thái gọi là kế nhau khi biểu diễn nhị phân
của chúng chỉ khác nhau 1 bit:
– 001 và 011 là kế nhau
– 010 và 001 là không kế nhau
• Hướng dẫn 1: Các trạng thái có cùng trạng thái
kế với cùng giá trị vào thì nên gán trạng thái kế
nhau.

• Hướng dẫn 2: Các trạng thái là trạng thái kế


của cùng trạng thái trước thì nên gán trạng thái
kế nhau.

• Hướng dẫn 3: Các trạng thái có cùng giá trị ra


với cùng giá trị vào thì nên gán trạng thái kế nhau.
139
Reset với FSM
• Thực tế phải luôn có tín hiệu Reset với FSM để có thể chạy từ
trang thái đầu mong muốn. Có 2 loại Reset: bất đồng bộ và
đồng bộ.
• Reset bất đồng bộ: có dạng (giả sử Reset tích cực thấp)
always @(posedge clk or negedge Reset)
if (! Reset)
state = S0;
else case(state) ….. endcase
• Reset đồng bộ: có dạng
always @(posedge clk )
if (! Reset)
state = S0;
else case(state) ….. endcase
140
Nội dung
• Cơ bản về Verilog
• Mô tả mạch tổ hợp
• Mô tả mạch tuần tự
• Mảng và bộ nhớ
• Mô tả máy trạng thái
• Mô tả RTL

141
Bức tranh tổng quát về RTL
Thông thường một RTL (Register
Transfer Logic = logic chuyển thanh
ghi) gồm 2 phần chính:

• Datapath (Đường [dẫn] dữ


liệu)
– Các phần tử tổ hợp
– Các phần tử tuần tự
– Cấu trúc nối bus

• Controller (bộ điều khiển)


– Các máy trạng thái

Chuyên đề RTL này tham khảo từ


Bài giảng của Prof. Zain Navabi, 2014
142
Các phần tử xử lý

Các phần tử tổ hợp

Các phần tử tuần tự

143
Hệ thống nối bus
Truyền thông trong RTL
• Cấu trúc nối bus

144
Bộ điều khiển
Các máy trạng thái
Moore/Mealy
Kiểu mã Huffman

145
Các phần tử tổ hợp của thiết kế RTL (1/5)
• Các đơn vị logic units, các đơn vị số học, các bus
– Logic ngẫu nhiên (Random logic)
– Phần cứng lặp (Iterative hardware)
– Hệ thống nối bus (Bussing system)
– Các đơn vị logic tổng quát (General logic units)

146
Các phần tử tổ hợp của thiết kế RTL (2/5)
Logic ngẫu nhiên
• Dùng phát biểu gán đồng thời (hay gán liên tục) assign
• TD: Biểu thức Boole
module someLogic (a, b, c, d, y );
input a, b, c, d;
output y;
assign y = ((a&b) | (b&c) | (a&c)) ^ d;
endmodule

• TD: Biểu thức có điều kiện


module someLogic (a, b, c, d, y );
input a, b, c, d;
output y;
assign y = d ? ~((a&b) | (b&c) | (a&c)) :
((a&b) | (b&c) | (a&c));
endmodule 147
Các phần tử tổ hợp của thiết kế RTL (3/5)
Logic lặp [lại] (Iterative logic)
• TD: 32-bit ripple carry adder

148
Các phần tử tổ hợp của thiết kế RTL (4/5)
Hệ thống nối bus (Busing system)
• Dùng các phát biểu assign
• TD: Hệ thống 3 bus

module bussingSystem (abus, bbus, cbus, sa, sb, sc, ybus );


input [7:0] abus, bbus, cbus;
input sa, sb, sc; // sa = Select a
output [7:0] ybus;

assign ybus = sa ? abus : 8’bz;


assign ybus = sb ? bbus : 8’bz;
assign ybus = sc ? cbus : 8’bz;
endmodule

149
Các phần tử tổ hợp của thiết kế RTL (5/5)
Các đơn vị logic tổng quát (General logic units)
• TD: ALU 8 bit với cờ zero.
module alu_8bit (a, b, f, gt, zero, y);
input [7:0] a, b;
input [1:0] f;
output gt, zero;
output [7:0] y; reg [7:0] y

always @ ( a or b or f )
case ( f )
2'b00 : y = a + b;
2'b01 : y = a > b ? a : b;
2'b10 : y = a & b;
2'b11 : y = a ^ b;
default: y = 4'b0000;
endcase
assign gt = a > b;
assign zero = (y==8’b0) ? 1’b1 : 1’b0;
endmodule
150
Các phần tử tuần tự của thiết kế RTL
• Gồm có
– Các thanh ghi (Registers)
– Các thanh ghi dịch (Shift registers)
– Các bộ đếm (Counters)

151
Phương pháp luận RTL (1/4)
Thiết kế cấp transistor

152
Phương pháp luận RTL (2/4)
Thiết kế cấp cổng

153
Phương pháp luận RTL (3/4)
Thiết kế cấp RT (chuyển thanh ghi)

154
Phương pháp luận RTL (4/4)
Thiết kế cấp hệ thống (System level design)
• Kết các CPU, bộ nhớ, v.v.
lại qua các kết nối kênh
truyền

155
Đường dẫn dữ liệu và bộ điều khiển
(Datapath and controller)

• Bất kỳ phần tử nào mà truyền, giữ hoặc xử lý dữ liệu là phần tử


datapath.
• Controller là phần tư duy của hệ thống.
• Ta nên quyết địnnh làm thế nào để nối các phần tử datapath lại với
nhau.
• Khi thiết kế datapath, đừng quan tâm về các tín hiệu điều khiển
được đưa ra như thế nào.
156
TD: Thiết kế bộ chia nguyên không dấu đơn giản

• Chia A cho B bằng cách trừ B vào A cho đến khi phần dư
nhỏ hơn B.
• Số lần số phép trừ xảy ra thành công là thương số (qbus).
• Giá trị còn lại là dư số (rbus).

157
Bộ chia nguyên không dấu (UID)

• Mạch có bus vào 16 bit cho A, bus vào 8 bit cho B và 2 bus
8 bit cho số dư và thương số.
• Sau khi có xung cho phép chạy, mạch đọc các toán hạng A
và B và phép chia bắt đầu.
• Sau phép chia hoàn tất, mạch đặt dư số R và thương số Q
vào các bus tương ứng (rbus và qbus) và phát ra 1 xung có
thời khoảng 1 clock báo sẵn sàng.
158
Datapath của UID

159
Controller của UID

160
UID – Mã Verilog của controller

161
UID – Mã Verilog của datapath

162
UID – Thiết kế hoàn tất

163

También podría gustarte