OpenCores
URL https://opencores.org/ocsvn/hpc-16/hpc-16/trunk

Subversion Repositories hpc-16

[/] [hpc-16/] [tags/] [release1/] [impl0/] [rtl/] [vhdl/] [dp.vhd] - Rev 15

Compare with Previous | Blame | View Log

--------------------------------------------------------------
-- dp.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: microprocessor datapath 
--
-- dependency: dp_pkg.vhd 
--
-- Author: M. Umair Siddiqui (umairsiddiqui@opencores.org)
---------------------------------------------------------------
------------------------------------------------------------------------------------
--                                                                                --
--    Copyright (c) 2005, M. Umair Siddiqui all rights reserved                   --
--                                                                                --
--    This file is part of HPC-16.                                                --
--                                                                                --
--    HPC-16 is free software; you can redistribute it and/or modify              --
--    it under the terms of the GNU Lesser General Public License as published by --
--    the Free Software Foundation; either version 2.1 of the License, or         --
--    (at your option) any later version.                                         --
--                                                                                --
--    HPC-16 is distributed in the hope that it will be useful,                   --
--    but WITHOUT ANY WARRANTY; without even the implied warranty of              --
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               --
--    GNU Lesser General Public License for more details.                         --
--                                                                                --
--    You should have received a copy of the GNU Lesser General Public License    --
--    along with HPC-16; if not, write to the Free Software                       --
--    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   --
--                                                                                --
------------------------------------------------------------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use work.dp_pkg.all;
 
entity dp is
   generic
   ( pc_preset_value : std_logic_vector(15 downto 0) := X"0000";  
     sp_preset_value : std_logic_vector(15 downto 0) := X"0000"
   );
   port
   (
   CLK_I : in std_logic;
   DAT_IO: inout std_logic_vector(15 downto 0);
   ADR_O : out std_logic_vector(15 downto 0);
   --
   jcc_ok : out std_logic;
   int_flag : out std_logic; 
   pc0 : out std_logic;
   sp0 : out std_logic;
   mar0 : out std_logic;
   tr20 : out std_logic;
   ir_high : out std_logic_vector(7 downto 0);
   --
   intr_ce : in std_logic;
   ir_ce : in std_logic;
   mdri_ce : in std_logic;
   mdri_hl_zse_sign : in std_logic;   
   intno_mux_sel : in std_logic_vector(2 downto 0);
   adin_mux_sel : in std_logic_vector(2 downto 0);
   rf_adwe : in std_logic;
   pcin_mux_sel : in std_logic_vector(1 downto 0);
   pc_pre : in std_logic;
   pc_ce : in std_logic;
   spin_mux_sel : in std_logic;
   sp_pre : in std_logic;
   sp_ce : in std_logic;
   dfh_ce : in std_logic;
   alua_mux_sel : in std_logic_vector(1 downto 0);
   alub_mux_sel : in std_logic_vector(2 downto 0);
   aopsel : in std_logic_vector(2 downto 0); 
   sopsel : in std_logic_vector(2 downto 0);
   sbin_mux_sel : in std_logic;
   asresult_mux_sel : std_logic;
   coszin_mux_sel : in std_logic;
   flags_rst : in std_logic;
   flags_ce : in std_logic;
   flags_cfce : in std_logic;
   flags_ifce : in std_logic;
   flags_clc : in std_logic;
   flags_cmc : in std_logic;
   flags_stc : in std_logic;
   flags_cli : in std_logic;
   flags_sti : in std_logic;
   marin_mux_sel : in std_logic_vector(1 downto 0);
   mar_ce : in std_logic;
   mdroin_mux_sel : in std_logic_vector(2 downto 0);
   mdro_ce : in std_logic; -- mdro rst removed (11 aug 2005)
   mdro_oe : in std_logic
   );   
end dp;
 
