---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
-- Microbuffer
|
-- Microbuffer
|
--
|
--
|
-- Part of the LXP32 CPU
|
-- Part of the LXP32 CPU
|
--
|
--
|
-- Copyright (c) 2016 by Alex I. Kuznetsov
|
-- Copyright (c) 2016 by Alex I. Kuznetsov
|
--
|
--
|
-- A small buffer with a FIFO-like interface, implemented
|
-- A small buffer with a FIFO-like interface, implemented
|
-- using registers.
|
-- using registers.
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
|
|
entity lxp32_ubuf is
|
entity lxp32_ubuf is
|
generic(
|
generic(
|
DATA_WIDTH: integer
|
DATA_WIDTH: integer
|
);
|
);
|
port(
|
port(
|
clk_i: in std_logic;
|
clk_i: in std_logic;
|
rst_i: in std_logic;
|
rst_i: in std_logic;
|
|
|
we_i: in std_logic;
|
we_i: in std_logic;
|
d_i: in std_logic_vector(DATA_WIDTH-1 downto 0);
|
d_i: in std_logic_vector(DATA_WIDTH-1 downto 0);
|
re_i: in std_logic;
|
re_i: in std_logic;
|
d_o: out std_logic_vector(DATA_WIDTH-1 downto 0);
|
d_o: out std_logic_vector(DATA_WIDTH-1 downto 0);
|
|
|
empty_o: out std_logic;
|
empty_o: out std_logic;
|
full_o: out std_logic
|
full_o: out std_logic
|
);
|
);
|
end entity;
|
end entity;
|
|
|
architecture rtl of lxp32_ubuf is
|
architecture rtl of lxp32_ubuf is
|
|
|
signal we: std_logic;
|
signal we: std_logic;
|
signal re: std_logic;
|
signal re: std_logic;
|
|
|
signal empty: std_logic:='1';
|
signal empty: std_logic:='1';
|
signal full: std_logic:='0';
|
signal full: std_logic:='0';
|
|
|
type regs_type is array (1 downto 0) of std_logic_vector(DATA_WIDTH-1 downto 0);
|
type regs_type is array (1 downto 0) of std_logic_vector(DATA_WIDTH-1 downto 0);
|
signal regs: regs_type;
|
signal regs: regs_type;
|
signal regs_mux: regs_type;
|
signal regs_mux: regs_type;
|
|
|
signal wpointer: std_logic_vector(2 downto 0):="001";
|
|
|
|
begin
|
begin
|
|
|
we<=we_i and not full;
|
we<=we_i and not full;
|
re<=re_i and not empty;
|
re<=re_i and not empty;
|
|
|
process (clk_i) is
|
process (clk_i) is
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
if rst_i='1' then
|
if rst_i='1' then
|
wpointer<="001";
|
|
empty<='1';
|
empty<='1';
|
full<='0';
|
full<='0';
|
|
regs<=(others=>(others=>'-'));
|
else
|
else
|
if re='0' then
|
if re='0' then
|
regs<=regs_mux;
|
regs(0)<=regs_mux(0);
|
else
|
else
|
regs(0)<=regs_mux(1);
|
regs(0)<=regs_mux(1);
|
end if;
|
end if;
|
|
|
|
regs(1)<=regs_mux(1);
|
|
|
if we='1' and re='0' then
|
if we='1' and re='0' then
|
wpointer<=wpointer(1 downto 0)&"0";
|
|
empty<='0';
|
empty<='0';
|
full<=wpointer(1);
|
full<=not empty;
|
elsif we='0' and re='1' then
|
elsif we='0' and re='1' then
|
wpointer<="0"&wpointer(2 downto 1);
|
empty<=not full;
|
empty<=wpointer(1);
|
|
full<='0';
|
full<='0';
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
mux: for i in regs_mux'range generate
|
regs_mux(0)<=regs(0) when we='0' or empty='0' else d_i;
|
regs_mux(i)<=regs(i) when we='0' or wpointer(i)='0' else d_i;
|
regs_mux(1)<=regs(1) when we='0' or empty='1' else d_i;
|
end generate;
|
|
|
|
d_o<=regs(0);
|
d_o<=regs(0);
|
empty_o<=empty;
|
empty_o<=empty;
|
full_o<=full;
|
full_o<=full;
|
|
|
end architecture;
|
end architecture;
|
|
|