--=============================
-- Listing 9.16 fifo controller
--=============================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fifo_sync_ctrl4 is
port(
clk, reset: in std_logic;
wr, rd: in std_logic;
full, empty: out std_logic;
w_addr, r_addr: out std_logic_vector(1 downto 0)
);
end fifo_sync_ctrl4;
architecture enlarged_bin_arch of fifo_sync_ctrl4 is
constant N: natural:=2;
signal w_ptr_reg, w_ptr_next: unsigned(N downto 0);
signal r_ptr_reg, r_ptr_next: unsigned(N downto 0);
signal full_flag, empty_flag: std_logic;
begin
-- register
process(clk,reset)
begin
if (reset='1') then
w_ptr_reg <= (others=>'0');
r_ptr_reg <= (others=>'0');
elsif (clk'event and clk='1') then
w_ptr_reg <= w_ptr_next;
r_ptr_reg <= r_ptr_next;
end if;
end process;
-- write pointer next-state logic
w_ptr_next <=
w_ptr_reg + 1 when wr='1' and full_flag='0' else
w_ptr_reg;
full_flag <=
'1' when r_ptr_reg(N) /=w_ptr_reg(N) and
r_ptr_reg(N-1 downto 0)=w_ptr_reg(N-1 downto 0)
else
'0';
-- write port output
w_addr <= std_logic_vector(w_ptr_reg(N-1 downto 0));
full <= full_flag;
-- read pointer next-state logic
r_ptr_next <=
r_ptr_reg + 1 when rd='1' and empty_flag='0' else
r_ptr_reg;
empty_flag <= '1' when r_ptr_reg=w_ptr_reg else
'0';
-- read port output
r_addr <= std_logic_vector(r_ptr_reg(N-1 downto 0));
empty <= empty_flag;
end enlarged_bin_arch;
--=============================
-- Listing 9.17
--=============================
architecture lookahead_bin_arch of fifo_sync_ctrl4 is
constant N: natural:=2;
signal w_ptr_reg, w_ptr_next: unsigned(N-1 downto 0);
signal w_ptr_succ: unsigned(N-1 downto 0);
signal r_ptr_reg, r_ptr_next: unsigned(N-1 downto 0);
signal r_ptr_succ: unsigned(N-1 downto 0);
signal full_reg, empty_reg: std_logic;
signal full_next, empty_next: std_logic;
signal wr_op: std_logic_vector(1 downto 0);
begin
-- register
process(clk,reset)
begin
if (reset='1') then
w_ptr_reg <= (others=>'0');
r_ptr_reg <= (others=>'0');
elsif (clk'event and clk='1') then
w_ptr_reg <= w_ptr_next;
r_ptr_reg <= r_ptr_next;
end if;
end process;
-- status FF
process(clk,reset)
begin
if (reset='1') then
full_reg <= '0';
empty_reg <= '1';
elsif (clk'event and clk='1') then
full_reg <= full_next;
empty_reg <= empty_next;
end if;
end process;
-- successive value for the write and read pointers
w_ptr_succ <= w_ptr_reg + 1;
r_ptr_succ <= r_ptr_reg + 1;
-- next-state logic
wr_op <= wr & rd;
process(w_ptr_reg,w_ptr_succ,r_ptr_reg,r_ptr_succ,
wr_op,empty_reg,full_reg)
begin
w_ptr_next <= w_ptr_reg;
r_ptr_next <= r_ptr_reg;
full_next <= full_reg;
empty_next <= empty_reg;
case wr_op is
when "00" => -- no op
when "10" => -- write
if (full_reg /= '1') then -- not full
w_ptr_next <= w_ptr_succ;
empty_next <= '0';
if (w_ptr_succ=r_ptr_reg) then
full_next <='1';
end if;
end if;
when "01" => -- read
if (empty_reg /= '1') then -- not empty
r_ptr_next <= r_ptr_succ;
full_next <= '0';
if (r_ptr_succ=w_ptr_reg) then
empty_next <='1';
end if;
end if;
when others => -- write/read;
w_ptr_next <= w_ptr_succ;
r_ptr_next <= r_ptr_succ;
end case;
end process;
-- write port output
w_addr <= std_logic_vector(w_ptr_reg);
full <= full_reg;
r_addr <= std_logic_vector(r_ptr_reg);
empty <= empty_reg;
end lookahead_bin_arch;
Monday, 30 October 2017
VHDL FIFO CONTROLLER
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment