Tải bản đầy đủ (.docx) (35 trang)

BÁO CÁO VỀ ĐỊNH THÌ FLIP-FLOP

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (744.63 KB, 35 trang )

BÁO CÁO TUẦN 4
ĐỊNH THÌ FLIP-FLOP
Setup and Hold time
Là khoảng thời gian mà tín hiệu đầu vào của Flip-Flop không được thay đổi.
Vì khi tín hiệu của Flip-Flop thay đổi từ 10 hay từ 01 thì trong lúc thay đổi sẽ đi
qua vùng không xác định giữa 1 và 0. Nếu đúng lúc này xuất hiện cạnh xung
“Clock” thì đầu vào được “bắt” là không xác định. Lúc này ngõ ra Flip-Flop rơi
vào trạng thái không xác định (gọi là metastable).
Nguyên nhân dẫn đến vi phạm setup và hold time là do tín hiệu ngõ vào trên
đường truyền bị suy hao và rơi vào vùng không xác định là mức 0 hay mức 1. 
không phải là nguyên nhân chính yếu ???
Setup time : là khoảng thời gian cần thiết mà tín hiệu đầu vào ổn định trước
khi xuất hiện xung “Clock”.
Hold time : là thời gian cần thiết mà tín hiệu đầu vào vẫn không đổi sau khi
có xung “Clock”.

Metastable : Nếu vị phạm setup time và hold time thì trạng thái metastable
xảy ra. Ngõ ra của Flip-Flop trong trạng thái không xác định ( không biết là mức 0
hay mức 1), nhưng trạng thái này chỉ xuất hiện một thời gian và sau đó sẽ đạt mức
ổn định. Có nghĩa là sau một thời gian “undefined” thì sẽ “settles-down” về 0 hay
1. Và yếu tố về 0 hay về 1 là ngẫu nhiên và không biết trước được. Và thời gian
xảy ra “metastable” kéo dài bao lâu là do công nghệ của nhà sản xuất ra Flip-Flop.


Như vậy, để tránh trường hợp này xảy ra khi thiết kế mạch số ta cần phải lưu
ý đến vấn đề thời gian (định thời ???). Ta xét ví dụ sau:
 Vi phạm Setup Time:

Tc: chu kì xung clock.
tpcq: thời gian từ khi xung clock đưa tín hiệu ngõ vào đến ngõ ra.
tpd : thời gian tính toán mạch combination logic.


tskew: thời gian tín hiệu clock nằm trong vùng không xác định khi chuyển từ 0
lên 1.
Như vậy, nếu không muốn vi phạm setup time thì ta phải tính toán thời gian
tpcq sao cho sau khi ổn định không rơi vào vùng tsetup.


 Vi phạm Hold time :

Phương pháp tránh “Metastable”:
 Ghép bộ đệm/ cổng inverter
Như đã đề cập ở trên, biên độ tín hiệu bị suy giảm trên đường truyền dẫn đến
tình trạng rơi vào trạng thái không xác định (nằm giữa mức 0 và 1). Phương pháp
dùng bộ đệm hoặc 2 cổng đảo để phục hồi suy hao điện áp cho tín hiệu trên đường
truyền.


 Ghép nối tiếp hai Flip-Flop với nhau :
Dựa vào đặc tính của metastable là ngõ ra Q sẽ không ổn định. Sau một thời
gian thì trạng thái metastable sẽ mất và lúc này ngõ ra Q sẽ giữ ổn định ở mức 0
hay mức 1. Do đó, đối với Flip-Flop thứ hai thì ngõ vào gần như là ổn định.

o Nếu trong trường hợp xấu nhất xảy ra. Có nghĩa là delay của Clock từ
FF1 đến FF2 bằng với delay để chuyển tín hiệu không xác định từ ngõ
vào FF1 đến ngõ ra FF1 thì FF2 cũng bắt được tín hiệu không xác
định.
o Như vậy, ghép thêm 1 Flip-Flop nối tiếp nữa là sẽ an toàn hơn khi sử
dụng phương pháp này
 Điều chỉnh vị trí thanh ghi hoặc chèn clock gate:
Việc sử dụng điều chỉnh vị trí thanh ghi hoặc chèn clock gate cũng có thể tránh
được những vi phạm về setup time và hold time nhưng một số vi phạm về các vấn



đề timing khác sẽ xảy ra như (không đồng bộ được đường Clock của tất cả các
Flip-Flop) nên không khuyến dụng cách này.
MÃ GRAY
Đối với các chuỗi số tăng tuần tự, việc chuyển giữa các trạng thái trong hệ
đếm nhị phân có thể làm thay đổi nhiều bit từ 0 sang 1 và ngược lại. Ví dụ, có 3 bit
thay đổi khi chuyển từ 0011 đến 0100. Trong các hệ thống thực tế, không có cách
nào đảm bảo rằng 3 bit này sẽ chuyển đổi cùng lúc với nhau, vì vậy hệ thống có thể
đi qua một số trạng thái tạm thời không ổn định trước khi chuyển đến giá trị cuối
cùng. Để tránh vấn đề này người ta dùng mã Gray, trong hệ thống mã này việc
chuyển giữa các giá trị lân cận nhau sẽ chỉ thay đổi giá trị của 1 bit duy nhất.
Dựa vào đặc tính như vậy, mã Gray được sử dụng rất hiệu quả để rút gọn
hàm logic tới mức tối giản hoặc dùng để tối thiểu hóa sai số.
Sơ đồ khối chuyển đổi mã Gray :

Ta xét ví dụ sau :
module GrayConverter ( bin,gray );
input [3:0] bin;
output [3:0] gray;
integer i;
for(i=0; i<=2; i=i+1);
begin
assign gray[i] = bin[i] ^ bin[i+1];
end
assign gray[3] = bin[3] ^ 1'b0;
endmodule


GRAY COUNTER

module GrayCounter ( ClockG, Clear, Q, QN );
parameter NBITS = 3;
input ClockG, Clear;
output [1:NBITS] Q,QN;
reg [1:NBITS] Counter, GrayCount;
integer K;
always @(posedge ClockG)
if (Clear)
Counter <= 0;
else
Counter <= Counter +1;
always @(Counter)
begin
GrayCount[1] = Counter[1];
for (K=2; K<= NBITS; K = K+1)
GrayCount[K] = Counter[K-1] ^ Counter[K];
end
assign Q = GrayCount;
assign QN = ~GrayCount;
endmodule
Giải thích :
RTL trên có chức năng đếm mã nhị phân sau đó chuyển thành mã Gray. Tín
hiệu “Clear” tích cực ban đầu để thiết lập giá trị “Counter” ban đầu.


 Cú pháp khai báo parameter :
parameter <signed> <range> name_1 = const_1
 signed : từ khóa cho biết parameter được khai báo kiểu có dấu hay không
dấu.
 range : dùng để khai báo độ rộng của parameter.

 name_1 : tên của parameter cần khai báo.
 const_1 : là giá trị của các parameter.
Ví dụ :

parameter [3:0] PARAM1 = 1;
parameter [3:0] PARAM2 = 4'b0010;
parameter [3:0] PARAM3 = 4'h3;

Các giá trị của parameter có thể là các số khác nhau hoặc là lấy giá trị từ một
define đã định trước, kết quả trả về từ một hàm, một phép tính…
Ví dụ:

`define DATA_WIDTH 32
parameter DWIDTH = `DATA_WIDTH;

 Các trường hợp sử dụng parameter :
Đối với các thiết kế cấu hình được và có khả năng sử dụng nhiều lần, người ta sử
dụng parameter trong việc khai báo các thông số cấu hình cho thiết kế đó. Chỉ cần
thay đổi giá trị của các parameter, ta sẽ có một thiết kế tương ứng với thông số vừa
cấu hình.


