OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.74/] [rtl/] [w11a/] [pdp11_sequencer.vhd] - Diff between revs 30 and 34

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 30 Rev 34
Line 1... Line 1...
-- $Id: pdp11_sequencer.vhd 679 2015-05-13 17:38:46Z mueller $
-- $Id: pdp11_sequencer.vhd 708 2015-08-03 06:41:43Z mueller $
--
--
-- Copyright 2006-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
-- Copyright 2006-2015 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
--
--
-- This program is free software; you may redistribute and/or modify it under
-- This program is free software; you may redistribute and/or modify it under
-- the terms of the GNU General Public License as published by the Free
-- the terms of the GNU General Public License as published by the Free
Line 20... Line 20...
-- Target Devices: generic
-- Target Devices: generic
-- Tool versions:  ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
-- Tool versions:  ise 8.2-14.7; viv 2014.4; ghdl 0.18-0.31
--
--
-- Revision History: 
-- Revision History: 
-- Date         Rev Version  Comment
-- Date         Rev Version  Comment
 
-- 2015-08-02   708   1.6.5  BUGFIX: proper trap_mmu and trap_ysv handling
 
-- 2015-08-01   707   1.6.4  set dm_idone in s_(trap_10|op_trap); add dm_vfetch
 
-- 2015-07-19   702   1.6.3  add DM_STAT_SE, drop SNUM port
 
-- 2015-07-10   700   1.6.2  use c_cpurust_hbpt
 
-- 2015-06-26   695   1.6.1  add SNUM (state number) port
-- 2015-05-10   678   1.6    start/stop/suspend overhaul; reset overhaul
-- 2015-05-10   678   1.6    start/stop/suspend overhaul; reset overhaul
-- 2015-02-07   643   1.5.2  s_op_wait: load R0 in DSRC for DR emulation
-- 2015-02-07   643   1.5.2  s_op_wait: load R0 in DSRC for DR emulation
-- 2014-07-12   569   1.5.1  rename s_opg_div_zero -> s_opg_div_quit;
-- 2014-07-12   569   1.5.1  rename s_opg_div_zero -> s_opg_div_quit;
--                           use DP_STAT.div_quit; set munit_s_div_sr;
--                           use DP_STAT.div_quit; set munit_s_div_sr;
--                           BUGFIX: s_opg_div_sr: check for late div_quit
--                           BUGFIX: s_opg_div_sr: check for late div_quit
Line 95... Line 100...
    VM_CNTL : out vm_cntl_type;         -- virtual memory control port
    VM_CNTL : out vm_cntl_type;         -- virtual memory control port
    CP_STAT : out cp_stat_type;         -- console port status
    CP_STAT : out cp_stat_type;         -- console port status
    ESUSP_O : out slbit;                -- external suspend output
    ESUSP_O : out slbit;                -- external suspend output
    ESUSP_I : in slbit;                 -- external suspend input
    ESUSP_I : in slbit;                 -- external suspend input
    ITIMER : out slbit;                 -- instruction timer
    ITIMER : out slbit;                 -- instruction timer
    EBREAK : in slbit;                  -- execution break
    HBPT : in slbit;                    -- hardware bpt
    DBREAK : in slbit;                  -- data break
 
    IB_MREQ : in ib_mreq_type;          -- ibus request
    IB_MREQ : in ib_mreq_type;          -- ibus request
    IB_SRES : out ib_sres_type          -- ibus response    
    IB_SRES : out ib_sres_type;         -- ibus response    
 
    DM_STAT_SE : out dm_stat_se_type    -- debug and monitor status - sequencer
  );
  );
end pdp11_sequencer;
end pdp11_sequencer;
 
 
architecture syn of pdp11_sequencer is
architecture syn of pdp11_sequencer is
 
 
Line 315... Line 320...
  end process proc_state;
  end process proc_state;
 
 
  proc_next: process (R_STATE, R_STATUS, PSW, PC, CP_CNTL,
  proc_next: process (R_STATE, R_STATUS, PSW, PC, CP_CNTL,
                      ID_STAT, R_IDSTAT, IREG, VM_STAT, DP_STAT,
                      ID_STAT, R_IDSTAT, IREG, VM_STAT, DP_STAT,
                      R_CPUERR, R_VMSTAT, IB_MREQ, IBSEL_CPUERR,
                      R_CPUERR, R_VMSTAT, IB_MREQ, IBSEL_CPUERR,
                      INT_PRI, INT_VECT, ESUSP_I, EBREAK, DBREAK)
                      INT_PRI, INT_VECT, ESUSP_I, HBPT)
 
 
    variable nstate : state_type;
    variable nstate : state_type;
    variable nstatus : cpustat_type := cpustat_init;
    variable nstatus : cpustat_type := cpustat_init;
    variable ncpuerr : cpuerr_type := cpuerr_init;
    variable ncpuerr : cpuerr_type := cpuerr_init;
 
 