architecture rtl of dp is
   signal dat_i : std_logic_vector(15 downto 0);
   --
   signal ir_out : std_logic_vector(15 downto 0);
   signal mdri_out : std_logic_vector(15 downto 0);
   signal rf_aq_out, rf_bq_out : std_logic_vector(15 downto 0);
   signal tr1_out, tr2_out, tr3_out, tr4_out : std_logic_vector(15 downto 0);
   signal pcin_mux_out : std_logic_vector(15 downto 0);
   signal pc_out : std_logic_vector(15 downto 0);
   signal spin_mux_out : std_logic_vector(15 downto 0);
   signal sp_out : std_logic_vector(15 downto 0);
   signal alua_mux_out : std_logic_vector(15 downto 0);
   signal alub_mux_out : std_logic_vector(15 downto 0);
   signal alu_result_out : std_logic_vector(15 downto 0);
   signal alu_c_out, alu_o_out : std_logic;
   signal sbin_mux_out : std_logic_vector(3 downto 0);
   signal shifter_result_out : std_logic_vector(15 downto 0);
   signal shifter_c_out, shifter_o_out : std_logic;
   signal asresult_mux_result_out : std_logic_vector(15 downto 0);
   signal asresult_mux_c_out, asresult_mux_o_out, 
          asresult_mux_s_out, asresult_mux_z_out : std_logic;  
   signal tr5_out : std_logic_vector(15 downto 0); 
   signal mdri_highlow_zse_high_out, mdri_highlow_zse_low_out : std_logic_vector(15 downto 0);    
   signal coszin_mux_out : std_logic_vector(3 downto 0);   
   signal flags_in : std_logic_vector(4 downto 0);
   signal adin_mux_out : std_logic_vector(15 downto 0);   
   signal flags_out : std_logic_vector(4 downto 0);
   signal intr_out : std_logic_vector(3 downto 0);
   signal intno_mux_out : std_logic_vector(15 downto 0); 
   signal marin_mux_out : std_logic_vector(15 downto 0);
   signal mar_out : std_logic_vector(15 downto 0);
   signal dfh_out : std_logic_vector(15 downto 0);
   signal mdroin_mux_out : std_logic_vector(15 downto 0);  
   signal mdro_out : std_logic_vector(15 downto 0);  