Ví dụ :
module AddWithCarryInCarryOut
(A,B,CarryIn,CarryOut,Sum);
parameter N=3;
input [N:1] A,B;
input CarryIn;
output CarryOut;
output [N:1] Sum;

assign {CarryOut,Sum} = A+B+CarryIn;
endmodule
Như vậy, nếu ta muốn có một bộ cộng với độ rộng dữ liệu là 4-bit thì chỉ cần thay
đổi giá trị N = 4 mà thôi.
 Cách thay đổi giá trị của parameter :
o Sử dụng defparam :
Ví dụ :
module two_registers (...);
parameter SIZE = 16;
input [SIZE-1:0] d;
output [SIZE-1:0] q;
defparam reg1.SIZE = 16;
register reg1 (.....)
defparam reg2.SIZE = 16;
register reg2 (.....)
....
defparam reg2.SIZE = 4;// xảy ra lỗi
Như vậy, ta có thể sử dụng defparam để thay đổi giá trị parameter “SIZE”
trong module con là “register”. Đây cũng là lợi điểm khi sử dụng defparam là nó
cho phép thay đổi giá trị của parameter của bất kì module nào có cấp độ thấp hơn
mà không cần phải ở cấp liền kề.
Nhưng một khuyết điểm xảy ra khi thực hiện việc gọi defparam là : nếu
một thiết kế lớn với số lượng dòng code lớn thì việc dùng defparam để thay đổi


giá trị parameter các module con là khó kiểm soát. Vì thay đổi nhiều lần module
con cùng lúc làm cho chức năng sai lệch đi.
o Truyền trực tiếp giá trị cho parameter :
Ví dụ :
//top module

module top_module (....);
...
sub_module # (8,16) sub_module_inst(....);
//sub module
module sub_module(..);
parameter PORT_NUM = 4;
parameter PORT_WIDTH = 8;
...
endmodule
Như vậy, giá trị “PORT_NUM” và “PORT_WIDTH” đã được thay đổi khi
gọi trong module top theo thứ tự là 8 và 16. Để thấy rõ ràng hơn thì ta nên thay đổi
parameter của module con theo tên gọi. Cách này giúp dòng code được tường minh
hơn.
//top module
module top_module (....);
...
sub_module # (.PORT_NUM(8),.PORT_WIDTH(16))
sub_module_inst(....);
CASE, CASEZ, CASEX
Cả ba loại của phát biểu trên đều có cú pháp hoàn toàn giống nhau, chỉ có
một điểm khác biệt duy nhất là từ khóa case, casex, casez.  chỉ khác nhau từ khóa
???
 Cách sử dụng phát biểu case, casex và casez
Ta có thể sử dụng giá trị don’t care trong các phát biểu case. Trong case, giá trị
x và z (hay ?) thì không được xem là don’t care mà chúng được xem là giá trị
không xác định.


Ví dụ :


always @(*)
begin
case (sel[2:0])
3'b001 : dout = din1;
3'b010 : dout = din2;
3'b1?? : dout = din3;
default dout = din4;
endcase
end

Trong ví dụ này, khi biến “sel” có giá trị là 2’b100 thì nhánh default sẽ được
thực thi. Vì trong case không hiểu ? là don’t care.
Nhưng trong casez thì dòng code trên thực thi đúng vì trong casez ? được
hiểu là don’t care. Ta xét ví dụ sau :
always @(*)
begin
casez (sel[2:0])
3'b001 : dout = din1;
3'b010 : dout = din2;
3'b1xx : dout = din4;
default dout = din1;
endcase
end
Lúc này, khi ngõ vào “sel” có giá trị là 3’b101 thì nhánh default được thực
thi. Vì trong casez giá trị x không được hiểu là don’t care.
Như vậy, ta rút ra kết luận sau :
 Case : chỉ hiểu giá trị xác định không dùng don’t care.
 Casez : hiểu giá trị z và ? là don’t care.
 Casex : hiểu giá trị x, z, ? là don’t care.