Line 340... Line 345...
    variable is_kmode : slbit := '0';        -- cmode is kernel mode
    variable is_kmode : slbit := '0';        -- cmode is kernel mode
    variable is_dstkstack1246 : slbit := '0'; -- dest is k-stack & mode= 1,2,4,6
    variable is_dstkstack1246 : slbit := '0'; -- dest is k-stack & mode= 1,2,4,6
 
 
    variable int_pending : slbit := '0';     -- an interrupt is pending
    variable int_pending : slbit := '0';     -- an interrupt is pending
 
 
 
    variable idm_idone   : slbit := '0';     -- idone  for dm_stat_se
 
    variable idm_vfetch  : slbit := '0';     -- vfetch for dm_stat_se
 
 
    alias SRCMOD : slv2 is IREG(11 downto 10); -- src register mode high
    alias SRCMOD : slv2 is IREG(11 downto 10); -- src register mode high
    alias SRCDEF : slbit is IREG(9);           -- src register mode defered
    alias SRCDEF : slbit is IREG(9);           -- src register mode defered
    alias SRCREG : slv3 is IREG(8 downto 6);   -- src register number
    alias SRCREG : slv3 is IREG(8 downto 6);   -- src register number
    alias DSTMODF : slv3 is IREG(5 downto 3);  -- dst register full mode
    alias DSTMODF : slv3 is IREG(5 downto 3);  -- dst register full mode
    alias DSTMOD : slv2 is IREG(5 downto 4);   -- dst register mode high
    alias DSTMOD : slv2 is IREG(5 downto 4);   -- dst register mode high
Line 422... Line 430...
      nstate  := nstate;                -- dummy to add driver (vivado)
      nstate  := nstate;                -- dummy to add driver (vivado)
      nstatus := nstatus;               -- "
      nstatus := nstatus;               -- "
      mok := false;
      mok := false;
      if VM_STAT.ack = '1' then
      if VM_STAT.ack = '1' then
        mok := true;
        mok := true;
        nstatus.trap_mmu := VM_STAT.trap_mmu;
        if VM_STAT.trap_mmu = '1' then  -- remember trap_mmu, may happen on any
 
          nstatus.trap_mmu := '1';      --   memory access of an instruction
 
        end if;
 
        if VM_STAT.trap_ysv = '1' then  -- remember trap_ysv (on any access)
        if R_CPUERR.ysv = '0' then      -- ysv trap when cpuerr not yet set
        if R_CPUERR.ysv = '0' then      -- ysv trap when cpuerr not yet set
          nstatus.trap_ysv := VM_STAT.trap_ysv;
            nstatus.trap_ysv := '1';
 
          end if;
        end if;
        end if;
      elsif VM_STAT.err='1' or VM_STAT.fail='1' then
      elsif VM_STAT.err='1' or VM_STAT.fail='1' then
        nstate := s_vmerr;
        nstate := s_vmerr;
      end if;
      end if;
    end procedure do_memcheck;
    end procedure do_memcheck;
Line 582... Line 594...
    int_pending := '0';
    int_pending := '0';
    if unsigned(INT_PRI) > unsigned(PSW.pri) then
    if unsigned(INT_PRI) > unsigned(PSW.pri) then
      int_pending := '1';
      int_pending := '1';
    end if;
    end if;
 
 
 
    idm_idone  := '0';
 
    idm_vfetch := '0';
 
 
    imemok := false;
    imemok := false;
 
 
    nmmumoni := mmu_moni_init;
    nmmumoni := mmu_moni_init;
    nmmumoni.pc := PC;
    nmmumoni.pc := PC;
 
 
Line 1295... Line 1310...
 
 
      when s_dstw_def_w =>
      when s_dstw_def_w =>
        nstate := s_dstw_def_w;
        nstate := s_dstw_def_w;
        do_memcheck(nstate, nstatus, imemok);
        do_memcheck(nstate, nstatus, imemok);
        if imemok then
        if imemok then
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                        -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
        end if;
        end if;
 
 
      when s_dstw_inc =>
      when s_dstw_inc =>
        ndpcntl.psr_ccwe := '1';
        ndpcntl.psr_ccwe := '1';
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;   -- VA = DDST
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_ddst;   -- VA = DDST
Line 1335... Line 1351...
          ndpcntl.gpr_we := '1';                   -- update DST reg
          ndpcntl.gpr_we := '1';                   -- update DST reg
        end if;
        end if;
        nstatus.do_gprwe := '0';
        nstatus.do_gprwe := '0';
        do_memcheck(nstate, nstatus, imemok);
        do_memcheck(nstate, nstatus, imemok);
        if imemok then
        if imemok then
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                        -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni); -- fetch next
        end if;
        end if;
 
 
      when s_dstw_incdef_w =>
      when s_dstw_incdef_w =>
        nstate := s_dstw_incdef_w;
        nstate := s_dstw_incdef_w;
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
Line 1508... Line 1525...
        end if;
        end if;
 
 
  -- instruction operate states -----------------------------------------------
  -- instruction operate states -----------------------------------------------
 
 
      when s_op_halt =>                 -- HALT
      when s_op_halt =>                 -- HALT
 
        idm_idone := '1';               -- instruction done
        if is_kmode = '1' then          -- if in kernel mode execute
        if is_kmode = '1' then          -- if in kernel mode execute
          nmmumoni.idone := '1';
          nmmumoni.idone := '1';
          nstatus.cpugo := '0';
          nstatus.cpugo := '0';
          nstatus.cpurust := c_cpurust_halt;
          nstatus.cpurust := c_cpurust_halt;
          nstate := s_idle;
          nstate := s_idle;
