URL
https://opencores.org/ocsvn/rv01_riscv_core/rv01_riscv_core/trunk
Subversion Repositories rv01_riscv_core
[/] [rv01_riscv_core/] [trunk/] [VHDL/] [RV01_ftchlog_1w.vhd] - Rev 2
Compare with Previous | Blame | View Log
----------------------------------------------------------------- -- -- ----------------------------------------------------------------- -- -- -- Copyright (C) 2017 Stefano Tonello -- -- -- -- This source file may be used and distributed without -- -- restriction provided that this copyright statement is not -- -- removed from the file and that any derivative work contains -- -- the original copyright notice and the associated disclaimer.-- -- -- -- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY -- -- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -- -- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -- -- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR -- -- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -- -- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -- -- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -- -- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -- -- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- -- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -- -- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- -- POSSIBILITY OF SUCH DAMAGE. -- -- -- ----------------------------------------------------------------- --------------------------------------------------------------- -- RV01 Instruction Fecthing Logic (scalar version) --------------------------------------------------------------- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; library work; use work.RV01_CONSTS_PKG.all; use work.RV01_TYPES_PKG.all; use work.RV01_CSR_PKG.all; entity RV01_FTCHLOG_1W is port( CLK_i : in std_logic; RST_i : in std_logic; STRT_i : in std_logic; STRTPC_i : in ADR_T; HALT_i : in std_logic; BJX_i : in std_logic; BJTA_i : in ADR_T; PBX_i : in std_logic; PBTA_i : in ADR_T; KLL1_i : in std_logic; PJRX_i : std_logic; PJRTA_i : in ADR_T; EXCP_i : in std_logic; ERET_i : in std_logic; RFTCH_i : in std_logic; ETVA_i : in ADR_T; PSTALL_i : in std_logic; -- Debug interface DHALT_i : in std_logic; IFV_o : out std_logic; IADR0_o : out ADR_T; IADR_MIS_o : out std_logic ); end RV01_FTCHLOG_1W; architecture ARC of RV01_FTCHLOG_1W is signal PC,PC_q : unsigned(ALEN-3 downto 0); signal PC_NS : unsigned(ALEN-3 downto 0); signal PCP4,PCP4_q : unsigned(ALEN-3 downto 0); signal HALT_q : std_logic; signal FC : std_logic; signal PC_NS_FC : unsigned(ALEN-3 downto 0); begin -- Halt flag register process(CLK_i) begin if(CLK_i = '1' and CLK_i'event) then if(RST_i = '1' or HALT_i = '1') then HALT_q <= '1'; elsif(STRT_i = '1') then HALT_q <= '0'; end if; end if; end process; -- Instructions are always fetched from a word address, so -- that PC LS 2 bits are guaranteed to be zero and are -- therefore not physically implemented. -- Fetched instruction #0 is always valid, unless processor is -- halted or fetch address is odd. IFV_o <= not(HALT_q) or STRT_i; -- PC register reset value is set to reset exception vector -- "low" address. -- PC register is incremented only if pipeline is not -- stalled (i.e. when PSTALL_i = '0'). -- PC+4 value is pre-calculated in current cycle and stored -- into PCP4 to remove addition from address critical path. -- Program Counter register process(CLK_i) begin if(CLK_i = '1' and CLK_i'event) then if(RST_i = '1') then PC_q <= to_unsigned(0,SDLEN-2); PCP4_q <= to_unsigned(1,SDLEN-2); elsif((HALT_q = '0') or (STRT_i = '1')) then PC_q <= PC; PCP4_q <= PCP4; end if; end if; end process; -- PC plus 4 PCP4 <= PC_NS + 1 when ( PSTALL_i = '0' or EXCP_i = '1' or ERET_i = '1' or RFTCH_i = '1' ) else PCP4_q; -- Flow change flag (non sequential fetch) FC <= EXCP_i or ERET_i or RFTCH_i or BJX_i; -- PC no-stall value process(PBX_i,PJRX_i,FC,PC_NS_FC,PBTA_i,PJRTA_i,PSTALL_i,PC_q,KLL1_i) begin if(PBX_i = '1' and FC = '0' and PSTALL_i = '0' and KLL1_i = '0') then PC_NS <= PBTA_i(ALEN-1 downto 2); elsif(PJRX_i = '1' and FC = '0' and PSTALL_i = '0') then PC_NS <= PJRTA_i(ALEN-1 downto 2); elsif(FC = '1' or PSTALL_i = '0') then PC_NS <= PC_NS_FC; else PC_NS <= PC_q; end if; end process; -- Current cycle PC value mux -- ETVA_i can be true exception vector, an address from CSR MEPC, -- a re-fetch address, debug memory address or a resume address. -- STRTPC_i can be the reset vector or an address from CSR MRV01HA. process(STRT_i,EXCP_i,ERET_i,RFTCH_i,ETVA_i,BJX_i,BJTA_i, PCP4_q,DHALT_i,STRTPC_i) begin if( BJX_i = '1' and (EXCP_i = '0' and ERET_i = '0' and RFTCH_i = '0' and DHALT_i = '0') ) then -- Note: the complicated if-condition allows to remove one -- muxing level on BJTA_i path. PC_NS_FC <= BJTA_i(ALEN-1 downto 2); elsif( EXCP_i = '1' or ERET_i = '1' or RFTCH_i = '1' or DHALT_i = '1' ) then PC_NS_FC <= ETVA_i(ALEN-1 downto 2); elsif(STRT_i = '1') then PC_NS_FC <= STRTPC_i(ALEN-1 downto 2); else PC_NS_FC <= PCP4_q; end if; end process; -- Current cycle PC PC <= PC_NS; -- Fetch address IADR0_o <= PC & "00"; -- A misaligned instruction address can be generated only -- by a B/J instruction. process(BJX_i,PBX_i,PJRX_i,BJTA_i,PJRTA_i,PBTA_i) begin IADR_MIS_o <= '0'; if(BJX_i = '1' and BJTA_i(1 downto 0) /= "00") then IADR_MIS_o <= '1'; elsif(PBX_i = '1' and PBTA_i(1 downto 0) /= "00" and KLL1_i = '0') then IADR_MIS_o <= '1'; elsif(PJRX_i = '1' and PJRTA_i(1 downto 0) /= "00") then IADR_MIS_o <= '1'; end if; end process; end ARC;