Shift register là thành phần quan trọng trong thiết kế VHDL, được sử dụng để lưu trữ và dịch chuyển dữ liệu. Việc viết code VHDL cho shift register hiệu quả sẽ giúp tối ưu hóa tài nguyên FPGA và cải thiện hiệu năng hệ thống. Bài viết này sẽ hướng dẫn bạn cách viết Shift Register Vhdl Code
hiệu quả, tận dụng các đặc điểm của FPGA để giảm thiểu tài nguyên sử dụng.
Các phương pháp triển khai Shift Register trong VHDL
Có nhiều cách để viết code VHDL cho shift register, nhưng không phải cách nào cũng tối ưu. Hiểu rõ kiến trúc FPGA và lựa chọn phương pháp phù hợp sẽ giúp giảm thiểu đáng kể tài nguyên tiêu thụ. Trước khi đi vào chi tiết, bạn nên nắm vững kiến thức cơ bản về std_logic_vector
trong VHDL.
Bài viết này sẽ tập trung vào shift register, mặc dù có những cấu trúc dữ liệu khác sử dụng ít tài nguyên hơn cho FIFO lớn.
Shift Register 1-bit với độ sâu tùy chỉnh
Đầu tiên, hãy xem xét các phương pháp tạo shift register 1-bit. Đầu vào và đầu ra là một bit đơn, giá trị std_logic
. Độ sâu (số bit lưu trữ) được cấu hình thông qua hằng số generic.
Khai báo entity cho tất cả các ví dụ về shift register 1-bit như sau:
entity shift_reg_1_width is
generic ( sr_depth : integer );
port (
clk : in std_logic;
rst : in std_logic; -- Optional
enable : in std_logic; -- Optional
sr_in : in std_logic;
sr_out : out std_logic
);
end;
ilinx FDCE-flip-flop
Hình 1: Xilinx FDCE flip-flop primitive
Sử dụng Vector Slicing
Cách đơn giản nhất là sử dụng vector slicing. Chèn phần tử mới vào một đầu của vector và đồng thời dịch chuyển các phần tử khác về phía đầu ra. Lấy bit cuối cùng trong vector làm đầu ra.
architecture slicing of shift_reg_1_width is
signal sr : std_logic_vector(sr_depth - 2 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
sr <= sr_in & sr(sr'high downto sr'low + 1);
sr_out <= sr(sr'low);
end if;
end process;
end architecture;
Sử dụng Vòng lặp For
Tương tự vector slicing, vòng lặp for cũng hoạt động trong tất cả các phiên bản VHDL. Cách này cần thêm một dòng code để gán đầu vào cho vector.
architecture for_loop of shift_reg_1_width is
signal sr : std_logic_vector(sr_depth - 2 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
sr(sr'low) <= sr_in;
for i in sr'high downto sr'low + 1 loop
sr(i) <= sr(i - 1);
end loop;
sr_out <= sr(sr'low);
end if;
end process;
end architecture;
Sử dụng hàm shift_left
Hàm shift_left
chỉ hoạt động với vector bit và yêu cầu vector unsigned làm tham số đầu tiên.
architecture ieee_shift_left of shift_reg_1_width is
signal sr : unsigned(sr_depth - 2 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
sr <= shift_left(sr, 1);
sr(sr'high) <= to_unsigned(sr_in,1);
sr_out <= to_std_logic(sr(0));
end if;
end process;
end architecture;
Đầu vào Enable
Hầu hết FPGA đều có flip-flop với đầu vào enable (E) hoặc clock enable (CE). Thêm đầu vào enable
sẽ không tiêu tốn thêm tài nguyên.
architecture with_enable of shift_reg_1_width is
signal sr : unsigned(sr_depth - 2 downto 0);
begin
process(clk)
begin
if rising_edge(clk) then
if enable = '1' then
sr <= shift_left(sr, 1);
sr(sr'high) <= to_unsigned(sr_in,1);
end if;
sr_out <= to_std_logic(sr(0));
end if;
end process;
end architecture;
Hạn chế của việc đặt giá trị Reset
Thêm giá trị reset cho vector hoặc đầu ra shift register sẽ ngăn công cụ tổng hợp đóng gói shift register vào LUT hoặc BRAM, dẫn đến việc sử dụng nhiều FF hơn.
Shift Register với độ sâu và độ rộng tùy chỉnh
Entity cho shift register với độ rộng và độ sâu dữ liệu có thể cấu hình:
entity shift_reg_generic_width is
generic (
sr_depth : integer;
sr_width : integer
);
port (
clk : in std_logic;
rst : in std_logic; -- Optional
sr_in : in std_logic_vector(sr_width - 1 downto 0);
sr_out : out std_logic_vector(sr_width - 1 downto 0)
);
end;
Không có Reset
Ví dụ về shift register vhdl code
với độ rộng và độ sâu tùy chỉnh, không có reset:
architecture slicing of shift_reg_generic_width is
type sr_type is array (sr_depth - 2 downto 0) of std_logic_vector(sr_width - 1 downto 0);
signal sr : sr_type;
begin
process(clk)
begin
if rising_edge(clk) then
sr <= sr_in & sr(sr'high downto sr'low + 1);
sr_out <= sr(sr'low);
end if;
end process;
end architecture;
Với bộ đếm Reset thông minh
Sử dụng bộ đếm reset để tránh việc reset toàn bộ shift register:
architecture counter_rst of shift_reg_generic_width is
type sr_type is array (sr_depth - 2 downto 0) of std_logic_vector(sr_width - 1 downto 0);
signal sr : sr_type;
signal rst_counter : integer range 0 to sr_depth - 1;
begin
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
rst_counter <= 0;
sr_out <= (others => '0');
else
if rst_counter < sr_depth -1 then
rst_counter <= rst_counter + 1;
end if;
sr <= sr_in & sr(sr'high downto sr'low + 1);
sr_out <= sr(sr'low);
end if;
end if;
end process;
end architecture counter_rst;
Kết luận
Viết code VHDL cho shift register hiệu quả đòi hỏi sự hiểu biết về kiến trúc FPGA và lựa chọn phương pháp triển khai phù hợp. Bằng cách áp dụng các kỹ thuật được đề cập trong bài viết này, bạn có thể tối ưu hóa việc sử dụng tài nguyên và nâng cao hiệu năng của thiết kế. Đối với FIFO lớn, nên cân nhắc sử dụng cấu trúc dữ liệu khác như ring buffer.