Line 1538... Line 1556...
          nstatus.cpuwait := '1';       -- if spinning here, signal with cpuwait
          nstatus.cpuwait := '1';       -- if spinning here, signal with cpuwait
          nstatus.itimer  := '1';       -- itimer will stay 1 during a WAIT
          nstatus.itimer  := '1';       -- itimer will stay 1 during a WAIT
       end if;
       end if;
 
 
      when s_op_trap =>                 -- traps
      when s_op_trap =>                 -- traps
 
        idm_idone := '1';                      -- instruction done
        lvector := "0000" & R_IDSTAT.trap_vec; -- vector
        lvector := "0000" & R_IDSTAT.trap_vec; -- vector
        do_start_int(nstate, ndpcntl, lvector);
        do_start_int(nstate, ndpcntl, lvector);
 
 
      when s_op_reset =>                -- RESET
      when s_op_reset =>                -- RESET
        if is_kmode = '1' then          -- if in kernel mode execute
        if is_kmode = '1' then          -- if in kernel mode execute
Line 1566... Line 1585...
        ndpcntl.dres_sel := c_dpath_res_vmdout;   -- DRES = VMDOUT
        ndpcntl.dres_sel := c_dpath_res_vmdout;   -- DRES = VMDOUT
        ndpcntl.gpr_adst := DSTREG;
        ndpcntl.gpr_adst := DSTREG;
        do_memcheck(nstate, nstatus, imemok);
        do_memcheck(nstate, nstatus, imemok);
        if imemok then
        if imemok then
          ndpcntl.gpr_we := '1';                  -- load R with (SP)+
          ndpcntl.gpr_we := '1';                  -- load R with (SP)+
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                       -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
        end if;
        end if;
 
 
      when s_op_spl =>                  -- SPL
      when s_op_spl =>                  -- SPL
        ndpcntl.dres_sel := c_dpath_res_ireg;    -- DRES = IREG
        ndpcntl.dres_sel := c_dpath_res_ireg;    -- DRES = IREG
        ndpcntl.psr_func := c_psr_func_wspl;
        ndpcntl.psr_func := c_psr_func_wspl;
 
        idm_idone := '1';                        -- instruction done
        if is_kmode = '1' then                   -- active only in kernel mode
        if is_kmode = '1' then                   -- active only in kernel mode
          ndpcntl.psr_we := '1';
          ndpcntl.psr_we := '1';
          nstate := s_ifetch;                    -- unconditionally fetch next
          nstate := s_ifetch;                    -- unconditionally fetch next
                                                 -- instruction like a 11/70
                                                 -- instruction like a 11/70
                                                 -- no interrupt recognition !
                                                 -- no interrupt recognition !
Line 1585... Line 1606...
 
 
      when s_op_mcc =>                  -- CLx/SEx
      when s_op_mcc =>                  -- CLx/SEx
        ndpcntl.dres_sel := c_dpath_res_ireg;    -- DRES = IREG
        ndpcntl.dres_sel := c_dpath_res_ireg;    -- DRES = IREG
        ndpcntl.psr_func := c_psr_func_wcc;
        ndpcntl.psr_func := c_psr_func_wcc;
        ndpcntl.psr_we := '1';
        ndpcntl.psr_we := '1';
        do_fork_next(nstate, nstatus, nmmumoni);
        idm_idone := '1';                        -- instruction done
 
        do_fork_next(nstate, nstatus, nmmumoni); -- fetch next
 
 
      when s_op_br =>                   -- BR
      when s_op_br =>                   -- BR
        nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
        nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC
        ndpcntl.ounit_asel := c_ounit_asel_pc;   -- OUNIT A = PC
        ndpcntl.ounit_asel := c_ounit_asel_pc;   -- OUNIT A = PC
Line 1615... Line 1637...
            brcond := PSW.cc(0);
            brcond := PSW.cc(0);
          when others => null;
          when others => null;
        end case;
        end case;
 
 
        ndpcntl.gpr_adst := c_gpr_pc;
        ndpcntl.gpr_adst := c_gpr_pc;
 
        idm_idone := '1';               -- instruction done
        if brcond = brcode(0) then      -- this coding creates redundant code
        if brcond = brcode(0) then      -- this coding creates redundant code
          ndpcntl.gpr_we := '1';        --   but synthesis optimizes this way !
          ndpcntl.gpr_we := '1';        --   but synthesis optimizes this way !
          do_fork_next(nstate, nstatus, nmmumoni);
          do_fork_next(nstate, nstatus, nmmumoni);
        else
        else
          do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni);
          do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni);
Line 1652... Line 1675...
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
        ndpcntl.dres_sel := c_dpath_res_vmdout;  -- DRES = VMDOUT
        ndpcntl.gpr_adst := c_gpr_r5;
        ndpcntl.gpr_adst := c_gpr_r5;
        do_memcheck(nstate, nstatus, imemok);
        do_memcheck(nstate, nstatus, imemok);
        if imemok then
        if imemok then
          ndpcntl.gpr_we := '1';                 -- load R5 with (sp)+
          ndpcntl.gpr_we := '1';                 -- load R5 with (sp)+
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                      -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
        end if;
        end if;
 
 
      when s_op_sob =>                  -- SOB (dec)
      when s_op_sob =>                  -- SOB (dec)
        -- comment fork_next_pref out (blog 2006-10-02) due to synthesis impact
        -- comment fork_next_pref out (blog 2006-10-02) due to synthesis impact
        --nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
        --nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
Line 1667... Line 1691...
 
 
        if DP_STAT.ccout_z = '0' then   -- if z=0 branch, if z=1 fall thru
        if DP_STAT.ccout_z = '0' then   -- if z=0 branch, if z=1 fall thru
          nstate := s_op_sob1;
          nstate := s_op_sob1;
        else
        else
          --do_fork_next_pref(nstate, ndpcntl, nvmcntl, nmmumoni);
          --do_fork_next_pref(nstate, ndpcntl, nvmcntl, nmmumoni);
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                  -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
        end if;
        end if;
 
 
      when s_op_sob1 =>                 -- SOB (br) 
      when s_op_sob1 =>                 -- SOB (br) 
        ndpcntl.ounit_asel := c_ounit_asel_pc;   -- OUNIT A = PC
        ndpcntl.ounit_asel := c_ounit_asel_pc;   -- OUNIT A = PC
        ndpcntl.ounit_bsel := c_ounit_bsel_ireg6;-- OUNIT B = IREG6
        ndpcntl.ounit_bsel := c_ounit_bsel_ireg6;-- OUNIT B = IREG6
        ndpcntl.ounit_opsub := '1';              -- OUNIT = A - B
        ndpcntl.ounit_opsub := '1';              -- OUNIT = A - B
        ndpcntl.dres_sel := c_dpath_res_ounit;   -- DRES = OUNIT
        ndpcntl.dres_sel := c_dpath_res_ounit;   -- DRES = OUNIT
        ndpcntl.gpr_adst := c_gpr_pc;
        ndpcntl.gpr_adst := c_gpr_pc;
        ndpcntl.gpr_we := '1';
        ndpcntl.gpr_we := '1';
        do_fork_next(nstate, nstatus, nmmumoni);
        idm_idone := '1';                        -- instruction done
 
        do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
 
 
      when s_opg_gen =>
      when s_opg_gen =>
        nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
        nvmcntl.dspace := '0';                   -- prepare do_fork_next_pref
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC
        ndpcntl.vmaddr_sel := c_dpath_vmaddr_pc; -- VA = PC
        ndpcntl.gpr_bytop := R_IDSTAT.is_bytop;
        ndpcntl.gpr_bytop := R_IDSTAT.is_bytop;
Line 1698... Line 1724...
        end if;
        end if;
 
 
        if R_IDSTAT.is_rmwop = '1' then
        if R_IDSTAT.is_rmwop = '1' then
          do_memwrite(nstate, nvmcntl, s_opg_gen_rmw_w, macc=>'1');
          do_memwrite(nstate, nvmcntl, s_opg_gen_rmw_w, macc=>'1');
        else
        else
 
          idm_idone := '1';                      -- instruction done
          if R_STATUS.prefdone = '1' then
          if R_STATUS.prefdone = '1' then
            nstatus.prefdone :='0';
            nstatus.prefdone :='0';
            nstate := s_ifetch_w;
            nstate := s_ifetch_w;
            do_memcheck(nstate, nstatus, imemok);
            do_memcheck(nstate, nstatus, imemok);
            if imemok then
            if imemok then
Line 1719... Line 1746...
 
 
      when s_opg_gen_rmw_w =>
      when s_opg_gen_rmw_w =>
        nstate := s_opg_gen_rmw_w;
        nstate := s_opg_gen_rmw_w;
        do_memcheck(nstate, nstatus, imemok);
        do_memcheck(nstate, nstatus, imemok);
        if imemok then
        if imemok then
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                      -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni); -- fetch next
        end if;
        end if;
 
 
      when s_opg_mul =>                 -- MUL (oper)
      when s_opg_mul =>                 -- MUL (oper)
        ndpcntl.dres_sel := R_IDSTAT.res_sel;   -- DRES = choice of idec
        ndpcntl.dres_sel := R_IDSTAT.res_sel;   -- DRES = choice of idec
        ndpcntl.gpr_adst := SRCREG;             -- write high order result
        ndpcntl.gpr_adst := SRCREG;             -- write high order result
Line 1739... Line 1767...
        ndpcntl.ounit_bsel := c_ounit_bsel_const;-- OUNIT B = const(0)
        ndpcntl.ounit_bsel := c_ounit_bsel_const;-- OUNIT B = const(0)
        ndpcntl.dres_sel := c_dpath_res_ounit;   -- DRES = OUNIT
        ndpcntl.dres_sel := c_dpath_res_ounit;   -- DRES = OUNIT
        ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg !
        ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg !
        ndpcntl.gpr_we := '1';
        ndpcntl.gpr_we := '1';
        ndpcntl.psr_ccwe := '1';
        ndpcntl.psr_ccwe := '1';
        do_fork_next(nstate, nstatus, nmmumoni);
        idm_idone := '1';                        -- instruction done
 
        do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
 
 
      when s_opg_div =>                 -- DIV (load dd_low)
      when s_opg_div =>                 -- DIV (load dd_low)
        ndpcntl.munit_s_div := '1';
        ndpcntl.munit_s_div := '1';
        ndpcntl.gpr_asrc := SRCREG(2 downto 1) & "1";-- read odd reg !
        ndpcntl.gpr_asrc := SRCREG(2 downto 1) & "1";-- read odd reg !
        ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc;
        ndpcntl.dtmp_sel := c_dpath_dtmp_dsrc;