Ví dụ : Sử dụng casex

module Dungcase ( sel, din1,din2,din3,dout);
input din1,din2,din3;
input [1:0] sel;
output dout;


reg dout;
always @(*)
begin
casex (sel[1:0])
2'b00 : dout
2'b01 : dout
2'b1x : dout
default dout
endcase
end
endmodule
Sel[1:0]
00
01
10
11
0x
0z
x0
z0
1x
1z
x1
z1

xx
zz

Kết quả
Din1
Din2
Din3
Din3
Din1
Din1
Din1
Din1
Din3
Din3
Din2
Din2
Din1
Din1

=
=
=
=

din1;
din2;
din3;
0;



Ví dụ : Sử dụng casez
module Dungcase ( sel, din1,din2,din3,dout);
input din1,din2,din3;
input [1:0] sel;
output dout;
reg dout;
always @(*)
begin
casez (sel[1:0])
2'b00 : dout = din1;
2'b01 : dout = din2;
2'b1z : dout = din3;
default dout = 0;
endcase
end
endmodule
Sel[1:0]
00
01
10
11
0x
0z
x0
z0
1x
1z
x1
z1
xx

zz

Kết quả
Din1
Din2
Din3
Din3
0
Din1
0
Din1
Din3
Din3
0
Din2
0
Din1

MÃ HÓA MÁY TRẠNG THÁI
Việc lựa chọn mã hóa trạng thái khác nhau sẽ cho mạch tổng hợp có tài
nguyên và tốc độ khác nhau. Nhiều loại mã có thể sử dụng để mã hóa trạng thái
như one-hot, binary tuần tự, gray….


 One-hot Encoding :
Mỗi bit trong thanh ghi trang thái sẽ quy định một trạng thái. Chỉ có 1 bit là 1
còn tất cả các bit khác đều mang giá trị 0. Mã hóa One-Hot trong máy biến trạng
thái là một kiểu mã hóa tốt. Vì thế mã hóa kiểu One-Hot yêu cầu một số lượng lớn
Flip-Flop, nó cung cấp một phương pháp đơn giản và dễ sử dụng tạo ra việc tối ưu
hóa trong thiết kế máy trạng thái.

Mã hóa One-hot là kiểu mã hóa có tốc độ cao nhất, và tốc độ này không phụ
thuộc vào số lượng trạng thái mà chỉ phụ thuộc vào việc chuyển đổi giữa các trạng
thái.
Trong mã hóa kiểu One-Hot thì sẽ làm tăng tối đa số Flip-Flop (mỗi trạng thái
là một Flip-Flop) và làm giảm tối thiểu số cổng logic (làm nhỏ mạch Combination
Logic).
Kết quả là khi sử dụng mã hóa One-Hot có thể tối ưu hóa về mặc sử dụng diện
tích do các cổng logic được tối giản, do đó có thể tiêu thụ ít điện năng lượng hơn.
 Mã hóa nhị phân Binary :
Trong mã hóa máy biến trạng thái bằng mã nhị phân thì ta có quan hệ giữa các
biến trạng thái và số lượng trạng thái qua công thức sau:
q = log2(n)
q : số bit của biến trạng thái.
n : số trạng thái
Ví dụ muốn biểu diễn máy trạng thái có 4 trạng thái thì ta chỉ cần khai báo biến q
là một vecto có độ rộng là 2-bit.
Với công thức được đưa ra như trên thì người ta có thể dễ dàng xác định
được độ rộng tối thiểu của các biến trạng thái cần dùng. Như vậy số lượng các
Flip-Flop được sử dụng là tương đương với độ rộng của biến trạng thái.
Mã hóa nhị phân sử dụng ít FlipFlop hơn mã hóa One-Hot. Thực chất cho
thấy rằng chỉ cần 7 Flip-Flop có thể mã hóa 100 trạng thái trong khi đó mã OneHot muốn mã hóa 100 trạng thái cần phải dùng tới 100 Flip-Flops.


Như vậy, khi sử dụng tối thiểu số lượng Flip-Flop thì làm cho mạch tổ hợp
(Combination Logic) lớn lên bởi vì cần các mạch logic để giải mã các trạng thái.
Phương pháp này thích hợp hơn cho việc sử dụng thiết kế các máy trạng thái ít hơn
8 trạng thái.
Một nhược điểm của mã hóa nhị phân là khi chuyển trạng thái thì có thể có
nhiều hơn 1-bit thay đổi và nó yêu cầu một mạch tổ hợp phức tạp để xác định các
trạng thái hiện tại. Dẫn đến tình trạng là tiêu tốn năng lượng nhiều hơn.

 Gray Code Encoding :
Là kiểu mã hóa mà mỗi trạng thái kề cận nhau chỉ có 1-bit thay đổi mà thôi.
Nói cách khác là chỉ có giá trị của một Flip-Flop thay đổi lúc mà các trạng thái
thay đổi liên tục.
Số flip-flop được xác định như sau:
Số biến trạng thái = số Flip-Flop = log2(số trạng thái)
Có nghĩa là 3-bit mã gray biểu hiện được 8 trang thái và số FF là 3.
Mã hóa sử dụng mã Gray là để giảm tiêu tốn về năng lượng khi các trạng
thái chuyển đổi nhiều và liên tục và trong trường hợp lý tưởng nghĩa là các trạng
thái chuyển đổi theo một thứ tự kề cận nhau (S1->S2->S3->S4…) thì việc sử dụng
kiểu mã hóa này là tối ưu và giảm thiểu năng lượng hoạt động của hệ thống một
cách tối đa.  tối ưu theo khía cạnh nào???
Cũng có thể cải thiện hơn nữa để làm giảm diện tích của các mạch tổ hợp
(Combination Logic) từ đó tạo nên một lợi ích về năng lượng tiêu thụ.


CHƯƠNG 3 : MODELING EXAMPLES
3.11. MODELING DECODER
3.11.1. A SIMPLE DECODER
module SimpleDecoder(A, B, Enable, DecodeOut);
input A,B,Enable;
output [0:3] DecodeOut;
wire Abar, Bbar;
assign Abar = ~A;
assign Bbar = ~B;
assign DecodeOut[0]
assign DecodeOut[1]
assign DecodeOut[2]
assign DecodeOut[3]
endmodule


=
=
=
=

~(
~(
~(
~(

Enable&Abar&Bbar);
Enable&Abar&B );
Enable&A&Bbar);
Enable&A&B);

Giải thích : RTL trên mô tả mạch giãi mã 2 sang 4, có một chân “Enable” tích cực
mức cao và ngõ ra tích cực mức thấp. Ta xem bảng trạng thái sau :
Enabl
e
0
1
1
1
1

A
X
0
0

1
1

B Decoder
0
X 1
0 0
1 1
0 1
1 1

Decoder
1
1
1
0
1
1

Decoder
2
1
1
1
0
1

Decoder
3
1

1
1
1
0


Giải thích dạng sóng:
 Khi tín hiệu cho phép “Enable” =0 thì bất chấp ngõ vào A,B là giá trị nào thì
ngõ ra “DecoderOut” vẫn mang giá trị là 4’b1111.
 Khi tín hiệu cho phép tích cực mức 1 thì quá trình giải mã được cho phép.
Do tín hiệu ngõ ra tích cực mức thấp nên mỗi thời điểm trong 4 trạng thái
của “DecoderOut” chỉ có 1 bit 0 xuất hiện mà thôi.

