155 lines
5.5 KiB
VHDL
155 lines
5.5 KiB
VHDL
-- -----------------------------------------------------------------------------
|
|
-- Copyright (c) 2013 Benjamin Krill <benjamin@krll.de>
|
|
--
|
|
-- Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
-- of this software and associated documentation files (the "Software"), to deal
|
|
-- in the Software without restriction, including without limitation the rights
|
|
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
-- copies of the Software, and to permit persons to whom the Software is
|
|
-- furnished to do so, subject to the following conditions:
|
|
--
|
|
-- The above copyright notice and this permission notice shall be included in
|
|
-- all copies or substantial portions of the Software.
|
|
--
|
|
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
-- THE SOFTWARE.
|
|
-- -----------------------------------------------------------------------------
|
|
library ieee;
|
|
use ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use work.strm_package.all;
|
|
|
|
entity strm_regfile is
|
|
generic ( REGISTER_CNT : integer := 1 );
|
|
port (
|
|
clk : in std_logic;
|
|
rst_n : in std_logic;
|
|
debug : out std_logic_vector( 7 downto 0);
|
|
|
|
-- streaming bus
|
|
strm_in_data_i : in std_logic_vector(31 downto 0);
|
|
strm_in_eop_i : in std_logic;
|
|
strm_in_sop_i : in std_logic;
|
|
strm_in_en_i : in std_logic;
|
|
strm_in_busy_o : out std_logic;
|
|
strm_out_req_o : out std_logic;
|
|
strm_out_busy_i : in std_logic;
|
|
strm_out_data_o : out std_logic_vector(31 downto 0);
|
|
strm_out_eop_o : out std_logic;
|
|
strm_out_en_o : out std_logic;
|
|
|
|
-- regfile
|
|
regfile_i : in std_logic_vector((32*REGISTER_CNT)-1 downto 0);
|
|
regfile_o : out std_logic_vector((32*REGISTER_CNT)-1 downto 0)
|
|
);
|
|
end strm_regfile;
|
|
|
|
architecture strm_regfile of strm_regfile is
|
|
type sm_strm_t is (IDLE, ADDRESS, READ, READ_OUT, WRITE);
|
|
signal sm_strm : sm_strm_t;
|
|
signal rst : std_logic;
|
|
signal strm_in_tag : std_logic_vector( 3 downto 0);
|
|
signal strm_in_data : std_logic_vector(31 downto 0);
|
|
signal strm_in_eop : std_logic;
|
|
signal strm_in_sop : std_logic;
|
|
signal strm_in_en : std_logic;
|
|
signal strm_in_busy : std_logic;
|
|
signal strm_type_vld : std_logic;
|
|
signal strm_out_en : std_logic;
|
|
signal strm_out_eop : std_logic;
|
|
signal strm_out_hdr_en : std_logic;
|
|
signal reg_adr : unsigned(27 downto 0);
|
|
signal reg_dat : std_logic_vector(31 downto 0);
|
|
type regfile_t is array(natural range <>) of std_logic_vector(31 downto 0);
|
|
signal regfile_in : regfile_t(REGISTER_CNT-1 downto 0);
|
|
signal regfile_out : regfile_t(REGISTER_CNT-1 downto 0);
|
|
begin
|
|
strm_in_data <= strm_in_data_i;
|
|
strm_in_eop <= strm_in_eop_i;
|
|
strm_in_sop <= strm_in_sop_i;
|
|
strm_in_en <= strm_in_en_i;
|
|
strm_in_busy_o <= strm_in_busy;
|
|
|
|
mreg: for I in 0 to REGISTER_CNT-1 generate
|
|
regfile_in(I) <= regfile_i((32*(I+1))-1 downto 32*I);
|
|
regfile_o((32*(I+1))-1 downto 32*I) <= regfile_out(I);
|
|
end generate mreg;
|
|
|
|
strm_in_busy <= '1' when sm_strm = WRITE or sm_strm = READ or sm_strm = READ_OUT else '0';
|
|
strm_type_vld <= strm_in_sop when strm_in_data(STRM_TYPE_HIGH downto STRM_TYPE_LOW) = STRM_TYPE_REGFILE else '0';
|
|
process (clk, rst_n)
|
|
begin
|
|
if rst_n = '0' then
|
|
sm_strm <= IDLE;
|
|
strm_in_tag <= (others => '0');
|
|
strm_out_hdr_en <= '0';
|
|
regfile_out <= (others => (others => '0'));
|
|
reg_dat <= (others => '0');
|
|
elsif rising_edge(clk) then
|
|
if sm_strm = IDLE and strm_type_vld = '1' then
|
|
strm_in_tag <= strm_in_data(STRM_TAG_HIGH downto STRM_TAG_LOW);
|
|
end if;
|
|
|
|
-- SAVE ADDRESS
|
|
if sm_strm = ADDRESS and strm_in_en = '1' then
|
|
reg_adr <= unsigned(strm_in_data(STRM_DDR2_ADR_HIGH downto STRM_DDR2_ADR_LOW));
|
|
end if;
|
|
|
|
-- write regfile
|
|
if sm_strm = WRITE and strm_in_en = '1' then
|
|
regfile_out(to_integer(reg_adr)) <= strm_in_data;
|
|
end if;
|
|
|
|
-- read regfile
|
|
if sm_strm = READ then
|
|
reg_dat <= regfile_in(to_integer(reg_adr));
|
|
end if;
|
|
|
|
if sm_strm = IDLE then
|
|
strm_out_hdr_en <= '1';
|
|
elsif strm_out_en = '1' then
|
|
end if;
|
|
|
|
-- SM
|
|
case sm_strm is
|
|
when IDLE =>
|
|
if strm_type_vld = '1' and strm_in_en = '1' then
|
|
sm_strm <= ADDRESS;
|
|
end if;
|
|
when ADDRESS =>
|
|
if strm_in_en = '1' then
|
|
if strm_in_data(STRM_DDR2_ACCESS) = STRM_DDR2_ACC_WRITE then
|
|
sm_strm <= WRITE;
|
|
else
|
|
sm_strm <= READ;
|
|
end if;
|
|
end if;
|
|
when WRITE =>
|
|
if strm_in_en = '1' then
|
|
sm_strm <= IDLE;
|
|
end if;
|
|
when READ =>
|
|
sm_strm <= READ_OUT;
|
|
when READ_OUT =>
|
|
if strm_out_eop = '1' then
|
|
sm_strm <= IDLE;
|
|
end if;
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
strm_out_req_o <= strm_out_busy_i when sm_strm = READ_OUT else '0';
|
|
strm_out_en <= not strm_out_busy_i when sm_strm = READ_OUT else '0';
|
|
strm_out_en_o <= strm_out_en;
|
|
strm_out_eop <= strm_out_en and not strm_out_hdr_en;
|
|
strm_out_eop_o <= strm_out_eop;
|
|
strm_out_data_o <= STRM_TYPE_REGFILE & strm_in_tag & (23 downto 1 => '0') & '1'
|
|
when strm_out_hdr_en = '1' else reg_dat;
|
|
|
|
end strm_regfile;
|