Line 1793... Line 1822...
        ndpcntl.gpr_we := '1';
        ndpcntl.gpr_we := '1';
        ndpcntl.psr_ccwe := '1';
        ndpcntl.psr_ccwe := '1';
        if DP_STAT.div_quit = '1' then
        if DP_STAT.div_quit = '1' then
          nstate := s_opg_div_quit;
          nstate := s_opg_div_quit;
        else
        else
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                       -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
        end if;
        end if;
 
 
      when s_opg_div_quit =>            -- DIV (0/ or /0 or V=1 aborts)
      when s_opg_div_quit =>            -- DIV (0/ or /0 or V=1 aborts)
        ndpcntl.psr_ccwe := '1';
        ndpcntl.psr_ccwe := '1';
        do_fork_next(nstate, nstatus, nmmumoni);
        idm_idone := '1';               -- instruction done
 
        do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
 
 
      when s_opg_ash =>                 -- ASH (load shc)
      when s_opg_ash =>                 -- ASH (load shc)
        ndpcntl.munit_s_ash := '1';
        ndpcntl.munit_s_ash := '1';
        nstate := s_opg_ash_cn;
        nstate := s_opg_ash_cn;
 
 
Line 1820... Line 1851...
          ndpcntl.dsrc_we := '1';                 -- update DSRC
          ndpcntl.dsrc_we := '1';                 -- update DSRC
        else
        else
          ndpcntl.dres_sel := c_dpath_res_ounit;  -- DRES = OUNIT
          ndpcntl.dres_sel := c_dpath_res_ounit;  -- DRES = OUNIT
          ndpcntl.gpr_we := '1';
          ndpcntl.gpr_we := '1';
          ndpcntl.psr_ccwe := '1';
          ndpcntl.psr_ccwe := '1';
 
          idm_idone := '1';                       -- instruction done
          do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni);
          do_fork_next_pref(nstate, nstatus, ndpcntl, nvmcntl, nmmumoni);
        end if;
        end if;
 
 
      when s_opg_ashc =>                -- ASHC (load low, load shc)
      when s_opg_ashc =>                -- ASHC (load low, load shc)
        ndpcntl.gpr_asrc := SRCREG(2 downto 1) & "1";-- read odd reg !
        ndpcntl.gpr_asrc := SRCREG(2 downto 1) & "1";-- read odd reg !
Line 1855... Line 1887...
        ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A = DTMP
        ndpcntl.ounit_asel := c_ounit_asel_dtmp; -- OUNIT A = DTMP
        ndpcntl.ounit_bsel := c_ounit_bsel_const;-- OUNIT B = const(0)
        ndpcntl.ounit_bsel := c_ounit_bsel_const;-- OUNIT B = const(0)
        ndpcntl.dres_sel := c_dpath_res_ounit;   -- DRES = OUNIT
        ndpcntl.dres_sel := c_dpath_res_ounit;   -- DRES = OUNIT
        ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg !
        ndpcntl.gpr_adst := SRCREG(2 downto 1) & "1";-- write odd reg !
        ndpcntl.gpr_we := '1';
        ndpcntl.gpr_we := '1';
        do_fork_next(nstate, nstatus, nmmumoni);
        idm_idone := '1';                        -- instruction done
 
        do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
 
 
  -- dsta mode operations -----------------------------------------------------
  -- dsta mode operations -----------------------------------------------------
 
 
      when s_opa_jsr =>
      when s_opa_jsr =>
        ndpcntl.gpr_asrc := c_gpr_sp;              --                (for else)
        ndpcntl.gpr_asrc := c_gpr_sp;              --                (for else)
Line 1916... Line 1949...
        ndpcntl.ounit_asel := c_ounit_asel_ddst;   -- OUNIT A=DDST
        ndpcntl.ounit_asel := c_ounit_asel_ddst;   -- OUNIT A=DDST
        ndpcntl.ounit_bsel := c_ounit_bsel_const;  -- OUNIT B=const(0)
        ndpcntl.ounit_bsel := c_ounit_bsel_const;  -- OUNIT B=const(0)
        ndpcntl.dres_sel := c_dpath_res_ounit;     -- DRES = OUNIT
        ndpcntl.dres_sel := c_dpath_res_ounit;     -- DRES = OUNIT
        ndpcntl.gpr_adst := c_gpr_pc;
        ndpcntl.gpr_adst := c_gpr_pc;
        ndpcntl.gpr_we := '1';                     -- load PC with dsta
        ndpcntl.gpr_we := '1';                     -- load PC with dsta
        do_fork_next(nstate, nstatus, nmmumoni);
        idm_idone := '1';                          -- instruction done
 
        do_fork_next(nstate, nstatus, nmmumoni);   -- fetch next
 
 
      when s_opa_jmp =>
      when s_opa_jmp =>
        ndpcntl.ounit_asel := c_ounit_asel_ddst;   -- OUNIT A=DDST
        ndpcntl.ounit_asel := c_ounit_asel_ddst;   -- OUNIT A=DDST
        ndpcntl.ounit_bsel := c_ounit_bsel_const;  -- OUNIT B=const(0)
        ndpcntl.ounit_bsel := c_ounit_bsel_const;  -- OUNIT B=const(0)
        ndpcntl.dres_sel := c_dpath_res_ounit;     -- DRES = OUNIT
        ndpcntl.dres_sel := c_dpath_res_ounit;     -- DRES = OUNIT
        ndpcntl.gpr_adst := c_gpr_pc;
        ndpcntl.gpr_adst := c_gpr_pc;
        if R_IDSTAT.is_dstmode0 = '1' then
        if R_IDSTAT.is_dstmode0 = '1' then
          nstate := s_trap_10;                     -- trap 10 like 11/70
          nstate := s_trap_10;                     -- trap 10 like 11/70
        else
        else
          ndpcntl.gpr_we := '1';                   -- load PC with dsta
          ndpcntl.gpr_we := '1';                   -- load PC with dsta
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                        -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
        end if;
        end if;
 
 
      when s_opa_mtp =>
      when s_opa_mtp =>
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_opa_mtp_pop_w,
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_opa_mtp_pop_w,
                          nmmumoni, updt_sp=>'1');
                          nmmumoni, updt_sp=>'1');
