Files
vhdl/lib/emac/src/piso.vhd
T
jens 08e85b7e8f - modified input rdy logic to avoid multi cycle ready after idle
Committed on the Free edition of March Hare Software CVSNT Server.
Upgrade to CVS Suite for more features and support:
http://march-hare.com/cvsnt/


git-svn-id: http://moon:8086/svn/vhdl/trunk@826 cc03376c-175c-47c8-b038-4cd826a8556b
2010-03-25 21:34:10 +00:00

141 lines
3.6 KiB
VHDL

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use std.textio.all; -- Imports the standard textio package.
use work.utils_pkg.all; -- Imports the standard textio package.
ENTITY piso IS
Generic
(
data_width_in : natural := 32;
data_width_out : natural := 8;
msb_first : boolean := false
);
Port
(
rst : in STD_LOGIC;
clk : in STD_LOGIC;
din_vld : in STD_LOGIC;
din_rdy : out STD_LOGIC;
din_be : in unsigned(data_width_in/data_width_out-1 downto 0);
din : in unsigned(data_width_in-1 downto 0);
dout_vld : out STD_LOGIC;
dout_en : in STD_LOGIC;
dout : out unsigned(data_width_out-1 downto 0)
);
END piso;
ARCHITECTURE behavior OF piso IS
constant num_shifts : natural := data_width_in/data_width_out;
signal pre_fin : STD_LOGIC;
signal rdy : STD_LOGIC;
signal shift_cnt_pipe : unsigned(num_shifts-1 downto 0);
signal shift_pipe : unsigned(data_width_in-1 downto 0);
signal vld_pipe : unsigned(num_shifts-1 downto 0);
signal din_reg : unsigned(data_width_in-1 downto 0);
signal din_be_reg : unsigned(num_shifts-1 downto 0);
signal din_vld_reg : STD_LOGIC;
--------------------------------------------------------------------------
begin
pre_fin <= shift_cnt_pipe(shift_cnt_pipe'left-1);
din_rdy <= rdy;
dout_vld <= vld_pipe(vld_pipe'left) when msb_first else vld_pipe(0);
dout <= shift_pipe(shift_pipe'left downto shift_pipe'left-data_width_out+1) when msb_first
else shift_pipe(data_width_out-1 downto 0);
--------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
rdy <= '0';
elsif pre_fin = '1' and rdy = '0' then
rdy <= '1';
elsif din_vld = '1' then
rdy <= '0';
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
din_vld_reg <= '0';
elsif pre_fin = '1' and dout_en = '1' then
din_vld_reg <= din_vld;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if din_vld = '1' and rdy = '1' then
din_reg <= din;
din_be_reg <= din_be;
end if;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
shift_cnt_pipe <= (others => '1');
elsif dout_en = '1' then
if (pre_fin = '1' and din_vld_reg = '1') or (din_vld = '1' and din_vld_reg = '0') then
shift_cnt_pipe <= (others => '0');
else
shift_cnt_pipe <= shift_cnt_pipe(shift_cnt_pipe'left-1 downto 0) & '1';
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if dout_en = '1' then
if pre_fin = '1' and din_vld_reg = '1' then
shift_pipe <= din_reg;
else
if (msb_first) then
shift_pipe <= shift_pipe(shift_pipe'left-data_width_out downto 0) & (data_width_out-1 downto 0 => '0');
else
shift_pipe <= (data_width_out-1 downto 0 => '0') & shift_pipe(shift_pipe'left downto data_width_out);
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------
process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
vld_pipe <= (others => '0');
elsif dout_en = '1' then
if pre_fin = '1' and din_vld_reg = '1' then
vld_pipe <= din_be_reg;
else
if (msb_first) then
vld_pipe <= vld_pipe(vld_pipe'left-1 downto 0) & '0';
else
vld_pipe <= '0' & vld_pipe(vld_pipe'left downto 1);
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------
end behavior;