3.11.2. BINARY DECODER
module BinaryDecoder(SelectAddress, DecodeOut);
parameter SBITS = 2;
parameter OUT_BITS = 4;
input [SBITS-1:0] SelectAddress;
output [OUT_BITS-1:0] DecodeOut;
reg [OUT_BITS-1:0] DecodeOut;
integer k;
always @(SelectAddress)
for(k= OUT_BITS-1;k>=0;k=k-1)
DecodeOut[k] = (k == SelectAddress)?'b1:'b0;
endmodule
Giải thích :
RTL trên mô tả mạch giải mã nhị phân với 2 ngõ vào và 4 ngõ ra, sử dụng
khai báo thông số parameter để khai báo độ rộng các bit ngõ vào và ngõ ra.



Do ngõ ra tích cực mức cao và không có tín hiệu cho phép “Enable” nên tại
mỗi thời điểm lựa chọn địa chỉ “SelectAddress” thì chỉ có một bit ngõ ra tích cực
mức cao. Ta xem xét bảng trạng thái của bộ giải mã:

SelectAddress[1
]
0
0
1
1

SelectAddress[0
]
0
1
0
1

3.11.3. JOHNSON DECODER

Decoder
3
0
0
0
1

Decoder
2
0

0
1
0

Decoder
1
0
1
0
0

Decoder
0
1
0
0
0


3.12. MODELING A MULTIPLEXER
3.12.1. A SIMPLE MULTIPLEXER
module SimpleMultiplexer(DataIn, SelectAddress,
MuxOut);
input [0:3] DataIn;
input [0:1] SelectAddress;
output MuxOut;
assign MuxOut = DataIn[SelectAddress];
endmodule

Giải thích :

RTL mô tả mạch ghép kênh 4 sang 1 sử dụng phép gán liên tục (Continuous
Assignment). Với tín hiệu lựa chọn kênh “SelectAddress”. Ta có 4 kênh ngõ vào là
“DataIn” và 1 kênh ngõ ra “MuxOut” .
Tai một thời điểm thì chỉ có dữ liệu của 1 kênh ngõ vào được chọn và đưa
đến ngõ ra.


3.12.2. A PARAMETERIZED MULTIPLEXER
module BinaryMultiplexer(DataBus, Select, Enable, Y,
Ybar);
parameter NBITS=2, WORDS=2;
input [NBITS*WORDS-1:0] DataBus;
input [WORDS-1:0] Select;
input Enable;
output [NBITS-1:0] Y,Ybar;
reg [NBITS-1:0] Y,Ybar;
integer k;
function [WORDS-1:0] GetWordIndex;
//Get the first index that has value 1.
input [WORDS-1:0] DecodedSelect;
integer Inx;
begin
GetWordIndex=0;
for(Inx=WORDS-1;Inx>=0;Inx=Inx-1)
if(DecodedSelect[Inx] == 'b1)
GetWordIndex = Inx;
end
endfunction



always @( DataBus or Select or Enable)
if(Enable=='b1)
begin
for(k=0;kY[k]=DataBus[GetWordIndex(Select)*NBITS+k];
Ybar=~Y;
end
else if (Enable=='b0)
begin
Y='bz;
Ybar='bz;
end
else
begin
Y='bx;
Ybar='bx;
end
endmodule
Giải thích:
RTL trên có chức năng chọn kênh, dữ liệu được chọn là “DataBus”. Khi tín
hiệu chọn lựa “Select” có giá trị là 00,01,11 thì tín hiệu “DataBus[1:0]” được đưa
đến ngõ ra “Y”. Khi “Select” là 10 thì “DataBus[2:3]” được đưa đến ngõ ra “Y”.

Giải thích dạng sóng :


Ta thấy rằng chỉ có thời điểm “Select” mang giá trị là 2’b10 thì
“DataBus[2:3]” mới được đưa đến ngõ ra “Y”. Tất cả các lựa chọn còn lại thì ngõ
ra đều là “DataBus[1:0]”. Ta xem sơ đồ khối sau :


3.13. MODELING A PARAMETERIZED PARITY GENERATOR
module ParityGenerator (DataIn, OddPar, EvenPar);
parameter N=4;
input [N-1:0] DataIn;
output OddPar, EvenPar;
assign EvenPar= ^DataIn;
assign OddPar=~EvenPar;
endmodule
Giải thích:


RTL trên có chức năng tạo ra bit Parity. Nếu sử dụng phương pháp kiểm tra
chẵn thì sử dụng tín hiệu “EvenPar” làm bit kiểm tra. Ngược lại, với phương pháp
kiểm tra lẻ ta sử dụng tín hiệu “OddPar” làm bit kiểm tra chẵn.

Giải thích dạng sóng :
Bằng cách kiểm tra số bit 1 của dữ liệu ngõ vào. Khi “DataIn” có số bit 1 lẻ
thì biến “EvenPar”=1. Khi “DataIn” có số bit 1 là chẵn thì tín hiệu “EvenPar” là 0.

3.14. MODELING A THREE-STATE GATE
module ThreeStateGates (ReadState, CpuBus, MainBus);
input ReadState;
input [3:0] CpuBus;
output [3:0] MainBus;
reg [3:0] MainBus;
always @(ReadState, CpuBus)
if (ReadState) MainBus = 4'bz;
else MainBus = CpuBus;
endmodule



Giải thích :
RTL trên mô tả chức năng của cổng 3 trạng thái, với tín hiệu điều khiển
“ReadState”. Khi tín hiệu “ReadState” tích cực mức cao thì ngõ ra “MainBus” bị
cách ly với ngõ vào nên ở trạng thái tổng trở cao.
Khi “ReadState” tích cực mức thấp thì ngõ vào “CpuBus” được đưa đến ngõ
ra “MainBus”.

3.15. A COUNT THREE 1’S MODEL
module Count3Ones (Data, Clock, Reset, SeqFound);
input Data, Clock, Reset;
output SeqFound;
reg SeqFound;
parameter PATTERN_SEARCHED_FOR = 3'b111;
reg [2:0] Previous;
always @(posedge Clock)
if (Reset) begin


Previous <= 3'b000;
SeqFound <= 1'b0;
end
else begin
Previous <= {Previous[1:0],Data};
SeqFound <=
(Previous==PATTERN_SEARCHED_FOR);
end
endmodule
Giải thích :
RTL trên có chức năng đếm ba bit 1 liên tiếp nhau. Khi dữ liệu vào “Data” là

ba bit 1 liền kề nhau thì ngõ ra “SeqFound” sẽ có giá trị là 1. Ngược lại, toàn bộ
giá trị ngõ ra “SeqFound” mang giá trị 0.
Ta thấy rằng, do việc gán tín hiệu ngõ ra “SeqFound” dưới tác động của
cạnh xuống xung “Clock” nên Flip-Flop đã được tạo ra cho biến này. Dẫn đến sự
bất lợi là khi đã có liên tiếp ba bit 1 xuất hiện mà ngõ ra vẫn chưa tích cực mà phải
đợi đến cạnh xuống “Clock” tiếp theo. Ta xét thêm ví dụ sau.

module Count3Ones (Data, Clock, Reset, SeqFound);
input Data, Clock, Reset;


output SeqFound;
wire SeqFound;
parameter PATTERN_SEARCHED_FOR = 3'b111;
reg [2:0] Previous;
always @(posedge Clock)
if (Reset) begin
Previous <= 3'b000;
end
else
Previous <= {Previous[1:0],Data};
assign SeqFound = (Previous == PATTERN_SEARCHED_FOR);
endmodule

Giải thích:
Trong ví dụ đưa ra sau đây, ngõ ra “SeqFound” do không được gán dưới tác
động của cạnh xuống “Clock” nên ngõ ra không tạo Flip-Flop cho biến
“SeqFound”. Lúc này khi ngõ vào “Data” là ba bit 1 liên tiếp nhau thì ngõ ra
“SeqFound” lập tức tích cực mức 1 liền mà không cần đợi đến cạnh xuống “Clock”
tiếp theo.


3.16. A FACTORIAL MODEL


×