begin
   -- internal tristate...(optional)
   dat_i <= DAT_IO; --when mdro_oe = '0' else
            --(others => 'Z');
   --
   ir : process(CLK_I)
   -- ir is 16-bit register, connected to data bus. cpu store the instruction
   -- fetched from memory. The ir's controlled by fsm signal ``ir_ce". 
   begin
      if rising_edge(CLK_I) then
         if ir_ce = '1' then
            ir_out <= DAT_I;
         end if;   
      end if;
   end process;
 
   -- ir outputs goes to different components...
   -- ir(15..8) goes to fsm for evaluation of current instruction's opcode
   -- and subop 
   ir_high <= ir_out(15 downto 8);
 
   mdri : process(CLK_I)
   -- mdri is another 16-bit register connected to databus. cpu store data and
   -- immediate const from memory in the this register. it is controlled by 
   -- fsm signal ``mdri_ce"  
   begin
      if rising_edge(CLK_I) then
         if mdri_ce = '1' then
            mdri_out <= DAT_I;
         end if;   
      end if;
   end process;
 
   mdri_highlow_zse : process (mdri_hl_zse_sign, mdri_out)
   -- while execution of lbzx/lbsx instruction cpu needs to load byte.
   -- after loading byte data, data is either zero extended or sign extended.
   -- additionally there is no alignment restriction on byte data, it may either
   -- present on even address or odd address. byte data on even address appear on 
   -- upper 8 lines of databus and loaded into mdri(15..8) while byte data on odd
   -- address appear on lower 8 lines of databus and loaded into mdri(7..0).
   -- so we have to (sign/zero) extend both of them.     
   begin
      case mdri_hl_zse_sign is
         when '0' => 
            mdri_highlow_zse_high_out <= ext(mdri_out(15 downto 8), 16);
            mdri_highlow_zse_low_out <= ext(mdri_out(7 downto 0), 16);
         when '1' => 
            mdri_highlow_zse_high_out <= sxt(mdri_out(15 downto 8), 16);
            mdri_highlow_zse_low_out <= sxt(mdri_out(7 downto 0), 16);
         when others => 
            mdri_highlow_zse_high_out <= (others => '0');
            mdri_highlow_zse_low_out <= (others => '0');
      end case;
   end process;
 
   u1 : regfile 
   -- register file contain 16-bit, 16 general purpose registers...
   -- register file has two address inputs (4-bit wide), one connected to aadrin_mux_out,
   -- another connected to ir(3..0). it's write control is connected to fsm 
   -- signal `rf_adwe'. its data input port (16-bit wide) is connected to adin_mux's output.
   -- register file has two outputs (16-bit wide): aq, bq
   -- the data (register contents) can be read asynchronously from register file however,
   -- data writing is done synchronously.      
      port map(
         aadr => ir_out(7 downto 4),
         badr => ir_out(3 downto 0),
         ad => adin_mux_out,
         adwe => rf_adwe,
         clk => CLK_I,
         aq => rf_aq_out,
         bq => rf_bq_out
      );
 
   -- two 16-bit temporary registers tr1 and tr2 are connected to register file's
   -- aq and bq output respectively. 
   -- two 16-bit temporary registers tr3 and tr4 are connected to sign extended fields of ir:
   -- ir(10..0) and (ir(10..8)&ir(3..0)) respectively
   tr1 : process(CLK_I)
   begin
      if rising_edge(CLK_I) then
         tr1_out <= rf_aq_out;
      end if;
   end process;
 
   tr2 : process(CLK_I)
   begin
      if rising_edge(CLK_I) then
         tr2_out <= rf_bq_out;
      end if;
   end process;
 
   -- tr2(0) goes out of datapath (to fsm) for evalution
   tr20 <= tr2_out(0);
 
   tr3 : process(CLK_I)
   begin
      if rising_edge(CLK_I) then      
         tr3_out <= sxt(ir_out(10 downto 0), 16);
      end if;
   end process;
 
   tr4 : process(CLK_I) 
   begin
      if rising_edge(CLK_I) then
         tr4_out <= sxt(ir_out(10 downto 8) & ir_out(3 downto 0), 16);
      end if;
   end process;
 
 
   alua_mux : process(alua_mux_sel, pc_out, sp_out, tr1_out, tr2_out)
   -- alua_mux is connected to alu's input port `A' and used to select
   -- operand `A'. it is controlled by fsm signal alua_mux_sel. it has four 
   -- inputs which are connected to: pc output, sp output, tr1 output and 
   -- tr2 output. all the inputs and output are 16-bit wide.   
   begin
      case alua_mux_sel is
         when "00" =>
            alua_mux_out <= pc_out;
         when "01" =>
            alua_mux_out <= sp_out;
         when "10" =>
            alua_mux_out <= tr1_out;
         when "11" =>
            alua_mux_out <= tr2_out;
         when others => 
            alua_mux_out <= (others => '-');         
      end case;   
   end process;
 
   alub_mux : process(alub_mux_sel, tr2_out, tr3_out, tr4_out, mdri_out)
   -- alub_mux is connected to alu's input port `B' and used to select
   -- operand `B'. it is controlled by fsm signal alua_mux_sel. it has 8 inputs,
   -- which are connected to: tr2 output, constant `2', constant `1', constant `0'
   -- tr3, tr4, mdri's ouput and rest don't care.
   -- all the inputs and output are 16-bit wide.
   begin
      case alub_mux_sel is
         when "000" =>
            alub_mux_out <= tr2_out;
         when "001" =>
            alub_mux_out <= X"0002";
         when "010" =>
            alub_mux_out <= X"0001";
         when "011" =>
            alub_mux_out <= X"0000";
         when "100" =>
            alub_mux_out <= tr3_out;
         when "101" =>
            alub_mux_out <= tr4_out;
         when "110" =>
            alub_mux_out <= mdri_out;
         when others => 
            alub_mux_out <= (others => '-');    
      end case;
   end process;
 
   u2 : alu 
   -- Alu perform all the arithmetic and logic operations. it has two 16-bit wide data inputs
   -- `A' and `B', and 1-bit carry input. the alu is controled by fsm signal aopsel(2..0).
   -- the alu has a 16-bit wide output: result, as well as carry out and overflow out 
   -- signals (1-bit each). the carry out and overflow out signals are used 
   -- to update corresponding status flags in ``flags" register. 
   port map(   
      a => alua_mux_out, 
      b => alub_mux_out,
      opsel => aopsel(2 downto 0),
      c_in => flags_out(4), 
      result => alu_result_out,
      c_out => alu_c_out,
      ofl_out => alu_o_out
   );   
 
   sbin_mux : process(sbin_mux_sel, ir_out(3 downto 0), tr2_out(3 downto 0))
   -- sbin_mux is 4-bit wide 2-1 mux, its output connected to `B' input of 
   -- shifter. one of its input connected to tr2(3..0) while other is connected   
   -- to ir(3..0). this allow us to implement const as well as variable shift operations
   begin
      case sbin_mux_sel is
         when '0' =>
            sbin_mux_out <= tr2_out(3 downto 0);
         when '1' =>
            sbin_mux_out <= ir_out(3 downto 0);
         when others => 
            sbin_mux_out <= (others => '-');
      end case;
   end process;
 
   u3 : shifter
   -- Shifter perform 16-bit data shift and rotate operations. it has a 16-bit data input `A',
   -- the no. of time shift operation is performed, is determined by 4-bit `B' input. To support
   -- operations: ``rotate carry left" and ``rotate carry right", there is 1-bit carry input signal.
   -- like alu, shifter also has a 16-bit wide output: result, as well as carry out and overflow out 
   -- signals (1-bit each). the carry out and overflow out signals are used 
   -- to update corresponding status flags in ``flags" register.      
   port map
   (
      a => tr1_out,
      b => sbin_mux_out,
      c_in => flags_out(4),
      opsel => sopsel(2 downto 0),
      result => shifter_result_out,
      c_out => shifter_c_out,
      ofl_out => shifter_o_out
   );    
 
   asresult_mux : process(asresult_mux_sel, alu_result_out, alu_c_out,
                          alu_o_out, shifter_result_out, shifter_c_out,
                          shifter_o_out)
   -- The result, carry out, and overflow out signals, are comming out from both shifter
   -- and alu. The asresult mux, multiplexed these signals 
   begin
      case asresult_mux_sel is
         when '0' =>
            asresult_mux_result_out <= alu_result_out;
            asresult_mux_c_out <= alu_c_out;
            asresult_mux_o_out <= alu_o_out;
         when '1' =>
            asresult_mux_result_out <= shifter_result_out;
            asresult_mux_c_out <= shifter_c_out;
            asresult_mux_o_out <= shifter_o_out;
         when others =>
            asresult_mux_result_out <= (others => '-');
            asresult_mux_c_out <= '-';
            asresult_mux_o_out <= '-';                         
      end case;
   end process;
 
   -- from ``asresult_mux_result_out" signal, two more signals are generated:
   -- ``asresult_mux_s_out" and ``asresult_mux_z_out". these two signal update
   -- two status flags: sign and zero flags inside flags register, respactively.
 
   asresult_mux_s_out <= asresult_mux_result_out(15);
 
   asresult_mux_z_out <= '1' when asresult_mux_result_out = X"0000" else
                         '0';
 
   tr5: process(CLK_I)
   -- the multiplexed result, ``asresult_mux_result_out" goes to 16-bit temporary
   -- register.
   begin
      if rising_edge(CLK_I) then
         tr5_out <= asresult_mux_result_out;   
      end if;
   end process;
 
   coszin_mux : process(coszin_mux_sel, mdri_out(4 downto 1), asresult_mux_c_out,
                        asresult_mux_o_out, asresult_mux_s_out, asresult_mux_z_out)
   -- The PUSHF instruction, push the content of flags register into memory.
   -- corresponding POPF instruction, pop the content of memory word into flags register.
   -- therefore a 4-bit wide 2-1 mux is required for four status flags (C, O, S, Z) in 
   -- flags register, to either select mdri(4 downto 1) or flag outputs of asresult mux.   
   begin
      case coszin_mux_sel is
         when '0' =>
            coszin_mux_out <= asresult_mux_c_out & asresult_mux_o_out 
                              & asresult_mux_s_out & asresult_mux_z_out;
         when '1' =>
            coszin_mux_out <= mdri_out(4 downto 1);
         when others => 
            coszin_mux_out <= (others => '-');
      end case;   
   end process;
 
   -- flags register contain four status flags: carry, overflow, sign and zero. 
   -- there is also a system flag: int. flags register input consists of 
   -- coszin_mux_out & mdri(0).
 
   flags_in <= coszin_mux_out & mdri_out(0);
 
   u4 : flags 
   -- flags register has several control signals: async reset which is control by fsm 
   -- signal ``flags_rst" asserted on cpu reset, load control by fsm's ``flags_ce"
   -- signal, separate load controls for carry and interrupt flags which are controlled
   -- by ``flags_cfce" and ``flags_ifce" respectively. 
   -- three control signals ``flags_clc", ``flags_cmc" and ``flags_stc" are provided 
   -- for clearing/complementing/setting carry flag.
   -- two control signals ``flags_cli" and ``flags_sti" are provided 
   -- for clearing/setting int flag.               
   port map(
      Flags_in => flags_in,  
      CLK_in => CLK_I,     
      ResetAll_in => flags_rst,
      CE_in => flags_ce,
      CFCE_in => flags_cfce,
      IFCE_in => flags_ifce, 
      CLC_in => flags_clc,
      CMC_in => flags_cmc,
      STC_in => flags_stc,
      STI_in => flags_sti,
      CLI_in => flags_cli,
      Flags_out => flags_out
   );  
 
   -- when hardware interrupt occurs, cpu need to check the status of interrupt flag.
   -- so this signal goes to fsm  
   int_flag <= flags_out(0);
 
   adin_mux : process(adin_mux_sel, tr2_out, tr5_out, sp_out, mdri_out,
                      mdri_highlow_zse_high_out, mdri_highlow_zse_low_out)
   -- the adin_mux is 16-bit wide 8-1 mux connected to regfile ad input. it is 
   -- controlled by fsm's signal ``adin_mux_sel". its input are connected to outputs of
   -- tr2, tr5, sp, mdri and mdri_highlow_zse. the rest of inputs are donot care.  
   begin
      case adin_mux_sel is
         when "000" =>
            adin_mux_out <= tr2_out;
         when "001" =>
            adin_mux_out <= tr5_out;
         when "010" =>
            adin_mux_out <= sp_out;
         when "011" =>
            adin_mux_out <= mdri_out;
         when "100" => 
            adin_mux_out <= mdri_highlow_zse_high_out;
         when "101" =>
            adin_mux_out <= mdri_highlow_zse_low_out;
         when others =>
            adin_mux_out <= (others => '-');
      end case;
   end process;
 
   u5: fcmp 
   -- A flag comparator (fcmp) is used during execution of jcc and into instruction.
   -- it has two 4-bit inputs connected to status flags of flags register and 
   -- ir(7..4). it has 1-bit output. It check the status flags according condition 
   -- specified in ir(7..4), if condition holds, the output is asserted.
   -- this output goes to fsm for evaluation.    
   port map( 
      tttnField_in => ir_out(7 downto 4),       
      flags_in => flags_out(4 downto 1),
      result_out => jcc_ok
   );  
 
   intr: process(CLK_I)
   -- the intr is 4-bit register, connected to data bus(11..8) lines of databus.
   -- it is controled by fsm's signal ``intr_ce". it is used to store
   -- interrupt vector no. provided by the interrupting hardware. 
   begin
      if rising_edge(CLK_I) then
         if intr_ce = '1' then
            intr_out <= DAT_I(11 downto 8);
         end if;
      end if;
   end process;
 
   intno_mux : process(intno_mux_sel, ir_out(3 downto 0), intr_out)
   -- the intno_mux select the vector no. it is controlled by fsm's intno_mux_sel
   -- signal. first four inputs are tied to consts declared in ``dp_pkg", which are
   -- vector numbers of invaild opcode exception, alignment exception, 
   -- stack error exception and double fault respectively. 
   -- the other two are tied to outputs of ir(3..0)and intr. 
   -- the selected vector number is further zero extended and multiplied by 8. 
      variable t1 : std_logic_vector(3 downto 0);
      variable t2 : std_logic_vector(15 downto 0);
   begin
      case intno_mux_sel is
         when "000" =>
            t1 := invaild_inst_vec;
         when "001" =>
            t1 := align_err_vec;
         when "010" =>
            t1 := stack_err_vec;
         when "011" =>
            t1 := df_err_vec;
         when "100" =>
            t1 := ir_out(3 downto 0);
         when "101" =>
            t1 := intr_out;
         when others =>
            t1 := (others => '-');       
      end case;
      t2 := "000000000000" & t1;
      intno_mux_out <= t2(12 downto 0) & "000"; 
   end process;
 
   pcin_mux : process(pcin_mux_sel, alu_result_out, intno_mux_out, mdri_out)
   -- the pcin_mux is 16-bit wide mux, connected to pc input.
   -- it is controlled by fsm's signal ``pcin_mux_sel". one of its input is connected
   -- alu result output (this allows increament in pc after fetching instruction, place 
   -- effective address calculated during jmp and call), second to intno_mux output
   -- (for int, into and hardware interrupt) and third to mdri output (for ret and iret
   -- instructions)   
   begin
      case pcin_mux_sel is
         when "00" =>
            pcin_mux_out <= alu_result_out;
         when "01" =>
            pcin_mux_out <= intno_mux_out;
         when "10" =>
            pcin_mux_out <= mdri_out;
         when others =>
            pcin_mux_out <= (others => '-');
      end case;
   end process;
 
   pc : process(CLK_I, pc_pre) 
   -- the 16-bit pc register contain the address of for the next instruction 
   -- to be executed. it is advanced from one instruction boundry to the next
   -- in straight line code or it is moved ahead or backwards by a number of instructions
   -- when executing jmp, jcc, call, ret and iret instructions.
   -- on cpu reset, the pc preset to ``pc_preset_value".   
   begin
      if pc_pre = '1' then 
         pc_out <= pc_preset_value;
      elsif rising_edge(CLK_I) then
         if pc_ce = '1' then
            pc_out <= pcin_mux_out;
         end if; 
      end if;    
   end process;
 
   -- the pc may contain odd address, specially after ret or iret instruction.
   -- therefore lsb of pc output goes to fsm input.
   pc0 <= pc_out(0);
 
   spin_mux : process(spin_mux_sel, alu_result_out, mdri_out)
   -- the spin_mux is 16-bit wide 2-1 mux, connected to sp input.
   -- it is controlled by fsm's signal ``spin_mux_sel". one of its input is connected
   -- alu result output and other to mdri output.    
   begin
      case spin_mux_sel is
         when '0' =>
            spin_mux_out <= alu_result_out;
         when '1' =>
            spin_mux_out <= mdri_out;
         when others =>
            spin_mux_out <= (others => '-');
      end case;
   end process;
 
   sp : process(CLK_I, sp_pre) 
   -- sp is 16-bit register, it contain the address of ``top of stack"(TOS).
   -- when items (only 16-bit) are pushed on stack, cpu decreament the sp,
   -- and push the item of TOS. when an item is popped off the stack, the
   -- processor read the items from TOS, then increament the sp register.
   -- on procedure call, cpu automatically push pc and on return pops the TOS
   -- into pc. on interrupt/exception cpu automattically push flags and pc while
   -- on iret, cpu restore pc and flags 
   -- on stack error and double fault, sp preset to ``sp_preset_value"
   begin
      if sp_pre = '1' then
         sp_out <= sp_preset_value;
      elsif rising_edge(CLK_I) then
         if sp_ce = '1' then 
            sp_out <= spin_mux_out;
         end if;
      end if;
   end process;
 
   -- lsb of sp goes to fsm's input, for alignment checking.
   sp0 <= sp_out(0);
 
   dfh : process(CLK_I) 
   -- dfh is 16-bit register which used to temporary store the offending sp value,
   -- during stk err and df. it is controlled by fsm's signal: dfh_ce. 
   begin
      if rising_edge(CLK_I) then
         if dfh_ce = '1' then
            dfh_out <= sp_out;
         end if;
      end if;
   end process;
 
   marin_mux : process(marin_mux_sel, pc_out, sp_out, alu_result_out)
   -- marin_mux is 16-bit wide mux. it is controlled by fsm's signal marin_mux_sel.
   -- its inputs are connected to: pc, sp and alu reseult output 
   begin
      case marin_mux_sel is
         when "00" =>
            marin_mux_out <= pc_out;
         when "01" =>
            marin_mux_out <= alu_result_out;
         when "10" => 
            marin_mux_out <= sp_out;   
         when others =>
            marin_mux_out <= (others => '-');
      end case;   
   end process;
 
   mar : process(CLK_I)
   -- mar is 16-bit regiser, conected to address bus. it is controlled by fsm's signal
   -- ``mar_ce". any address is first loaded into mar and then goes to address bus.    
   begin       
      if rising_edge(CLK_I) then
         if mar_ce = '1' then
            mar_out <= marin_mux_out;
         end if;
      end if;   
   end process;
 
   mar0 <= mar_out(0);
 
   ADR_O <= mar_out;     
 
   mdroin_mux : process(mdroin_mux_sel, pc_out, tr1_out, flags_out, dfh_out, intno_mux_out)
   -- mdroin_mux is 16-bit wide mux. it is controlled by fsm's signal mdroin_mux_sel.
   -- its inputs are connected to: pc, tr1, zero extended flags output, (tr1(7..0)& X"00")  
   -- zero extended tr1(7..0), dfh output, intno_mux outputs are used in stk and df exception
   begin
      case mdroin_mux_sel is
         when "000" =>
            mdroin_mux_out <= pc_out;
         when "001" =>
            mdroin_mux_out <= tr1_out;
         when "010" =>
            mdroin_mux_out <= "00000000000" & flags_out;
         when "011" =>
            mdroin_mux_out <= dfh_out;
         when "100" =>
            mdroin_mux_out <= intno_mux_out;
         when "101" => 
            mdroin_mux_out <= tr1_out(7 downto 0) & X"00";
         when "110" =>
            mdroin_mux_out <= X"00" & tr1_out(7 downto 0);
         when others =>
            mdroin_mux_out <= (others => '-');
      end case;   
   end process;
 
   -- mdro is 16-bit register connected to databus, through tri-state buffer. it has for control 
   -- signals: mdro_ce for load control, second control: mdro_oe is tri-state buffer control.
   mdro : process(CLK_I)
   begin       
      if rising_edge(CLK_I) then
         if mdro_ce = '1' then 
            mdro_out <= mdroin_mux_out;
         end if;            
      end if;   
   end process;
 
   DAT_IO <= mdro_out when mdro_oe = '1' else
             (others => 'Z');
 
end rtl;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.