Inital version
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@912 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
use work.utils_pkg.all; -- Imports the standard textio package.
|
||||
|
||||
ENTITY align IS
|
||||
Generic
|
||||
(
|
||||
data_width : natural := 32;
|
||||
aggregate_size : natural := 8;
|
||||
allow_partial_valid : boolean := false
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
eb : in STD_LOGIC;
|
||||
offset : in unsigned(NextExpBaseTwo(data_width/aggregate_size)-1 downto 0);
|
||||
din_last_vld : in STD_LOGIC;
|
||||
din_vld : in STD_LOGIC;
|
||||
din : in unsigned(data_width-1 downto 0);
|
||||
dout_vld : out STD_LOGIC;
|
||||
dout : out unsigned(data_width-1 downto 0);
|
||||
dout_be : out unsigned(data_width/aggregate_size-1 downto 0)
|
||||
|
||||
);
|
||||
END align;
|
||||
|
||||
ARCHITECTURE behavior OF align IS
|
||||
|
||||
signal shift_dout : unsigned(data_width-1 downto 0);
|
||||
signal shift_vld : std_logic;
|
||||
|
||||
signal reg0_vld : std_logic;
|
||||
signal reg0 : unsigned(data_width-1 downto 0);
|
||||
|
||||
signal reg : unsigned(data_width-1 downto 0);
|
||||
signal reg_vld : std_logic;
|
||||
signal reg_be : unsigned(data_width/aggregate_size-1 downto 0);
|
||||
|
||||
signal data_vld : std_logic;
|
||||
signal shift_din_vld : std_logic;
|
||||
signal last_vld : unsigned(NextExpBaseTwo(data_width/aggregate_size)-1 downto 0);
|
||||
|
||||
type byte_en_rom_t is array (0 to 2*data_width/aggregate_size-1) of unsigned (data_width/aggregate_size-1 downto 0);
|
||||
|
||||
function gen_byte_en_rom(N : natural) return byte_en_rom_t is
|
||||
variable k : integer;
|
||||
variable result : byte_en_rom_t;
|
||||
begin
|
||||
|
||||
k:=0;
|
||||
|
||||
result(k) := (others => '1');
|
||||
k := k + 1;
|
||||
|
||||
for i in 1 to N-1 loop
|
||||
result(k) := (N-1 downto i => '1') & (i-1 downto 0 => '0');
|
||||
k := k + 1;
|
||||
end loop;
|
||||
|
||||
result(k) := (others => '1');
|
||||
k := k + 1;
|
||||
|
||||
for i in 1 to N-1 loop
|
||||
result(k) := (N-1 downto i => '0') & (i-1 downto 0 => '1');
|
||||
k := k + 1;
|
||||
end loop;
|
||||
|
||||
return result;
|
||||
end gen_byte_en_rom;
|
||||
|
||||
signal byte_en_rom : byte_en_rom_t := gen_byte_en_rom(data_width/aggregate_size);
|
||||
signal byte_en : unsigned (data_width/aggregate_size-1 downto 0);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
byte_en <= byte_en_rom(to_integer(not eb & offset));
|
||||
dout <= reg;
|
||||
dout_be <= reg_be;
|
||||
dout_vld <= data_vld;
|
||||
shift_din_vld <= din_vld;
|
||||
|
||||
inst_shifter : entity work.shifter
|
||||
GENERIC MAP
|
||||
(
|
||||
data_width => data_width,
|
||||
aggregate_size => aggregate_size,
|
||||
do_pipelined => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
ce => ce,
|
||||
sa => to_integer(offset),
|
||||
din_vld => shift_din_vld,
|
||||
din => din,
|
||||
dout_vld => shift_vld,
|
||||
dout => shift_dout
|
||||
|
||||
);
|
||||
|
||||
proc_data_valid:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
reg0_vld <= '0';
|
||||
data_vld <= '0';
|
||||
last_vld <= (others => '0');
|
||||
elsif ce = '1' then
|
||||
last_vld <= last_vld(last_vld'left-1 downto 0) & din_last_vld;
|
||||
reg0_vld <= shift_vld;
|
||||
if offset /= (NextExpBaseTwo(data_width/aggregate_size)-1 downto 0 => '0') and not allow_partial_valid then
|
||||
data_vld <= reg_vld and (shift_vld and not last_vld(last_vld'left));
|
||||
else
|
||||
data_vld <= shift_vld or last_vld(last_vld'left);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_align:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if ce = '1' then
|
||||
if shift_vld = '1' then
|
||||
reg0 <= shift_dout;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_blit_dst_combine:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
reg_be <= (others => '0');
|
||||
reg_vld <= '0';
|
||||
elsif ce = '1' then
|
||||
if reg0_vld = '1' or shift_vld = '1' then
|
||||
reg_vld <= not last_vld(last_vld'left);
|
||||
reg <= reg0;
|
||||
if reg_vld = '0' or last_vld(last_vld'left) = '1' then
|
||||
reg_be <= not byte_en and (data_width/aggregate_size-1 downto 0 => reg0_vld);
|
||||
else
|
||||
reg_be <= not byte_en;
|
||||
end if;
|
||||
if shift_vld = '1' then
|
||||
for i in 0 to data_width/aggregate_size-1 loop
|
||||
if byte_en(i) = '1' then
|
||||
reg_be(i) <= '1';
|
||||
reg(aggregate_size*(i+1)-1 downto aggregate_size*i) <= shift_dout(aggregate_size*(i+1)-1 downto aggregate_size*i);
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end behavior;
|
||||
@@ -0,0 +1,133 @@
|
||||
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 shifter IS
|
||||
Generic
|
||||
(
|
||||
data_width : natural := 32;
|
||||
aggregate_size : natural := 8;
|
||||
positive_shift_left : boolean := true;
|
||||
do_pipelined : boolean := true
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
sa : in integer;
|
||||
din_vld : in STD_LOGIC;
|
||||
din : in unsigned(data_width-1 downto 0);
|
||||
dout_vld : out STD_LOGIC;
|
||||
dout : out unsigned(data_width-1 downto 0)
|
||||
|
||||
);
|
||||
END shifter;
|
||||
|
||||
ARCHITECTURE behavior OF shifter IS
|
||||
|
||||
constant num_rounds : natural := NextExpBaseTwo(data_width/aggregate_size);
|
||||
subtype sa_rnd_t is signed(num_rounds-1 downto 0);
|
||||
subtype word_t is unsigned(data_width-1 downto 0);
|
||||
type word_array_t is array (0 to num_rounds) of word_t;
|
||||
|
||||
signal rot_data : word_array_t;
|
||||
signal sa_rnd : sa_rnd_t;
|
||||
|
||||
type sa_rnd_array_t is array (0 to num_rounds) of sa_rnd_t;
|
||||
signal sa_rnd_pipe : sa_rnd_array_t;
|
||||
signal dout_vld_pipe : unsigned(0 to num_rounds);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function rol_stage(x : unsigned; en : std_logic; stage_num : natural; size : natural) return unsigned is
|
||||
variable result : unsigned(x'range);
|
||||
constant sa : natural := (2**stage_num) * size;
|
||||
begin
|
||||
if en = '1' then
|
||||
result := x(x'left-sa downto 0) & x(x'left downto x'length-sa);
|
||||
else
|
||||
result := x;
|
||||
end if;
|
||||
return result;
|
||||
|
||||
end rol_stage;
|
||||
|
||||
|
||||
function ror_stage(x : unsigned; en : std_logic; stage_num : natural; size : natural) return unsigned is
|
||||
variable result : unsigned(x'range);
|
||||
constant sa : natural := (2**stage_num) * size;
|
||||
begin
|
||||
if en = '1' then
|
||||
result := x(sa-1 downto 0) & x(x'left downto sa);
|
||||
else
|
||||
result := x;
|
||||
end if;
|
||||
return result;
|
||||
|
||||
end ror_stage;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
gen_non_pipelined:
|
||||
if do_pipelined = false generate
|
||||
begin
|
||||
|
||||
rot_data(0) <= din;
|
||||
|
||||
gen_rotate:
|
||||
for stage in 0 to num_rounds-1 generate
|
||||
begin
|
||||
rot_data(stage+1) <= rol_stage(rot_data(stage), sa_rnd(stage), stage, aggregate_size) when positive_shift_left else
|
||||
ror_stage(rot_data(stage), sa_rnd(stage), stage, aggregate_size);
|
||||
end generate;
|
||||
|
||||
sa_rnd <= to_signed(sa, num_rounds);
|
||||
dout <= rot_data(num_rounds);
|
||||
dout_vld <= din_vld;
|
||||
|
||||
end generate;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
gen_pipelined:
|
||||
if do_pipelined = true generate
|
||||
begin
|
||||
|
||||
rot_data(0) <= din;
|
||||
sa_rnd_pipe(0) <= to_signed(sa, num_rounds);
|
||||
dout_vld_pipe(0) <= din_vld;
|
||||
|
||||
gen_rotate:
|
||||
for stage in 0 to num_rounds-1 generate
|
||||
begin
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
dout_vld_pipe(stage+1) <= '0';
|
||||
elsif ce = '1' then
|
||||
dout_vld_pipe(stage+1) <= dout_vld_pipe(stage);
|
||||
if dout_vld_pipe(stage) = '1' then
|
||||
sa_rnd_pipe(stage+1) <= sa_rnd_pipe(stage);
|
||||
if positive_shift_left then
|
||||
rot_data(stage+1) <= rol_stage(rot_data(stage), sa_rnd_pipe(stage)(stage), stage, aggregate_size);
|
||||
else
|
||||
rot_data(stage+1) <= ror_stage(rot_data(stage), sa_rnd_pipe(stage)(stage), stage, aggregate_size);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
dout <= rot_data(num_rounds);
|
||||
dout_vld <= dout_vld_pipe(num_rounds);
|
||||
|
||||
end generate;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end behavior;
|
||||
Reference in New Issue
Block a user