Line 1963... Line 1998...
        ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B = const(0)
        ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B = const(0)
        ndpcntl.dres_sel := c_dpath_res_ounit;    -- DRES = OUNIT
        ndpcntl.dres_sel := c_dpath_res_ounit;    -- DRES = OUNIT
        ndpcntl.psr_ccwe := '1';                  -- set cc (from ounit too)
        ndpcntl.psr_ccwe := '1';                  -- set cc (from ounit too)
        ndpcntl.gpr_mode := PSW.pmode;            -- load reg in pmode
        ndpcntl.gpr_mode := PSW.pmode;            -- load reg in pmode
        ndpcntl.gpr_we := '1';
        ndpcntl.gpr_we := '1';
        do_fork_next(nstate, nstatus, nmmumoni);
        idm_idone := '1';                         -- instruction done
 
        do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
 
 
      when s_opa_mtp_mem =>
      when s_opa_mtp_mem =>
        ndpcntl.ounit_asel := c_ounit_asel_dtmp;  -- OUNIT A = DTMP
        ndpcntl.ounit_asel := c_ounit_asel_dtmp;  -- OUNIT A = DTMP
        ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B = const(0)
        ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B = const(0)
        ndpcntl.dres_sel := c_dpath_res_ounit;    -- DRES = OUNIT
        ndpcntl.dres_sel := c_dpath_res_ounit;    -- DRES = OUNIT
Line 1981... Line 2017...
 
 
      when s_opa_mtp_mem_w =>
      when s_opa_mtp_mem_w =>
        nstate := s_opa_mtp_mem_w;
        nstate := s_opa_mtp_mem_w;
        do_memcheck(nstate, nstatus, imemok);
        do_memcheck(nstate, nstatus, imemok);
        if imemok then
        if imemok then
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                       -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
        end if;
        end if;
 
 
      when s_opa_mfp_reg =>
      when s_opa_mfp_reg =>
        ndpcntl.gpr_mode := PSW.pmode;           -- fetch reg in pmode
        ndpcntl.gpr_mode := PSW.pmode;           -- fetch reg in pmode
        ndpcntl.ddst_sel := c_dpath_ddst_dst;    -- DDST = reg(dst)
        ndpcntl.ddst_sel := c_dpath_ddst_dst;    -- DDST = reg(dst)
Line 2042... Line 2079...
 
 
      when s_opa_mfp_push_w =>
      when s_opa_mfp_push_w =>
        nstate := s_opa_mfp_push_w;
        nstate := s_opa_mfp_push_w;
        do_memcheck(nstate, nstatus, imemok);
        do_memcheck(nstate, nstatus, imemok);
        if imemok then
        if imemok then
          do_fork_next(nstate, nstatus, nmmumoni);
          idm_idone := '1';                       -- instruction done
 
          do_fork_next(nstate, nstatus, nmmumoni);  -- fetch next
        end if;
        end if;
 
 
  -- trap and interrupt handling states ---------------------------------------
  -- trap and interrupt handling states ---------------------------------------
 
 
      when s_trap_4 =>
      when s_trap_4 =>
        lvector := "0000001";           -- vector (4)
        lvector := "0000001";           -- vector (4)
        do_start_int(nstate, ndpcntl, lvector);
        do_start_int(nstate, ndpcntl, lvector);
 
 
      when s_trap_10 =>
      when s_trap_10 =>
 
        idm_idone := '1';               -- instruction done
        lvector := "0000010";           -- vector (10)
        lvector := "0000010";           -- vector (10)
        do_start_int(nstate, ndpcntl, lvector);
        do_start_int(nstate, ndpcntl, lvector);
 
 
      when s_trap_disp =>
      when s_trap_disp =>
        if R_STATUS.trap_mmu = '1' then
        if R_STATUS.trap_mmu = '1' then
Line 2074... Line 2113...
      when s_int_ext =>
      when s_int_ext =>
        lvector := R_STATUS.intvect;    -- external vector
        lvector := R_STATUS.intvect;    -- external vector
        do_start_int(nstate, ndpcntl, lvector);
        do_start_int(nstate, ndpcntl, lvector);
 
 
      when s_int_getpc =>
      when s_int_getpc =>
 
        idm_vfetch := '1';              -- signal vfetch
        nvmcntl.mode := c_psw_kmode;    -- fetch PC from kernel D space
        nvmcntl.mode := c_psw_kmode;    -- fetch PC from kernel D space
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_int_getpc_w, nmmumoni);
        do_memread_srcinc(nstate, ndpcntl, nvmcntl, s_int_getpc_w, nmmumoni);
 
 
      when s_int_getpc_w =>
      when s_int_getpc_w =>
        nstate := s_int_getpc_w;
        nstate := s_int_getpc_w;
