You are on page 1of 5

Để thiết kế mạch fifo bằng verilog code, bạn có thể làm theo các bước sau:

B1: Xác định các tính năng của mạch fifo

Trong mạch fifo, chúng ta cần định nghĩa các tính năng sau:

 Dung lượng fifo: số lượng phần tử tối đa mà fifo có thể chứa


 Tốc độ đọc và ghi: tốc độ tối đa của quá trình ghi và đọc dữ liệu từ fifo
 Các tín hiệu điều khiển: các tín hiệu để điều khiển quá trình ghi và đọc dữ liệu

B2: Thiết kế các module fifo

- Sau khi xác định các tính năng của mạch fifo, chúng ta cần thiết kế các module để thực hiện các
tính năng này. Trong ví dụ này, chúng ta sẽ thiết kế 2 module là FIFO_writer và FIFO_reader.
- Module FIFO_writer sẽ được sử dụng để ghi dữ liệu vào FIFO, và module FIFO_reader sẽ được
sử dụng để đọc dữ liệu từ FIFO. Các module này sẽ được kết nối với nhau để tạo thành một
mạch FIFO hoàn chỉnh

B3: Viết mã verilog cho các module FIFO

- Sau khi thiết kế các module, chúng ta cần viết mã verilog cho từng module này
- Đây là ví dụ về verilog cho module FIFO_writer:

module FIFO_writer (

input clk,

input reset,

input write_enable,

input [7:0] data_in,

output full

);

reg [7:0] fifo ;

reg write_pointer = 0;

reg read_pointer = 0;

wire empty = (write_pointer == read_pointer);

wire almost_full = (write_pointer == read_pointer + 1) || (write_pointer == 0 && read_pointer == 255);

always @(posedge clk) begin

if (reset) begin

write_pointer <= 0;

read_pointer <= 0;
fifo <= 8'h00;

end

else if (write_enable && !full) begin

fifo[write_pointer] <= data_in;

write_pointer <= write_pointer + 1;

end

end

assign full = (almost_full && write_enable);

endmodule

- Trong module FIFO_writer này, chúng ta sử dụng một mảng reg để lưu trữ dữ liệu trong FIFO.
Chúng ta sử dụng hai con trỏ để theo dõi vị trí của dữ liệu trong FIFO.
- Trong mỗi chu kì xung clock, chúng ta kiểm tra nếu tín hiệu reset được kích hoạt, thì chúng ta đặt
con trỏ ghi và đọc về giá trị 0 và xóa toàn bộ dữ liệu trong FIFO. Nếu tín hiệu ghi được kích hoạt
và FIFO chưa đầy, chúng ta sẽ lưu trữ dữ liệu mới vào vị trí hiện tại của con trỏ ghi và tăng giá trị
của con trỏ ghi lên 1.
- Chúng ta cũng tính toán giá trị của tính hiệu full bằng cách kiểm tra xem FIFO có gần đầy hay
không. Nếu FIFO gần đầy và tín hiệu ghi được kích hoạt, thì chúng ta xác định rằng FIFO đã đầy
- Đây là ví dụ về FIFO_reader:

module FIFO_reader (

input clk,

input reset,

input read_enable,

output [7:0] data_out,

output empty

);

reg [7:0] fifo ;

reg write_pointer = 0;

reg read_pointer = 0;

wire full = (write_pointer == read_pointer + 1) || (write_pointer == 0 && read_pointer == 255);

wire almost_empty = (write_pointer == read_pointer);

wire [7:0] data = fifo[read_pointer];


always @(posedge clk) begin

if (reset) begin

write_pointer <= 0;

read_pointer <= 0;

fifo <= 8'h00;

end

else if (read_enable && !empty) begin

read_pointer <= read_pointer + 1;

end

end

assign empty = (almost_empty && !read_enable);

assign data_out = data;

endmodule

- Trong module FIFO_reader, chúng ta sử dụng một mảng reg để lưu dữ liệu trong FIFO. Chúng ta
sử dụng hai con trỏ để theo dõi vị trí của dữ liệu trong FIFO.
- Trong mỗi chu kỳ xung clock, chúng ta kiểm tra nếu tín hiệu reset được kích hoạt, thì chúng ta
đặt lại con trỏ ghi và đọc về giá trị 0 và xóa toàn bộ dữ liệu trong FIFO. Nếu tín hiệu đọc được
kích hoạt và FIFO không rỗng, chúng ta sẽ tăng giá trị của con trỏ đọc lên 1.
- Chúng ta cũng tính toán giá trị của tín hiệu empty bằng cách kiểm tra xem FIFO có gần rỗng hay
không. Nếu FIFO gần rỗng và tín hiệu đọc được kích hoạt, thì chúng ta xác định rằng FIFO đã
rỗng. chúng ta sử dụng tín hiệu almost_empty để kiểm tra trường hợp đặc biệt khi con trỏ ghi và
con trỏ đọc cùng trỏ đến vị trí cuối cùng của FIFO

B4: Kết nối dây để kết nối các tín hiệu giữa các module.

module FIFO (

input clk,

input reset,

input read_enable,

input write_enable,

input [7:0] data_in,


output [7:0] data_out,

output full,

output empty

);

wire [7:0] data_out_internal;

wire full_internal;

wire empty_internal;

FIFO_writer writer (

.clk(clk),

.reset(reset),

.write_enable(write_enable),

.data_in(data_in),

.full(full_internal)

);

FIFO_reader reader (

.clk(clk),

.reset(reset),

.read_enable(read_enable),

.data_out(data_out_internal),

.empty(empty_internal)

);

assign data_out = data_out_internal;

assign full = full_internal;

assign empty = empty_internal;


endmodule

- Trong module FIFO, chúng ta sử dụng các module FIFO_writer và FIFO_reader để thực hiện các
chức năng đọc/ghi dữ liệu. Chúng ta sử dụng kết nối dây để kết nối các tín hiệu giữa các module.
Chúng ta sử dụng tín hiệu full_internal và empty_internal để lưu trữ giá trị của các tín hiệu full
và empty được tính toán bởi các module FIFO_writer và FIFO_reader.
- Chúng ta sử dụng các assign statements để kết nối các tín hiệu data_out, full và empty từ các
module con tới module FIFO. Cuối cùng, chúng ta có thể sử dụng module FIFO trong các mạch số
học phức tạp để lưu trữ và truyền tải các dữ liệu giữa các module khác nhau
- Đó là cách chúng ta có thể thiết kế một mạch FIFO bằng mã verilog. Mạch FIFO là một phần quan
trọng của nhiều ứng dụng kĩ thuật số và là một phần quan trong của hệ thống lưu trữ dữ liệu.
Việc hiểu cách thiết kế mạch FIFO có thể giúp chúng ta hiểu rõ hơn về các khái niệm cơ bản của
kĩ thuật số và phát triển các ứng dụng phức tạp hơn trong tương lai.

You might also like