Bài viết này sẽ trình bày ba cách khác nhau để implement một shift register trong VHDL. Đầu tiên, chúng ta cùng xem lại khái niệm shift register. Nó có thể được biểu diễn bằng một chuỗi các flip-flop được kết nối nối tiếp, trong đó đầu ra của một flip-flop là đầu vào của flip-flop tiếp theo.
Hình 1 dưới đây minh họa cấu trúc của một shift register.
Như đã đề cập, có ít nhất ba cách khác nhau để mô tả cấu trúc phần cứng này trong VHDL. Ba mô tả này hoàn toàn tương đương nhau.
Mô tả Shift Register trong VHDL theo cách thông thường
Một mô tả thông thường của shift register trong Hình 1 được thể hiện trong đoạn mã VHDL dưới đây.
library ieee; use ieee.std_logic_1164.all;
entity shift_register is
port (
i_clk : in std_logic;
i_rstb : in std_logic;
i_data : in std_logic_vector(1 downto 0);
o_data : out std_logic_vector(1 downto 0)
);
end shift_register;
architecture rtl of shift_register is
signal r0_data : std_logic_vector(1 downto 0);
signal r1_data : std_logic_vector(1 downto 0);
signal r2_data : std_logic_vector(1 downto 0);
signal r3_data : std_logic_vector(1 downto 0);
begin
o_data <= r3_data;
process(i_clk, i_rstb)
begin
if(i_rstb = '0') then
r0_data <= (others => '0');
r1_data <= (others => '0');
r2_data <= (others => '0');
r3_data <= (others => '0');
elsif(rising_edge(i_clk)) then
r0_data <= i_data;
r1_data <= r0_data;
r2_data <= r1_data;
r3_data <= r2_data;
end if;
end process;
end rtl;
Trong trường hợp này, mỗi thanh ghi được khai báo trong phần khai báo kiến trúc. Đây là một mô tả VHDL đơn giản và dễ hiểu cho một shift register. Vì flip-flop được khai báo dưới dạng tín hiệu, bạn có thể thay đổi thứ tự gán mà không làm thay đổi kết quả cuối cùng.
Một cách tiếp cận khác là sử dụng biến thay vì tín hiệu bên trong process.
library ieee; use ieee.std_logic_1164.all;
entity shift_register is
port (
i_clk : in std_logic;
i_rstb : in std_logic;
i_data : in std_logic_vector(1 downto 0);
o_data : out std_logic_vector(1 downto 0)
);
end shift_register;
architecture rtl of shift_register is
begin
p_sreg : process(i_clk,i_rstb)
variable v0_data : std_logic_vector(1 downto 0);
variable v1_data : std_logic_vector(1 downto 0);
variable v2_data : std_logic_vector(1 downto 0);
begin
if(i_rstb='0') then
v0_data := (others=>'0');
v1_data := (others=>'0');
v2_data := (others=>'0');
o_data <= (others=>'0');
elsif(rising_edge(i_clk)) then
v0_data := i_data;
v1_data := v0_data;
v2_data := v1_data;
o_data <= v2_data;
end if;
end process;
end rtl;
Cách tiếp cận này hữu ích khi bạn cần nhiều shift register khác nhau mà không cần khai báo nhiều tín hiệu. Lưu ý rằng thứ tự gán rất quan trọng khi sử dụng biến vì giá trị được gán ngay lập tức.
Mô tả Shift Register trong VHDL sử dụng vòng lặp For
Một cách triển khai shift register VHDL hiệu quả hơn về mặt mô tả mã VHDL có thể đạt được bằng cách sử dụng câu lệnh lặp for. So với mô tả thông thường, việc triển khai vòng lặp for VHDL có thể được tham số hóa. Trong mã VHDL, chúng ta đã sử dụng khai báo kiểu cho shift register để số lượng shift register cần triển khai có thể được truyền dưới dạng hằng số hoặc generic trong thực thể VHDL.
library ieee; use ieee.std_logic_1164.all;
entity shift_register is
port (
i_clk : in std_logic;
i_rstb : in std_logic;
i_data : in std_logic_vector(1 downto 0);
o_data : out std_logic_vector(1 downto 0)
);
end shift_register;
architecture rtl of shift_register is
type t_sreg is array(0 to 3) of std_logic_vector(1 downto 0);
signal r_data : t_sreg;
begin
o_data <= r_data(3);
process(i_clk, i_rstb)
begin
if(i_rstb = '0') then
r_data <= (others => (others => '0'));
elsif(rising_edge(i_clk)) then
r_data(0) <= i_data;
for i in 1 to 3 loop
r_data(i) <= r_data(i-1);
end loop;
end if;
end process;
end rtl;
Mô tả Shift Register trong VHDL chỉ với một dòng code
Việc triển khai shift register cuối cùng là sử dụng một dòng mã VHDL duy nhất. Bạn có thể triển khai một shift register theo cách tham số với một dòng mã VHDL.
library ieee; use ieee.std_logic_1164.all;
entity shift_register is
port (
i_clk : in std_logic;
i_rstb : in std_logic;
i_data : in std_logic_vector(1 downto 0);
o_data : out std_logic_vector(1 downto 0)
);
end shift_register;
architecture rtl of shift_register is
type t_sreg is array(0 to 3) of std_logic_vector(1 downto 0);
signal r_data : t_sreg;
begin
o_data <= r_data(3);
process(i_clk, i_rstb)
begin
if(i_rstb = '0') then
r_data <= (others => (others => '0'));
elsif(rising_edge(i_clk)) then
r_data <= i_data & r_data(0 to 2);
end if;
end process;
end rtl;
Trong mô tả này, chức năng shift được triển khai bằng cách sử dụng tính năng gán do VHDL cung cấp. VHDL cho phép gán các đối tượng cùng loại trong một dòng mã.