Line 2221... Line 2261...
        ndpcntl.ounit_asel := c_ounit_asel_ddst;  -- OUNIT A=DDST
        ndpcntl.ounit_asel := c_ounit_asel_ddst;  -- OUNIT A=DDST
        ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B=const (0)
        ndpcntl.ounit_bsel := c_ounit_bsel_const; -- OUNIT B=const (0)
        ndpcntl.dres_sel := c_dpath_res_ounit;    -- DRES = OUNIT
        ndpcntl.dres_sel := c_dpath_res_ounit;    -- DRES = OUNIT
        ndpcntl.gpr_adst := c_gpr_pc;
        ndpcntl.gpr_adst := c_gpr_pc;
        ndpcntl.gpr_we := '1';                    -- load new PC
        ndpcntl.gpr_we := '1';                    -- load new PC
 
        idm_idone := '1';                         -- instruction done
        if R_IDSTAT.op_rtt = '1' then             -- if RTT instruction
        if R_IDSTAT.op_rtt = '1' then             -- if RTT instruction
          nstate := s_ifetch;                       --   force fetch
          nstate := s_ifetch;                       --   force fetch
        else                                      -- otherwise RTI
        else                                      -- otherwise RTI
          do_fork_next(nstate, nstatus, nmmumoni);
          do_fork_next(nstate, nstatus, nmmumoni);
        end if;
        end if;
Line 2293... Line 2334...
      when others =>
      when others =>
        nstate := s_cpufail;             --!!! catch undefined states !!!
        nstate := s_cpufail;             --!!! catch undefined states !!!
 
 
    end case;
    end case;
 
 
    if DBREAK = '1' then                -- handle BREAK
    if HBPT = '1' then                  -- handle hardware bpt
 
      nstatus.cpurust := c_cpurust_hbpt;
      nstatus.suspint :='1';
      nstatus.suspint :='1';
    end if;
    end if;
    nstatus.suspext := ESUSP_I;
    nstatus.suspext := ESUSP_I;
 
 
    -- handle cpususp transitions 
    -- handle cpususp transitions 
Line 2329... Line 2371...
 
 
    nmmumoni.regnum := ndpcntl.gpr_adst;
    nmmumoni.regnum := ndpcntl.gpr_adst;
    nmmumoni.delta  := ndpcntl.ounit_const(3 downto 0);
    nmmumoni.delta  := ndpcntl.ounit_const(3 downto 0);
    MMU_MONI <= nmmumoni;
    MMU_MONI <= nmmumoni;
 
 
 
    DM_STAT_SE.istart <= nmmumoni.istart;
 
    DM_STAT_SE.idone  <= idm_idone;
 
    DM_STAT_SE.vfetch <= idm_vfetch;
 
 
  end process proc_next;
  end process proc_next;
 
 
  proc_cpstat : process (R_STATUS)
  proc_cpstat : process (R_STATUS)
  begin
  begin
    CP_STAT         <= cp_stat_init;
    CP_STAT         <= cp_stat_init;
