ilinx FDCE-flip-flop
ilinx FDCE-flip-flop

Hướng dẫn viết code VHDL cho Shift Register hiệu quả

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-flopilinx 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.

Comments

No comments yet. Why don’t you start the discussion?

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *