From a63dfb4372969efaec9d84f120687ed3e55be852 Mon Sep 17 00:00:00 2001 From: Benjamin Krill Date: Wed, 4 Dec 2013 15:44:08 +0100 Subject: [PATCH] add stream regfile client --- fpga/strm_regfile/strm_regfile.vhd | 154 +++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 fpga/strm_regfile/strm_regfile.vhd diff --git a/fpga/strm_regfile/strm_regfile.vhd b/fpga/strm_regfile/strm_regfile.vhd new file mode 100644 index 0000000..08926e1 --- /dev/null +++ b/fpga/strm_regfile/strm_regfile.vhd @@ -0,0 +1,154 @@ +-- ----------------------------------------------------------------------------- +-- Copyright (c) 2013 Benjamin Krill +-- +-- 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;