Line 2347... Line 2393...
    CP_STAT.cpurust <= R_STATUS.cpurust;
    CP_STAT.cpurust <= R_STATUS.cpurust;
    CP_STAT.suspint <= R_STATUS.suspint;
    CP_STAT.suspint <= R_STATUS.suspint;
    CP_STAT.suspext <= R_STATUS.suspext;
    CP_STAT.suspext <= R_STATUS.suspext;
  end process proc_cpstat;
  end process proc_cpstat;
 
 
 
  proc_snum : process (R_STATE)
 
    variable isnum : slv8 := (others=>'0');
 
  begin
 
    isnum := (others=>'0');
 
    case R_STATE is
 
      -- STATE2SNUM mapper begin
 
      when s_idle           => isnum := x"00";
 
      when s_cp_regread     => isnum := x"01";
 
      when s_cp_rps         => isnum := x"02";
 
      when s_cp_memr_w      => isnum := x"03";
 
      when s_cp_memw_w      => isnum := x"04";
 
      when s_ifetch         => isnum := x"05";
 
      when s_ifetch_w       => isnum := x"06";
 
      when s_idecode        => isnum := x"07";
 
 
 
      when s_srcr_def       => isnum := x"08";
 
      when s_srcr_def_w     => isnum := x"09";
 
      when s_srcr_inc       => isnum := x"0a";
 
      when s_srcr_inc_w     => isnum := x"0b";
 
      when s_srcr_dec       => isnum := x"0c";
 
      when s_srcr_dec1      => isnum := x"0d";
 
      when s_srcr_ind       => isnum := x"0e";
 
      when s_srcr_ind1_w    => isnum := x"0f";
 
      when s_srcr_ind2      => isnum := x"10";
 
      when s_srcr_ind2_w    => isnum := x"11";
 
 
 
      when s_dstr_def       => isnum := x"12";
 
      when s_dstr_def_w     => isnum := x"13";
 
      when s_dstr_inc       => isnum := x"14";
 
      when s_dstr_inc_w     => isnum := x"15";
 
      when s_dstr_dec       => isnum := x"16";
 
      when s_dstr_dec1      => isnum := x"17";
 
      when s_dstr_ind       => isnum := x"18";
 
      when s_dstr_ind1_w    => isnum := x"19";
 
      when s_dstr_ind2      => isnum := x"1a";
 
      when s_dstr_ind2_w    => isnum := x"1b";
 
 
 
      when s_dstw_def       => isnum := x"1c";
 
      when s_dstw_def_w     => isnum := x"1d";
 
      when s_dstw_inc       => isnum := x"1e";
 
      when s_dstw_inc_w     => isnum := x"1f";
 
      when s_dstw_incdef_w  => isnum := x"20";
 
      when s_dstw_dec       => isnum := x"21";
 
      when s_dstw_dec1      => isnum := x"22";
 
      when s_dstw_ind       => isnum := x"23";
 
      when s_dstw_ind_w     => isnum := x"24";
 
      when s_dstw_def246    => isnum := x"25";
 
 
 
      when s_dsta_inc       => isnum := x"26";
 
      when s_dsta_incdef_w  => isnum := x"27";
 
      when s_dsta_dec       => isnum := x"28";
 
      when s_dsta_dec1      => isnum := x"29";
 
      when s_dsta_ind       => isnum := x"2a";
 
      when s_dsta_ind_w     => isnum := x"2b";
 
 
 
      when s_op_halt        => isnum := x"2c";
 
      when s_op_wait        => isnum := x"2d";
 
      when s_op_trap        => isnum := x"2e";
 
      when s_op_reset       => isnum := x"2f";
 
      when s_op_rts         => isnum := x"30";
 
      when s_op_rts_pop     => isnum := x"31";
 
      when s_op_rts_pop_w   => isnum := x"32";
 
      when s_op_spl         => isnum := x"33";
 
      when s_op_mcc         => isnum := x"34";
 
      when s_op_br          => isnum := x"35";
 
      when s_op_mark        => isnum := x"36";
 
      when s_op_mark1       => isnum := x"37";
 
      when s_op_mark_pop    => isnum := x"38";
 
      when s_op_mark_pop_w  => isnum := x"39";
 
      when s_op_sob         => isnum := x"3a";
 
      when s_op_sob1        => isnum := x"3b";
 
 
 
      when s_opg_gen        => isnum := x"3c";
 
      when s_opg_gen_rmw_w  => isnum := x"3d";
 
      when s_opg_mul        => isnum := x"3e";
 
      when s_opg_mul1       => isnum := x"3f";
 
      when s_opg_div        => isnum := x"40";
 
      when s_opg_div_cn     => isnum := x"41";
 
      when s_opg_div_cr     => isnum := x"42";
 
      when s_opg_div_sq     => isnum := x"43";
 
      when s_opg_div_sr     => isnum := x"44";
 
      when s_opg_div_quit   => isnum := x"45";
 
      when s_opg_ash        => isnum := x"46";
 
      when s_opg_ash_cn     => isnum := x"47";
 
      when s_opg_ashc       => isnum := x"48";
 
      when s_opg_ashc_cn    => isnum := x"49";
 
      when s_opg_ashc_wl    => isnum := x"4a";
 
 
 
      when s_opa_jsr        => isnum := x"4b";
 
      when s_opa_jsr1       => isnum := x"4c";
 
      when s_opa_jsr_push   => isnum := x"4d";
 
      when s_opa_jsr_push_w => isnum := x"4e";
 
      when s_opa_jsr2       => isnum := x"4f";
 
      when s_opa_jmp        => isnum := x"50";
 
      when s_opa_mtp        => isnum := x"51";
 
      when s_opa_mtp_pop_w  => isnum := x"52";
 
      when s_opa_mtp_reg    => isnum := x"53";
 
      when s_opa_mtp_mem    => isnum := x"54";
 
      when s_opa_mtp_mem_w  => isnum := x"55";
 
      when s_opa_mfp_reg    => isnum := x"56";
 
      when s_opa_mfp_mem    => isnum := x"57";
 
      when s_opa_mfp_mem_w  => isnum := x"58";
 
      when s_opa_mfp_dec    => isnum := x"59";
 
      when s_opa_mfp_push   => isnum := x"5a";
 
      when s_opa_mfp_push_w => isnum := x"5b";
 
 
 
      when s_trap_4         => isnum := x"5c";
 
      when s_trap_10        => isnum := x"5d";
 
      when s_trap_disp      => isnum := x"5e";
 
 
 
      when s_int_ext        => isnum := x"5f";
 
 
 
      when s_int_getpc      => isnum := x"60";
 
      when s_int_getpc_w    => isnum := x"61";
 
      when s_int_getps      => isnum := x"62";
 
      when s_int_getps_w    => isnum := x"63";
 
      when s_int_getsp      => isnum := x"64";
 
      when s_int_decsp      => isnum := x"65";
 
      when s_int_pushps     => isnum := x"66";
 
      when s_int_pushps_w   => isnum := x"67";
 
      when s_int_pushpc     => isnum := x"68";
 
      when s_int_pushpc_w   => isnum := x"69";
 
 
 
      when s_rti_getpc      => isnum := x"6a";
 
      when s_rti_getpc_w    => isnum := x"6b";
 
      when s_rti_getps      => isnum := x"6c";
 
      when s_rti_getps_w    => isnum := x"6d";
 
      when s_rti_newpc      => isnum := x"6e";
 
 
 
      when s_vmerr          => isnum := x"6f";
 
      when s_cpufail        => isnum := x"70";
 
 
 
      -- STATE2SNUM mapper end
 
      when others           => isnum := x"ff";
 
    end case;
 
    DM_STAT_SE.snum   <= isnum;
 
  end process proc_snum;
 
 
end syn;
end syn;
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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