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

Subversion Repositories hpc-16

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /hpc-16/trunk/impl0/rtl
    from Rev 14 to Rev 15
    Reverse comparison

Rev 14 → Rev 15

/vhdl/cpu.vhd
0,0 → 1,200
--------------------------------------------------------------
-- cpu.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: main microprocessor, instantiates the datapath and control unit
-- components and perform interconnection
--
-- dependency: cpu_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 work.cpu_pkg.all;
entity cpu 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;
RST_I : in std_logic;
ACK_I : in std_logic;
INTR_I : in std_logic;
--
SEL_O : out std_logic_vector(1 downto 0);
STB_O : out std_logic;
CYC_O : out std_logic;
WE_O : out std_logic;
--
INTA_CYC_O : out std_logic;
I_CYC_O : out std_logic;
C_CYC_O : out std_logic;
D_CYC_O : out std_logic;
--
DAT_IO : inout std_logic_vector(15 downto 0);
ADR_O : out std_logic_vector(15 downto 0)
);
end cpu;
 
architecture struct of cpu is
signal jcc_ok , int_flag , pc0 , sp0 , mar0 , tr20, intr_ce, ir_ce ,
mdri_ce, mdri_hl_zse_sign, rf_adwe, pc_pre, pc_ce,
spin_mux_sel, sp_pre, sp_ce, dfh_ce,
sbin_mux_sel, asresult_mux_sel, coszin_mux_sel,
flags_rst, flags_ce, flags_cfce, flags_ifce,
flags_clc, flags_cmc, flags_stc, flags_cli, flags_sti,
mar_ce, mdro_ce, mdro_oe : std_logic;
 
signal ir_high : std_logic_vector(7 downto 0);
 
signal intno_mux_sel, adin_mux_sel,
alub_mux_sel, aopsel, sopsel, mdroin_mux_sel : std_logic_vector(2 downto 0);
 
signal pcin_mux_sel, alua_mux_sel, marin_mux_sel : std_logic_vector(1 downto 0);
 
 
for control : con1 use entity work.con1(rtl);
 
begin
 
assert pc_preset_value(0) = '0' and sp_preset_value(0) = '0'
report "the preset values of sp and pc should be even"
severity failure;
 
control: con1
PORT MAP(
CLK_I => CLK_I,
RST_I => RST_I,
ACK_I => ACK_I,
INTR_I => INTR_I,
SEL_O => SEL_O,
STB_O => STB_O,
CYC_O => CYC_O,
WE_O => WE_O,
INTA_CYC_O => INTA_CYC_O,
C_CYC_O => C_CYC_O,
I_CYC_O => I_CYC_O,
D_CYC_O => D_CYC_O,
jcc_ok => jcc_ok,
int_flag => int_flag,
pc0 => pc0,
sp0 => sp0,
mar0 => mar0,
tr20 => tr20,
ir_high => ir_high,
intr_ce => intr_ce,
ir_ce => ir_ce,
mdri_ce => mdri_ce,
mdri_hl_zse_sign => mdri_hl_zse_sign,
intno_mux_sel => intno_mux_sel,
adin_mux_sel => adin_mux_sel,
rf_adwe => rf_adwe,
pcin_mux_sel => pcin_mux_sel,
pc_pre => pc_pre,
pc_ce => pc_ce,
spin_mux_sel => spin_mux_sel,
sp_pre => sp_pre,
sp_ce => sp_ce,
dfh_ce => dfh_ce,
alua_mux_sel => alua_mux_sel,
alub_mux_sel => alub_mux_sel,
aopsel => aopsel,
sopsel => sopsel,
sbin_mux_sel => sbin_mux_sel,
asresult_mux_sel => asresult_mux_sel,
coszin_mux_sel => coszin_mux_sel,
flags_rst => flags_rst,
flags_ce => flags_ce,
flags_cfce => flags_cfce,
flags_ifce => flags_ifce,
flags_clc => flags_clc,
flags_cmc => flags_cmc,
flags_stc => flags_stc,
flags_cli => flags_cli,
flags_sti => flags_sti,
marin_mux_sel => marin_mux_sel,
mar_ce => mar_ce,
mdroin_mux_sel => mdroin_mux_sel,
mdro_ce => mdro_ce,
mdro_oe => mdro_oe
);
 
datapath : dp
generic map
(
pc_preset_value => pc_preset_value,
sp_preset_value => sp_preset_value
)
PORT MAP(
CLK_I => CLK_I,
DAT_IO => DAT_IO,
ADR_O => ADR_O,
jcc_ok => jcc_ok,
int_flag => int_flag,
pc0 => pc0,
sp0 => sp0,
mar0 => mar0,
tr20 => tr20,
ir_high => ir_high,
intr_ce => intr_ce,
ir_ce => ir_ce,
mdri_ce => mdri_ce,
mdri_hl_zse_sign => mdri_hl_zse_sign,
intno_mux_sel => intno_mux_sel,
adin_mux_sel => adin_mux_sel,
rf_adwe => rf_adwe,
pcin_mux_sel => pcin_mux_sel,
pc_pre => pc_pre,
pc_ce => pc_ce,
spin_mux_sel => spin_mux_sel,
sp_pre => sp_pre,
sp_ce => sp_ce,
dfh_ce => dfh_ce,
alua_mux_sel => alua_mux_sel,
alub_mux_sel => alub_mux_sel,
aopsel => aopsel,
sopsel => sopsel,
sbin_mux_sel => sbin_mux_sel,
asresult_mux_sel => asresult_mux_sel,
coszin_mux_sel => coszin_mux_sel,
flags_rst => flags_rst,
flags_ce => flags_ce,
flags_cfce => flags_cfce,
flags_ifce => flags_ifce,
flags_clc => flags_clc,
flags_cmc => flags_cmc,
flags_stc => flags_stc,
flags_cli => flags_cli,
flags_sti => flags_sti,
marin_mux_sel => marin_mux_sel,
mar_ce => mar_ce,
mdroin_mux_sel => mdroin_mux_sel,
mdro_ce => mdro_ce,
mdro_oe => mdro_oe
);
end struct;
/vhdl/nontri/cpu.vhd
0,0 → 1,206
--------------------------------------------------------------
-- cpu.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: main microprocessor, instantiates the datapath and control unit
-- components and perform interconnection
--
-- dependency: cpu_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 --
-- --
------------------------------------------------------------------------------------
--------------------------------
-- --
-- non-tristate version --
-- --
--------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.cpu_pkg.all;
entity cpu 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;
RST_I : in std_logic;
ACK_I : in std_logic;
INTR_I : in std_logic;
--
SEL_O : out std_logic_vector(1 downto 0);
STB_O : out std_logic;
CYC_O : out std_logic;
WE_O : out std_logic;
--
INTA_CYC_O : out std_logic;
I_CYC_O : out std_logic;
C_CYC_O : out std_logic;
D_CYC_O : out std_logic;
--
DAT_I : in std_logic_vector(15 downto 0);
DAT_O : out std_logic_vector(15 downto 0);
--
ADR_O : out std_logic_vector(15 downto 0)
);
end cpu;
 
architecture struct of cpu is
signal jcc_ok , int_flag , pc0 , sp0 , mar0 , tr20, intr_ce, ir_ce ,
mdri_ce, mdri_hl_zse_sign, rf_adwe, pc_pre, pc_ce,
spin_mux_sel, sp_pre, sp_ce, dfh_ce,
sbin_mux_sel, asresult_mux_sel, coszin_mux_sel,
flags_rst, flags_ce, flags_cfce, flags_ifce,
flags_clc, flags_cmc, flags_stc, flags_cli, flags_sti,
mar_ce, mdro_ce : std_logic;
 
signal ir_high : std_logic_vector(7 downto 0);
 
signal intno_mux_sel, adin_mux_sel,
alub_mux_sel, aopsel, sopsel, mdroin_mux_sel : std_logic_vector(2 downto 0);
 
signal pcin_mux_sel, alua_mux_sel, marin_mux_sel : std_logic_vector(1 downto 0);
 
for control : con1 use entity work.con1(rtl);
 
begin
 
assert pc_preset_value(0) = '0' and sp_preset_value(0) = '0'
report "the preset values of sp and pc should be even"
severity failure;
 
control: con1
PORT MAP(
CLK_I => CLK_I,
RST_I => RST_I,
ACK_I => ACK_I,
INTR_I => INTR_I,
SEL_O => SEL_O,
STB_O => STB_O,
CYC_O => CYC_O,
WE_O => WE_O,
INTA_CYC_O => INTA_CYC_O,
C_CYC_O => C_CYC_O,
I_CYC_O => I_CYC_O,
D_CYC_O => D_CYC_O,
jcc_ok => jcc_ok,
int_flag => int_flag,
pc0 => pc0,
sp0 => sp0,
mar0 => mar0,
tr20 => tr20,
ir_high => ir_high,
intr_ce => intr_ce,
ir_ce => ir_ce,
mdri_ce => mdri_ce,
mdri_hl_zse_sign => mdri_hl_zse_sign,
intno_mux_sel => intno_mux_sel,
adin_mux_sel => adin_mux_sel,
rf_adwe => rf_adwe,
pcin_mux_sel => pcin_mux_sel,
pc_pre => pc_pre,
pc_ce => pc_ce,
spin_mux_sel => spin_mux_sel,
sp_pre => sp_pre,
sp_ce => sp_ce,
dfh_ce => dfh_ce,
alua_mux_sel => alua_mux_sel,
alub_mux_sel => alub_mux_sel,
aopsel => aopsel,
sopsel => sopsel,
sbin_mux_sel => sbin_mux_sel,
asresult_mux_sel => asresult_mux_sel,
coszin_mux_sel => coszin_mux_sel,
flags_rst => flags_rst,
flags_ce => flags_ce,
flags_cfce => flags_cfce,
flags_ifce => flags_ifce,
flags_clc => flags_clc,
flags_cmc => flags_cmc,
flags_stc => flags_stc,
flags_cli => flags_cli,
flags_sti => flags_sti,
marin_mux_sel => marin_mux_sel,
mar_ce => mar_ce,
mdroin_mux_sel => mdroin_mux_sel,
mdro_ce => mdro_ce
);
 
datapath : dp
generic map
(
pc_preset_value => pc_preset_value,
sp_preset_value => sp_preset_value
)
PORT MAP(
CLK_I => CLK_I,
DAT_I => DAT_I,
DAT_O => DAT_O,
ADR_O => ADR_O,
jcc_ok => jcc_ok,
int_flag => int_flag,
pc0 => pc0,
sp0 => sp0,
mar0 => mar0,
tr20 => tr20,
ir_high => ir_high,
intr_ce => intr_ce,
ir_ce => ir_ce,
mdri_ce => mdri_ce,
mdri_hl_zse_sign => mdri_hl_zse_sign,
intno_mux_sel => intno_mux_sel,
adin_mux_sel => adin_mux_sel,
rf_adwe => rf_adwe,
pcin_mux_sel => pcin_mux_sel,
pc_pre => pc_pre,
pc_ce => pc_ce,
spin_mux_sel => spin_mux_sel,
sp_pre => sp_pre,
sp_ce => sp_ce,
dfh_ce => dfh_ce,
alua_mux_sel => alua_mux_sel,
alub_mux_sel => alub_mux_sel,
aopsel => aopsel,
sopsel => sopsel,
sbin_mux_sel => sbin_mux_sel,
asresult_mux_sel => asresult_mux_sel,
coszin_mux_sel => coszin_mux_sel,
flags_rst => flags_rst,
flags_ce => flags_ce,
flags_cfce => flags_cfce,
flags_ifce => flags_ifce,
flags_clc => flags_clc,
flags_cmc => flags_cmc,
flags_stc => flags_stc,
flags_cli => flags_cli,
flags_sti => flags_sti,
marin_mux_sel => marin_mux_sel,
mar_ce => mar_ce,
mdroin_mux_sel => mdroin_mux_sel,
mdro_ce => mdro_ce
);
end struct;
/vhdl/nontri/con1.vhd
0,0 → 1,2107
--------------------------------------------------------------
-- con1.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: control unit of microprocessor
--
-- dependency: con_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 --
-- --
------------------------------------------------------------------------------------
--------------------------------
-- --
-- non-tristate version --
-- --
--------------------------------
 
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.con_pkg.all;
 
entity con1 is
port(
CLK_I : in std_logic;
RST_I : in std_logic;
ACK_I : in std_logic;
INTR_I : in std_logic;
--
SEL_O : out std_logic_vector(1 downto 0);
STB_O : out std_logic;
CYC_O : out std_logic;
WE_O : out std_logic;
INTA_CYC_O : out std_logic;
C_CYC_O : out std_logic;
I_CYC_O : out std_logic;
D_CYC_O : out std_logic;
--
jcc_ok : in std_logic;
int_flag : in std_logic;
pc0 : in std_logic;
sp0 : in std_logic;
mar0 : in std_logic;
tr20 : in std_logic;
ir_high : in std_logic_vector(7 downto 0);
--
intr_ce : out std_logic;
ir_ce : out std_logic;
mdri_ce : out std_logic;
mdri_hl_zse_sign : out std_logic;
intno_mux_sel : out std_logic_vector(2 downto 0);
adin_mux_sel : out std_logic_vector(2 downto 0);
rf_adwe : out std_logic;
pcin_mux_sel : out std_logic_vector(1 downto 0);
pc_pre : out std_logic;
pc_ce : out std_logic;
spin_mux_sel : out std_logic;
sp_pre : out std_logic;
sp_ce : out std_logic;
dfh_ce : out std_logic;
alua_mux_sel : out std_logic_vector(1 downto 0);
alub_mux_sel : out std_logic_vector(2 downto 0);
aopsel : out std_logic_vector(2 downto 0);
sopsel : out std_logic_vector(2 downto 0);
sbin_mux_sel : out std_logic;
asresult_mux_sel : out std_logic;
coszin_mux_sel : out std_logic;
flags_rst : out std_logic;
flags_ce : out std_logic;
flags_cfce : out std_logic;
flags_ifce : out std_logic;
flags_clc : out std_logic;
flags_cmc : out std_logic;
flags_stc : out std_logic;
flags_cli : out std_logic;
flags_sti : out std_logic;
marin_mux_sel : out std_logic_vector(1 downto 0);
mar_ce : out std_logic;
mdroin_mux_sel : out std_logic_vector(2 downto 0);
mdro_ce : out std_logic
);
end con1;
 
architecture rtl of con1 is
signal rst_sync : std_logic;
signal ack_sync : std_logic;
signal intr_sync : std_logic;
signal cur_state , nxt_state : state;
signal cur_ic : ic;
signal asopsel : std_logic_vector(3 downto 0);
signal rsync_stage0 : std_logic;
signal rsync_stage1 : std_logic;
 
signal isync_stage0 : std_logic;
signal isync_stage1 : std_logic;
signal isync_stage2 : std_logic;
signal isync : std_logic;
signal intr_sync_rst : std_logic;
begin
process(CLK_I)
begin
if rising_edge(CLK_I) then
rsync_stage0 <= RST_I;
rsync_stage1 <= rsync_stage0;
rst_sync <= rsync_stage1;
end if;
end process;
 
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
ack_sync <= '0';
elsif rising_edge(CLK_I)then
ack_sync <= ACK_I;
end if;
end process;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
isync_stage0 <= '0';
isync_stage1 <= '0';
isync_stage2 <= '0';
elsif rising_edge(CLK_I)then
isync_stage0 <= INTR_I;
isync_stage1 <= isync_stage0;
isync_stage2 <= isync_stage1;
end if;
end process;
isync <= isync_stage0 and isync_stage1 and not isync_stage2;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
intr_sync <= '0';
elsif rising_edge(CLK_I) then
if intr_sync_rst = '1' then
intr_sync <= '0';
elsif isync = '1' then
intr_sync <= '1';
end if;
end if;
end process;
 
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
cur_state <= reset;
elsif rising_edge(CLK_I) then
cur_state <= nxt_state;
end if;
end process;
decode:
cur_ic <= ic_mov_rn_rm when ir_high = mov_rn_rm else
ic_mov_sp_rm when ir_high = mov_sp_rm else
ic_mov_rn_sp when ir_high = mov_rn_sp else
ic_ld_rn_rb when ir_high = ld_rn_rb else
ic_ld_rn_rb_disp when ir_high = ld_rn_rb_disp else
ic_ld_rn_sp when ir_high = ld_rn_sp else
ic_ld_rn_sp_disp when ir_high = ld_rn_sp_disp else
ic_st_rn_rb when ir_high = st_rn_rb else
ic_st_rn_rb_disp when ir_high = st_rn_rb_disp else
ic_st_rn_sp when ir_high = st_rn_sp else
ic_st_rn_sp_disp when ir_high = st_rn_sp_disp else
ic_lbzx_rn_rb when ir_high = lbzx_rn_rb else
ic_lbzx_rn_rb_disp when ir_high = lbzx_rn_rb_disp else
ic_lbsx_rn_rb when ir_high = lbsx_rn_rb else
ic_lbsx_rn_rb_disp when ir_high = lbsx_rn_rb_disp else
ic_sb_rn_rb when ir_high = sb_rn_rb else
ic_sb_rn_rb_disp when ir_high = sb_rn_rb_disp else
ic_sing_dec when ir_high = sing_dec else
ic_sing_inc when ir_high = sing_inc else
ic_alur when ir_high(7 downto 3) = alur else
ic_shiftr when ir_high(7 downto 3) = shiftr else
ic_cmp_cmp when ir_high = cmp_cmp else
ic_cmp_tst when ir_high = cmp_tst else
ic_li_rn when ir_high = li_rn else
ic_li_sp when ir_high = li_sp else
ic_alui when ir_high(7 downto 3) = alui else
ic_shifti when ir_high(7 downto 3) = shifti else
ic_cmpi_cmp when ir_high = cmpi_cmp else
ic_cmpi_tst when ir_high = cmpi_tst else
ic_alusp_sub when ir_high = alusp_sub else
ic_alusp_add when ir_high = alusp_add else
ic_stk_pushr when ir_high = stk_pushr else
ic_stk_pushf when ir_high = stk_pushf else
ic_stk_popr when ir_high = stk_popr else
ic_stk_popf when ir_high = stk_popf else
ic_acall when ir_high = acall else
ic_lcall when ir_high = lcall else
ic_scall when ir_high(7 downto 3) = scall else
ic_ret when ir_high(7 downto 3) = ret else
ic_int when ir_high(7 downto 3) = int else
ic_into when ir_high(7 downto 3) = into else
ic_iret when ir_high(7 downto 3) = iret else
ic_ajmp when ir_high = ajmp else
ic_ljmp when ir_high = ljmp else
ic_sjmp when ir_high(7 downto 3) = sjmp else
ic_jcc when ir_high(7 downto 3) = jcc else
ic_fop_clc when ir_high = fop_clc else
ic_fop_stc when ir_high = fop_stc else
ic_fop_cmc when ir_high = fop_cmc else
ic_fop_cli when ir_high = fop_cli else
ic_fop_sti when ir_high = fop_sti else
ic_nop when ir_high(7 downto 3) = nop else
ic_hlt when ir_high(7 downto 3) = hlt else
ic_invalid;
 
process(cur_state, cur_ic, jcc_ok, int_flag, pc0, sp0, tr20, mar0, ir_high,
ack_sync, intr_sync, rst_sync)
begin
SEL_O <= "00";
STB_O <= '0';
CYC_O <= '0';
WE_O <= '0';
INTA_CYC_O <= '0';
C_CYC_O <= '0';
I_CYC_O <= '0';
D_CYC_O <= '0';
intr_ce <= '0';
ir_ce <= '0';
mdri_ce <= '0';
mdri_hl_zse_sign <= '0';
intno_mux_sel <= "000";
adin_mux_sel <= "000";
rf_adwe <= '0';
pcin_mux_sel <= "00";
pc_pre <= '0';
pc_ce <= '0';
spin_mux_sel <= '0';
sp_pre <= '0';
sp_ce <= '0';
alua_mux_sel <= "00";
alub_mux_sel <= "000";
sbin_mux_sel <= '0';
asopsel <= "0000";
coszin_mux_sel <= '0';
flags_rst <= '0';
flags_ce <= '0';
flags_cfce <= '0';
flags_ifce <= '0';
flags_clc <= '0';
flags_cmc <= '0';
flags_stc <= '0';
flags_cli <= '0';
flags_sti <= '0';
marin_mux_sel <= "00";
mar_ce <= '0';
dfh_ce <= '0';
mdroin_mux_sel <= "000";
mdro_ce <= '0';
intr_sync_rst <= '0';
case cur_state is
--//////////////////////////////////////
when reset =>
pc_pre <= '1';
flags_rst <= '1';
-- @new start
sp_pre <= '1';
-- @new end
if rst_sync = '0' then
nxt_state <= fetch0;
else
nxt_state <= reset;
end if;
--//////////////////////////////////////
when fetch0 =>
if pc0 = '0' then
-- mar = pc
marin_mux_sel <= marin_mux_sel_pc;
mar_ce <= '1';
-- pc += 2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= fetch1;
else
nxt_state <= align0;
end if;
--///////////////////////////////////////
when fetch1 =>
-- read instruction; note STB_O is one shot
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; I_CYC_O <= '1';
-- prepare ir
ir_ce <= '1';
--
nxt_state <= fetch2;
--///////////////////////////////////////
when fetch2 =>
if ack_sync = '1' then
-- read end
nxt_state <= exec0;
else
-- continue read & prepare ir
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; I_CYC_O <= '1';
ir_ce <= '1';
--
nxt_state <= fetch2;
end if;
--///////////////////////////////////////
when exec0 =>
case cur_ic is
----------------------------------------------
when ic_mov_rn_rm =>
-- rn = tr2
adin_mux_sel <= adin_mux_sel_tr2;
rf_adwe <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_mov_sp_rm =>
-- sp = (tr2 + 0)
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_mov_rn_sp =>
-- rn = sp
adin_mux_sel <= adin_mux_sel_sp;
rf_adwe <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_ld_rn_rb =>
if tr20 = '0' then
-- mar = tr2 + 0
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
nxt_state <= exec1;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp |
ic_st_rn_rb_disp | ic_st_rn_sp_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp |
ic_sb_rn_rb_disp | ic_li_rn |
ic_li_sp | ic_alui | ic_cmpi_cmp |
ic_cmpi_tst | ic_alusp_add | ic_alusp_sub =>
-- mar = pc
marin_mux_sel <= marin_mux_sel_pc;
mar_ce <= '1';
-- pc += 2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_ld_rn_sp =>
if sp0 = '0' then
-- mar = sp
marin_mux_sel <= marin_mux_sel_sp;
mar_ce <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_st_rn_rb =>
if tr20 = '0' then
-- mar = tr2 + 0
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--
nxt_state <= exec1;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_st_rn_sp =>
if sp0 = '0' then
-- mar = sp
marin_mux_sel <= marin_mux_sel_sp;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_lbzx_rn_rb | ic_lbsx_rn_rb =>
-- mar = tr2 + 0
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sb_rn_rb =>
-- mar = tr2 + 0
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
if tr20 = '0' then
-- mdro = tr1(7..0) & 0000_0000
mdroin_mux_sel <= mdroin_mux_sel_tr1_loweven;
else
-- mdro = 0000_0000 & tr1(7..0)
mdroin_mux_sel <= mdroin_mux_sel_tr1_lowodd;
end if;
mdro_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sing_inc =>
-- tr5 = tr1 + 1
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_1;
asopsel <= asopsel_add;
-- flags updated (except cf, if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sing_dec =>
-- tr5 = tr1 - 1
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_1;
asopsel <= asopsel_sub;
-- flags updated (except cf, if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_alur =>
-- tr5 = tr1 aluop tr2
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_tr2;
case ir_high(2 downto 0) is
when a_sub =>
asopsel <= asopsel_sub;
when a_add =>
asopsel <= asopsel_add;
when a_sbb =>
asopsel <= asopsel_sbb;
when a_adc =>
asopsel <= asopsel_adc;
when a_not =>
asopsel <= asopsel_not;
when a_and =>
asopsel <= asopsel_and;
when a_or =>
asopsel <= asopsel_or;
when a_xor =>
asopsel <= asopsel_xor;
when others =>
asopsel <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_shiftr =>
-- tr5 = tr1 shiftop tr2
sbin_mux_sel <= sbin_mux_sel_tr2;
case ir_high(2 downto 0) is
when s_sll =>
asopsel <= asopsel_sll;
when s_slr =>
asopsel <= asopsel_slr;
when s_sal =>
asopsel <= asopsel_sal;
when s_sar =>
asopsel <= asopsel_sar;
when s_rol =>
asopsel <= asopsel_rol;
when s_ror =>
asopsel <= asopsel_ror;
when s_rcl =>
asopsel <= asopsel_rcl;
when s_rcr =>
asopsel <= asopsel_rcr;
when others =>
asopsel <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_cmp_cmp =>
-- tr5 = tr1 - tr2
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_tr2;
asopsel <= asopsel_sub;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_cmp_tst =>
-- tr5 = tr1 and tr2
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_tr2;
asopsel <= asopsel_and;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_shifti =>
-- tr5 = tr1 shiftop ir(3..0)
sbin_mux_sel <= sbin_mux_sel_ir;
case ir_high(2 downto 0) is
when s_sll =>
asopsel <= asopsel_sll;
when s_slr =>
asopsel <= asopsel_slr;
when s_sal =>
asopsel <= asopsel_sal;
when s_sar =>
asopsel <= asopsel_sar;
when s_rol =>
asopsel <= asopsel_rol;
when s_ror =>
asopsel <= asopsel_ror;
when s_rcl =>
asopsel <= asopsel_rcl;
when s_rcr =>
asopsel <= asopsel_rcr;
when others =>
asopsel <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_stk_pushr =>
if sp0 = '0' then
--
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_stk_pushf =>
if sp0 = '0' then
--
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = flags
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_stk_popr | ic_stk_popf | ic_ret | ic_iret =>
if sp0 = '0' then
--
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_add;
-- sp = old sp + 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp
marin_mux_sel <= marin_mux_sel_sp;
mar_ce <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
---------------------------------------------
when ic_acall | ic_lcall | ic_scall =>
if sp0 = '0' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--
nxt_state <= exec1;
else
-- dfh =sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
---------------------------------------------
when ic_int =>
if sp0 = '0' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = flags
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--
nxt_state <= exec1;
else
-- mdro = intno
intno_mux_sel <= intno_mux_sel_ir;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
-- dfh =sp
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
---------------------------------------------
when ic_into =>
if sp0 = '0' then
if jcc_ok = '0' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = flags
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--
nxt_state <= exec1;
else
nxt_state <= int_chk;
end if;
else
-- mdro = intno
intno_mux_sel <= intno_mux_sel_ir;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
-- dfh =sp
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
---------------------------------------------
when ic_ajmp =>
-- pc = tr2
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
--------------------------------------------
when ic_ljmp =>
-- pc += tr2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr2;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
---------------------------------------------
when ic_sjmp =>
-- pc += tr3
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr3;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_jcc =>
if jcc_ok = '1' then
-- pc += tr4
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr4;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
else
null;
end if;
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_clc =>
flags_clc <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_cmc =>
flags_cmc <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_stc =>
flags_stc <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_cli =>
flags_cli <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_sti =>
flags_sti <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_nop =>
nxt_state <= int_chk;
----------------------------------------------
when ic_hlt =>
--flags_sti <= '1';
nxt_state <= halted;
----------------------------------------------
when ic_invalid =>
nxt_state <= invalid0;
----------------------------------------------
end case;
--///////////////////////////////////////
when exec1 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb | ic_ld_rn_sp | ic_stk_popr |
ic_stk_popf | ic_ret | ic_iret =>
-- read data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
---------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp |
ic_st_rn_rb_disp | ic_st_rn_sp_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp |
ic_sb_rn_rb_disp | ic_li_rn | ic_li_sp |
ic_alui | ic_cmpi_cmp | ic_cmpi_tst |
ic_alusp_add | ic_alusp_sub =>
-- read const word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_st_rn_rb | ic_st_rn_sp | ic_stk_pushr |
ic_stk_pushf | ic_acall | ic_lcall | ic_scall |
ic_int | ic_into =>
-- write data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
-------------------------------------------
when ic_lbzx_rn_rb | ic_lbsx_rn_rb =>
-- read data byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_sb_rn_rb =>
-- write data byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_sing_inc | ic_sing_dec | ic_alur |
ic_shiftr | ic_shifti =>
-- rn = tr5
adin_mux_sel <= adin_mux_sel_tr5;
rf_adwe <= '1';
--
nxt_state <= int_chk;
--------------------------------------------
when others =>
nxt_state <= halted; -- @new
end case;
--///////////////////////////////////////
when exec2 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb | ic_ld_rn_sp =>
if ack_sync = '1' then
-- rn = mdri
adin_mux_sel <= adin_mux_sel_mdri;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
-- try reading data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_ld_rn_rb_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_ld_rn_sp_disp =>
if ack_sync = '1' then
-- mar = sp + mdri
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_sp_disp =>
if ack_sync = '1' then
-- mar = sp + mdri
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_rb | ic_st_rn_sp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- try write data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lbzx_rn_rb =>
if ack_sync = '1' then
mdri_hl_zse_sign <= '0';
if mar0 = '0' then
adin_mux_sel <= adin_mux_sel_mdri_high;
else
adin_mux_sel <= adin_mux_sel_mdri_low;
end if;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
-- try read byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lbsx_rn_rb =>
if ack_sync = '1' then
mdri_hl_zse_sign <= '1';
if mar0 = '0' then
adin_mux_sel <= adin_mux_sel_mdri_high;
else
adin_mux_sel <= adin_mux_sel_mdri_low;
end if;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
-- try read byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_sb_rn_rb =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- try writing byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_sb_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_li_rn =>
if ack_sync = '1' then
-- rn = mdri
adin_mux_sel <= adin_mux_sel_mdri;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_li_sp =>
if ack_sync = '1' then
-- sp = mdri
spin_mux_sel <= spin_mux_sel_mdri;
sp_ce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alui =>
if ack_sync = '1' then
-- tr5 = tr1 aluop mdri
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_mdri;
case ir_high(2 downto 0) is
when a_sub =>
asopsel <= asopsel_sub;
when a_add =>
asopsel <= asopsel_add;
when a_sbb =>
asopsel <= asopsel_sbb;
when a_adc =>
asopsel <= asopsel_adc;
when a_and =>
asopsel <= asopsel_and;
when a_or =>
asopsel <= asopsel_or;
when a_xor =>
asopsel <= asopsel_xor;
when others =>
asopsel <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= exec3;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_cmpi_cmp =>
if ack_sync = '1' then
-- tr5 = tr1 - mdri
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_sub;
-- flags updated
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_cmpi_tst =>
if ack_sync = '1' then
-- tr5 = tr1 and mdri
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_and;
-- flags updated
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alusp_sub =>
if ack_sync = '1' then
-- sp = sp - mdri
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_sub;
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alusp_add =>
if ack_sync = '1' then
-- sp = sp + mdri
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_pushr | ic_stk_pushf =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_popr =>
if ack_sync = '1'then
-- rn = mdri
adin_mux_sel <= adin_mux_sel_mdri;
rf_adwe <= '1';
nxt_state <= int_chk;
else
-- try reading data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_popf =>
if ack_sync = '1' then
-- flags = mdri
coszin_mux_sel <= coszin_mux_sel_mdri;
flags_ce <= '1';
flags_cfce <= '1';
flags_ifce <= '1';
--
nxt_state <= int_chk;
else
-- try reading word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_acall =>
if ack_sync = '1' then
-- pc = tr2
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lcall =>
if ack_sync = '1' then
-- pc += tr2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr2;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
------------------------------------------
when ic_scall =>
if ack_sync = '1' then
-- pc += tr2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr3;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_ret =>
if ack_sync = '1' then
-- pc = mdri
pcin_mux_sel <= pcin_mux_sel_mdri;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
-- try reading data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
-------------------------------------------
when ic_int | ic_into =>
if ack_sync = '1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- mar = old sp -2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--
nxt_state <= exec3;
else
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- pc = mdri
pcin_mux_sel <= pcin_mux_sel_mdri;
pc_ce <= '1';
-- sp = old sp + 2
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_add;
spin_mux_sel <= spin_mux_sel_aluout;
-- mar = sp
marin_mux_sel <= marin_mux_sel_sp;
mar_ce <= '1';
--
nxt_state <= exec3;
else
-- try reading data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when others =>
nxt_state <= halted; -- @new
-------------------------------------------
end case;
--///////////////////////////////////////
when exec3 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp =>
if mar0 = '0' then
-- try reading data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec4;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_st_rn_rb_disp | ic_st_rn_sp_disp =>
if mar0 = '0' then
-- try writing data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp =>
-- try reading data byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_sb_rn_rb_disp =>
mdro_ce <= '1';
if mar0 = '0' then
mdroin_mux_sel <= mdroin_mux_sel_tr1_loweven;
else
mdroin_mux_sel <= mdroin_mux_sel_tr1_lowodd;
end if;
nxt_state <= exec4;
----------------------------------------------
when ic_alui =>
-- rn = tr5
adin_mux_sel <= adin_mux_sel_tr5;
rf_adwe <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_int | ic_into =>
-- try writting word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_iret =>
mdri_ce <= '1';
-- try reading word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when others =>
nxt_state <= halted; -- @new
----------------------------------------------
end case;
--///////////////////////////////////////
when exec4 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp =>
if ack_sync = '1' then
adin_mux_sel <= adin_mux_sel_mdri;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
-- read data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_st_rn_rb_disp | ic_st_rn_sp_disp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- write data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_lbzx_rn_rb_disp =>
if ack_sync = '1' then
mdri_hl_zse_sign <= '0';
if mar0 = '0' then
adin_mux_sel <= adin_mux_sel_mdri_high;
else
adin_mux_sel <= adin_mux_sel_mdri_low;
end if;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_lbsx_rn_rb_disp =>
if ack_sync = '1' then
mdri_hl_zse_sign <= '1';
if mar0 = '0' then
adin_mux_sel <= adin_mux_sel_mdri_high;
else
adin_mux_sel <= adin_mux_sel_mdri_low;
end if;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_sb_rn_rb_disp =>
-- write byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec5;
----------------------------------------------
when ic_int | ic_into =>
if ack_sync = '1' then
-- pc = ext(ir(3..0))
intno_mux_sel <= intno_mux_sel_ir;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
-- write word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- flags = mdri
coszin_mux_sel <= coszin_mux_sel_mdri;
flags_ce <= '1';
flags_cfce <= '1';
flags_ifce <= '1';
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
-- try reading word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when others =>
nxt_state <= halted; -- @new;
----------------------------------------------
end case;
--///////////////////////////////////////
when exec5 =>
case cur_ic is
when ic_sb_rn_rb_disp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- write byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec5;
end if;
when others =>
nxt_state <= halted; -- @new
end case;
--///////////////////////////////////////
when int_chk =>
if int_flag = '1' then
if intr_sync = '1' then
-- read vector no.
SEL_O <= "10"; STB_O <= '1'; CYC_O <= '1'; INTA_CYC_O <= '1';
-- prepare intr
intr_ce <= '1';
-- clear intr_sync
intr_sync_rst <= '1';
-- clear IF
flags_cli <= '1';
--
nxt_state <= int0;
else
nxt_state <= fetch0;
end if;
else
nxt_state <= fetch0;
end if;
--///////////////////////////////////////
when int0 =>
if ack_sync = '1' then
if sp0 = '0' then
-- mar = old sp - 2
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = flags
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--
nxt_state <= int1;
else
-- mdro = intno
intno_mux_sel <= intno_mux_sel_intr;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
else
-- try reading vector number
SEL_O <= "10"; STB_O <= '0'; CYC_O <= '1'; INTA_CYC_O <= '1';
--
intr_ce <= '1';
--
nxt_state <= int0;
end if;
--///////////////////////////////////////
when int1 =>
-- write flags
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= int2;
--///////////////////////////////////////
when int2 =>
if ack_sync = '1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--
nxt_state <= int3;
else
-- try writing data word (flags)
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= int2;
end if;
--///////////////////////////////////////
when int3 =>
-- write pc
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= int4;
--///////////////////////////////////////
when int4 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_intr;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= int4;
end if;
--///////////////////////////////////////
when invalid0 =>
if sp0= '0' then
-- push flag
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--
nxt_state <= invalid1;
else
-- in case of df
-- move the vector no to
intno_mux_sel <= intno_mux_sel_invalid;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
--
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
--///////////////////////////////////////
when invalid1 =>
-- write flags
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= invalid2;
--///////////////////////////////////////
when invalid2 =>
if ack_sync = '1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--
nxt_state <= invalid3;
else
-- try writing data word (flags)
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= invalid2;
end if;
--///////////////////////////////////////
when invalid3 =>
-- write pc
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= invalid4;
--///////////////////////////////////////
when invalid4 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_intr;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= invalid4;
end if;
--///////////////////////////////////////
when align0 =>
if sp0= '0' then
-- push flag
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--
nxt_state <= align1;
else
-- in case of df
-- move the vector no to
intno_mux_sel <= intno_mux_sel_align;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
--
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
--///////////////////////////////////////
when align1 =>
-- write flags
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= align2;
--///////////////////////////////////////
when align2 =>
if ack_sync = '1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--
nxt_state <= align3;
else
-- try writing data word (flags)
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= align2;
end if;
--///////////////////////////////////////
when align3 =>
-- write pc
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= align4;
--///////////////////////////////////////
when align4 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_intr;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= align4;
end if;
--///////////////////////////////////////
when stkerr0 =>
sp_pre <= '1';
nxt_state <= stkerr1;
--//////////////////////////////////////
when stkerr1 =>
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_dfh;
mdro_ce <= '1';
--
nxt_state <= stkerr2;
--///////////////////////////////////////
when stkerr2 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= stkerr3;
--///////////////////////////////////////
when stkerr3 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--
nxt_state <= stkerr4;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= stkerr3;
end if;
--///////////////////////////////////////
when stkerr4 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= stkerr5;
--///////////////////////////////////////
when stkerr5 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--
nxt_state <= stkerr6;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= stkerr5;
end if;
--///////////////////////////////////////
when stkerr6 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= stkerr7;
--///////////////////////////////////////
when stkerr7 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_df;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= stkerr7;
end if;
--///////////////////////////////////////
when df0 =>
sp_pre <= '1';
nxt_state <= df1;
--//////////////////////////////////////
when df1 =>
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
nxt_state <= df2;
--//////////////////////////////////////
when df2 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= df3;
--//////////////////////////////////////
when df3 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_dfh;
mdro_ce <= '1';
--
nxt_state <= df4;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= df3;
end if;
--///////////////////////////////////////
when df4 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= df5;
--///////////////////////////////////////
when df5 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--
nxt_state <= df6;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= df5;
end if;
--///////////////////////////////////////
when df6 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= df7;
--///////////////////////////////////////
when df7 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--
nxt_state <= df8;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= df7;
end if;
--///////////////////////////////////////
when df8 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
nxt_state <= df9;
--///////////////////////////////////////
when df9 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_df;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
--
nxt_state <= df9;
end if;
--///////////////////////////////////////
when halted =>
if int_flag = '1' and intr_sync = '1' then
-- read vector no.
SEL_O <= "10"; STB_O <= '1'; CYC_O <= '1'; INTA_CYC_O <= '1';
-- prepare intr
intr_ce <= '1';
--
nxt_state <= int0;
else
nxt_state <= halted;
end if;
--//////////////////////////////////////
end case;
end process;
-- since alu & shifter are not used simultanously...
aopsel <= asopsel(2 downto 0);
sopsel <= asopsel(2 downto 0);
asresult_mux_sel <= asopsel(3);
end rtl;
/vhdl/nontri/con1_arch_rtlfast.vhd
0,0 → 1,2175
--------------------------------------------------------------
-- con1_arch_rtlfast.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: "fast arch" of control unit of microprocessor
--
-- dependency: con1.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 --
-- --
------------------------------------------------------------------------------------
--------------------------------
-- --
-- non-tristate version --
-- --
--------------------------------
 
architecture rtlfast of con1 is
signal rst_sync : std_logic;
signal ack_sync : std_logic;
signal intr_sync : std_logic;
signal cur_state , nxt_state : state;
signal cur_ic : ic;
signal asopsel : std_logic_vector(3 downto 0);
signal rsync_stage0 : std_logic;
signal rsync_stage1 : std_logic;
 
signal isync_stage0 : std_logic;
signal isync_stage1 : std_logic;
signal isync_stage2 : std_logic;
signal isync : std_logic;
signal intr_sync_rst : std_logic;
 
signal intr_sync_rst_int : std_logic;
signal SEL_O_int : std_logic_vector(1 downto 0);
signal STB_O_int : std_logic;
signal CYC_O_int : std_logic;
signal WE_O_int : std_logic;
signal INTA_CYC_O_int : std_logic;
signal C_CYC_O_int : std_logic;
signal I_CYC_O_int : std_logic;
signal D_CYC_O_int : std_logic;
signal intr_ce_int : std_logic;
signal ir_ce_int : std_logic;
signal mdri_ce_int : std_logic;
signal mdri_hl_zse_sign_int : std_logic;
signal intno_mux_sel_int : std_logic_vector(2 downto 0);
signal adin_mux_sel_int : std_logic_vector(2 downto 0);
signal rf_adwe_int : std_logic;
signal pcin_mux_sel_int : std_logic_vector(1 downto 0);
signal pc_pre_int : std_logic;
signal pc_ce_int : std_logic;
signal spin_mux_sel_int : std_logic;
signal sp_pre_int : std_logic;
signal sp_ce_int : std_logic;
signal dfh_ce_int : std_logic;
signal alua_mux_sel_int : std_logic_vector(1 downto 0);
signal alub_mux_sel_int : std_logic_vector(2 downto 0);
signal asopsel_int : std_logic_vector(3 downto 0);
signal sbin_mux_sel_int : std_logic;
signal coszin_mux_sel_int : std_logic;
signal flags_rst_int : std_logic;
signal flags_ce_int : std_logic;
signal flags_cfce_int : std_logic;
signal flags_ifce_int : std_logic;
signal flags_clc_int : std_logic;
signal flags_cmc_int : std_logic;
signal flags_stc_int : std_logic;
signal flags_cli_int : std_logic;
signal flags_sti_int : std_logic;
signal marin_mux_sel_int : std_logic_vector(1 downto 0);
signal mar_ce_int : std_logic;
signal mdroin_mux_sel_int : std_logic_vector(2 downto 0);
signal mdro_ce_int : std_logic;
begin
process(CLK_I)
begin
if rising_edge(CLK_I) then
rsync_stage0 <= RST_I;
rsync_stage1 <= rsync_stage0;
rst_sync <= rsync_stage1;
end if;
end process;
 
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
ack_sync <= '0';
elsif rising_edge(CLK_I)then
ack_sync <= ACK_I;
end if;
end process;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
isync_stage0 <= '0';
isync_stage1 <= '0';
isync_stage2 <= '0';
elsif rising_edge(CLK_I)then
isync_stage0 <= INTR_I;
isync_stage1 <= isync_stage0;
isync_stage2 <= isync_stage1;
end if;
end process;
isync <= isync_stage0 and isync_stage1 and not isync_stage2;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
intr_sync <= '0';
elsif rising_edge(CLK_I) then
if intr_sync_rst = '1' then
intr_sync <= '0';
elsif isync = '1' then
intr_sync <= '1';
end if;
end if;
end process;
 
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
cur_state <= reset;
elsif rising_edge(CLK_I) then
cur_state <= nxt_state;
end if;
end process;
decode:
cur_ic <= ic_mov_rn_rm when ir_high = mov_rn_rm else
ic_mov_sp_rm when ir_high = mov_sp_rm else
ic_mov_rn_sp when ir_high = mov_rn_sp else
ic_ld_rn_rb when ir_high = ld_rn_rb else
ic_ld_rn_rb_disp when ir_high = ld_rn_rb_disp else
ic_ld_rn_sp when ir_high = ld_rn_sp else
ic_ld_rn_sp_disp when ir_high = ld_rn_sp_disp else
ic_st_rn_rb when ir_high = st_rn_rb else
ic_st_rn_rb_disp when ir_high = st_rn_rb_disp else
ic_st_rn_sp when ir_high = st_rn_sp else
ic_st_rn_sp_disp when ir_high = st_rn_sp_disp else
ic_lbzx_rn_rb when ir_high = lbzx_rn_rb else
ic_lbzx_rn_rb_disp when ir_high = lbzx_rn_rb_disp else
ic_lbsx_rn_rb when ir_high = lbsx_rn_rb else
ic_lbsx_rn_rb_disp when ir_high = lbsx_rn_rb_disp else
ic_sb_rn_rb when ir_high = sb_rn_rb else
ic_sb_rn_rb_disp when ir_high = sb_rn_rb_disp else
ic_sing_dec when ir_high = sing_dec else
ic_sing_inc when ir_high = sing_inc else
ic_alur when ir_high(7 downto 3) = alur else
ic_shiftr when ir_high(7 downto 3) = shiftr else
ic_cmp_cmp when ir_high = cmp_cmp else
ic_cmp_tst when ir_high = cmp_tst else
ic_li_rn when ir_high = li_rn else
ic_li_sp when ir_high = li_sp else
ic_alui when ir_high(7 downto 3) = alui else
ic_shifti when ir_high(7 downto 3) = shifti else
ic_cmpi_cmp when ir_high = cmpi_cmp else
ic_cmpi_tst when ir_high = cmpi_tst else
ic_alusp_sub when ir_high = alusp_sub else
ic_alusp_add when ir_high = alusp_add else
ic_stk_pushr when ir_high = stk_pushr else
ic_stk_pushf when ir_high = stk_pushf else
ic_stk_popr when ir_high = stk_popr else
ic_stk_popf when ir_high = stk_popf else
ic_acall when ir_high = acall else
ic_lcall when ir_high = lcall else
ic_scall when ir_high(7 downto 3) = scall else
ic_ret when ir_high(7 downto 3) = ret else
ic_int when ir_high(7 downto 3) = int else
ic_into when ir_high(7 downto 3) = into else
ic_iret when ir_high(7 downto 3) = iret else
ic_ajmp when ir_high = ajmp else
ic_ljmp when ir_high = ljmp else
ic_sjmp when ir_high(7 downto 3) = sjmp else
ic_jcc when ir_high(7 downto 3) = jcc else
ic_fop_clc when ir_high = fop_clc else
ic_fop_stc when ir_high = fop_stc else
ic_fop_cmc when ir_high = fop_cmc else
ic_fop_cli when ir_high = fop_cli else
ic_fop_sti when ir_high = fop_sti else
ic_nop when ir_high(7 downto 3) = nop else
ic_hlt when ir_high(7 downto 3) = hlt else
ic_invalid;
 
process(cur_state, cur_ic, jcc_ok, int_flag, pc0, sp0, tr20, mar0, ir_high,
ack_sync, intr_sync, rst_sync)
begin
SEL_O_int <= "00";
STB_O_int <= '0';
CYC_O_int <= '0';
WE_O_int <= '0';
INTA_CYC_O_int <= '0';
C_CYC_O_int <= '0';
I_CYC_O_int <= '0';
D_CYC_O_int <= '0';
intr_ce_int <= '0';
ir_ce_int <= '0';
mdri_ce_int <= '0';
mdri_hl_zse_sign_int <= '0';
intno_mux_sel_int <= "000";
adin_mux_sel_int <= "000";
rf_adwe_int <= '0';
pcin_mux_sel_int <= "00";
pc_pre_int <= '0';
pc_ce_int <= '0';
spin_mux_sel_int <= '0';
sp_pre_int <= '0';
sp_ce_int <= '0';
alua_mux_sel_int <= "00";
alub_mux_sel_int <= "000";
sbin_mux_sel_int <= '0';
asopsel_int <= "0000";
coszin_mux_sel_int <= '0';
flags_rst_int <= '0';
flags_ce_int <= '0';
flags_cfce_int <= '0';
flags_ifce_int <= '0';
flags_clc_int <= '0';
flags_cmc_int <= '0';
flags_stc_int <= '0';
flags_cli_int <= '0';
flags_sti_int <= '0';
marin_mux_sel_int <= "00";
mar_ce_int <= '0';
dfh_ce_int <= '0';
mdroin_mux_sel_int <= "000";
mdro_ce_int <= '0';
intr_sync_rst_int <= '0';
case cur_state is
--//////////////////////////////////////
when reset =>
pc_pre_int <= '1';
flags_rst_int <= '1';
-- @new start
sp_pre_int <= '1';
-- @new end
if rst_sync = '0' then
nxt_state <= fetch0;
else
nxt_state <= reset;
end if;
--//////////////////////////////////////
when fetch0 =>
if pc0 = '0' then
-- mar = pc
marin_mux_sel_int <= marin_mux_sel_pc;
mar_ce_int <= '1';
-- pc += 2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= fetch1;
else
nxt_state <= align0;
end if;
--///////////////////////////////////////
when fetch1 =>
-- read instruction; note STB_O_int is one shot
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; I_CYC_O_int <= '1';
-- prepare ir
ir_ce_int <= '1';
--
nxt_state <= fetch2;
--///////////////////////////////////////
when fetch2 =>
if ack_sync = '1' then
-- read end
nxt_state <= exec0;
else
-- continue read & prepare ir
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; I_CYC_O_int <= '1';
ir_ce_int <= '1';
--
nxt_state <= fetch2;
end if;
--///////////////////////////////////////
when exec0 =>
case cur_ic is
----------------------------------------------
when ic_mov_rn_rm =>
-- rn = tr2
adin_mux_sel_int <= adin_mux_sel_tr2;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_mov_sp_rm =>
-- sp = (tr2 + 0)
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_mov_rn_sp =>
-- rn = sp
adin_mux_sel_int <= adin_mux_sel_sp;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_ld_rn_rb =>
if tr20 = '0' then
-- mar = tr2 + 0
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
nxt_state <= exec1;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp |
ic_st_rn_rb_disp | ic_st_rn_sp_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp |
ic_sb_rn_rb_disp | ic_li_rn |
ic_li_sp | ic_alui | ic_cmpi_cmp |
ic_cmpi_tst | ic_alusp_add | ic_alusp_sub =>
-- mar = pc
marin_mux_sel_int <= marin_mux_sel_pc;
mar_ce_int <= '1';
-- pc += 2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_ld_rn_sp =>
if sp0 = '0' then
-- mar = sp
marin_mux_sel_int <= marin_mux_sel_sp;
mar_ce_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_st_rn_rb =>
if tr20 = '0' then
-- mar = tr2 + 0
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--
nxt_state <= exec1;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_st_rn_sp =>
if sp0 = '0' then
-- mar = sp
marin_mux_sel_int <= marin_mux_sel_sp;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_lbzx_rn_rb | ic_lbsx_rn_rb =>
-- mar = tr2 + 0
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sb_rn_rb =>
-- mar = tr2 + 0
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
if tr20 = '0' then
-- mdro = tr1(7..0) & 0000_0000
mdroin_mux_sel_int <= mdroin_mux_sel_tr1_loweven;
else
-- mdro = 0000_0000 & tr1(7..0)
mdroin_mux_sel_int <= mdroin_mux_sel_tr1_lowodd;
end if;
mdro_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sing_inc =>
-- tr5 = tr1 + 1
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_1;
asopsel_int <= asopsel_add;
-- flags updated (except cf, if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sing_dec =>
-- tr5 = tr1 - 1
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_1;
asopsel_int <= asopsel_sub;
-- flags updated (except cf, if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_alur =>
-- tr5 = tr1 aluop tr2
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_tr2;
case ir_high(2 downto 0) is
when a_sub =>
asopsel_int <= asopsel_sub;
when a_add =>
asopsel_int <= asopsel_add;
when a_sbb =>
asopsel_int <= asopsel_sbb;
when a_adc =>
asopsel_int <= asopsel_adc;
when a_not =>
asopsel_int <= asopsel_not;
when a_and =>
asopsel_int <= asopsel_and;
when a_or =>
asopsel_int <= asopsel_or;
when a_xor =>
asopsel_int <= asopsel_xor;
when others =>
asopsel_int <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_shiftr =>
-- tr5 = tr1 shiftop tr2
sbin_mux_sel_int <= sbin_mux_sel_tr2;
case ir_high(2 downto 0) is
when s_sll =>
asopsel_int <= asopsel_sll;
when s_slr =>
asopsel_int <= asopsel_slr;
when s_sal =>
asopsel_int <= asopsel_sal;
when s_sar =>
asopsel_int <= asopsel_sar;
when s_rol =>
asopsel_int <= asopsel_rol;
when s_ror =>
asopsel_int <= asopsel_ror;
when s_rcl =>
asopsel_int <= asopsel_rcl;
when s_rcr =>
asopsel_int <= asopsel_rcr;
when others =>
asopsel_int <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_cmp_cmp =>
-- tr5 = tr1 - tr2
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_tr2;
asopsel_int <= asopsel_sub;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_cmp_tst =>
-- tr5 = tr1 and tr2
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_tr2;
asopsel_int <= asopsel_and;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_shifti =>
-- tr5 = tr1 shiftop ir(3..0)
sbin_mux_sel_int <= sbin_mux_sel_ir;
case ir_high(2 downto 0) is
when s_sll =>
asopsel_int <= asopsel_sll;
when s_slr =>
asopsel_int <= asopsel_slr;
when s_sal =>
asopsel_int <= asopsel_sal;
when s_sar =>
asopsel_int <= asopsel_sar;
when s_rol =>
asopsel_int <= asopsel_rol;
when s_ror =>
asopsel_int <= asopsel_ror;
when s_rcl =>
asopsel_int <= asopsel_rcl;
when s_rcr =>
asopsel_int <= asopsel_rcr;
when others =>
asopsel_int <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_stk_pushr =>
if sp0 = '0' then
--
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_stk_pushf =>
if sp0 = '0' then
--
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = flags
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_stk_popr | ic_stk_popf | ic_ret | ic_iret =>
if sp0 = '0' then
--
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_add;
-- sp = old sp + 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp
marin_mux_sel_int <= marin_mux_sel_sp;
mar_ce_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
---------------------------------------------
when ic_acall | ic_lcall | ic_scall =>
if sp0 = '0' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--
nxt_state <= exec1;
else
-- dfh =sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
---------------------------------------------
when ic_int =>
if sp0 = '0' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = flags
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--
nxt_state <= exec1;
else
-- mdro = intno
intno_mux_sel_int <= intno_mux_sel_ir;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
-- dfh =sp
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
---------------------------------------------
when ic_into =>
if sp0 = '0' then
if jcc_ok = '0' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = flags
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--
nxt_state <= exec1;
else
nxt_state <= int_chk;
end if;
else
-- mdro = intno
intno_mux_sel_int <= intno_mux_sel_ir;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
-- dfh =sp
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
---------------------------------------------
when ic_ajmp =>
-- pc = tr2
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
--------------------------------------------
when ic_ljmp =>
-- pc += tr2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr2;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
---------------------------------------------
when ic_sjmp =>
-- pc += tr3
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr3;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_jcc =>
if jcc_ok = '1' then
-- pc += tr4
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr4;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
else
null;
end if;
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_clc =>
flags_clc_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_cmc =>
flags_cmc_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_stc =>
flags_stc_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_cli =>
flags_cli_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_sti =>
flags_sti_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_nop =>
nxt_state <= int_chk;
----------------------------------------------
when ic_hlt =>
--flags_sti_int <= '1';
nxt_state <= halted;
----------------------------------------------
when ic_invalid =>
nxt_state <= invalid0;
----------------------------------------------
end case;
--///////////////////////////////////////
when exec1 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb | ic_ld_rn_sp | ic_stk_popr |
ic_stk_popf | ic_ret | ic_iret =>
-- read data word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
---------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp |
ic_st_rn_rb_disp | ic_st_rn_sp_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp |
ic_sb_rn_rb_disp | ic_li_rn | ic_li_sp |
ic_alui | ic_cmpi_cmp | ic_cmpi_tst |
ic_alusp_add | ic_alusp_sub =>
-- read const word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_st_rn_rb | ic_st_rn_sp | ic_stk_pushr |
ic_stk_pushf | ic_acall | ic_lcall | ic_scall |
ic_int | ic_into =>
-- write data word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
-------------------------------------------
when ic_lbzx_rn_rb | ic_lbsx_rn_rb =>
-- read data byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_sb_rn_rb =>
-- write data byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_sing_inc | ic_sing_dec | ic_alur |
ic_shiftr | ic_shifti =>
-- rn = tr5
adin_mux_sel_int <= adin_mux_sel_tr5;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
--------------------------------------------
when others =>
nxt_state <= halted; -- @new
end case;
--///////////////////////////////////////
when exec2 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb | ic_ld_rn_sp =>
if ack_sync = '1' then
-- rn = mdri
adin_mux_sel_int <= adin_mux_sel_mdri;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_ld_rn_rb_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_ld_rn_sp_disp =>
if ack_sync = '1' then
-- mar = sp + mdri
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_sp_disp =>
if ack_sync = '1' then
-- mar = sp + mdri
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_rb | ic_st_rn_sp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- try write data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lbzx_rn_rb =>
if ack_sync = '1' then
mdri_hl_zse_sign_int <= '0';
if mar0 = '0' then
adin_mux_sel_int <= adin_mux_sel_mdri_high;
else
adin_mux_sel_int <= adin_mux_sel_mdri_low;
end if;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
-- try read byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lbsx_rn_rb =>
if ack_sync = '1' then
mdri_hl_zse_sign_int <= '1';
if mar0 = '0' then
adin_mux_sel_int <= adin_mux_sel_mdri_high;
else
adin_mux_sel_int <= adin_mux_sel_mdri_low;
end if;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
-- try read byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_sb_rn_rb =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- try writing byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_sb_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_li_rn =>
if ack_sync = '1' then
-- rn = mdri
adin_mux_sel_int <= adin_mux_sel_mdri;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_li_sp =>
if ack_sync = '1' then
-- sp = mdri
spin_mux_sel_int <= spin_mux_sel_mdri;
sp_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alui =>
if ack_sync = '1' then
-- tr5 = tr1 aluop mdri
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_mdri;
case ir_high(2 downto 0) is
when a_sub =>
asopsel_int <= asopsel_sub;
when a_add =>
asopsel_int <= asopsel_add;
when a_sbb =>
asopsel_int <= asopsel_sbb;
when a_adc =>
asopsel_int <= asopsel_adc;
when a_and =>
asopsel_int <= asopsel_and;
when a_or =>
asopsel_int <= asopsel_or;
when a_xor =>
asopsel_int <= asopsel_xor;
when others =>
asopsel_int <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_cmpi_cmp =>
if ack_sync = '1' then
-- tr5 = tr1 - mdri
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_sub;
-- flags updated
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_cmpi_tst =>
if ack_sync = '1' then
-- tr5 = tr1 and mdri
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_and;
-- flags updated
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alusp_sub =>
if ack_sync = '1' then
-- sp = sp - mdri
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_sub;
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alusp_add =>
if ack_sync = '1' then
-- sp = sp + mdri
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_pushr | ic_stk_pushf =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_popr =>
if ack_sync = '1'then
-- rn = mdri
adin_mux_sel_int <= adin_mux_sel_mdri;
rf_adwe_int <= '1';
nxt_state <= int_chk;
else
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_popf =>
if ack_sync = '1' then
-- flags = mdri
coszin_mux_sel_int <= coszin_mux_sel_mdri;
flags_ce_int <= '1';
flags_cfce_int <= '1';
flags_ifce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_acall =>
if ack_sync = '1' then
-- pc = tr2
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lcall =>
if ack_sync = '1' then
-- pc += tr2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr2;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
------------------------------------------
when ic_scall =>
if ack_sync = '1' then
-- pc += tr2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr3;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_ret =>
if ack_sync = '1' then
-- pc = mdri
pcin_mux_sel_int <= pcin_mux_sel_mdri;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
-------------------------------------------
when ic_int | ic_into =>
if ack_sync = '1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- mar = old sp -2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- pc = mdri
pcin_mux_sel_int <= pcin_mux_sel_mdri;
pc_ce_int <= '1';
-- sp = old sp + 2
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_add;
spin_mux_sel_int <= spin_mux_sel_aluout;
-- mar = sp
marin_mux_sel_int <= marin_mux_sel_sp;
mar_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when others =>
nxt_state <= halted; -- @new
-------------------------------------------
end case;
--///////////////////////////////////////
when exec3 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp =>
if mar0 = '0' then
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec4;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_st_rn_rb_disp | ic_st_rn_sp_disp =>
if mar0 = '0' then
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp =>
-- try reading data byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_sb_rn_rb_disp =>
mdro_ce_int <= '1';
if mar0 = '0' then
mdroin_mux_sel_int <= mdroin_mux_sel_tr1_loweven;
else
mdroin_mux_sel_int <= mdroin_mux_sel_tr1_lowodd;
end if;
nxt_state <= exec4;
----------------------------------------------
when ic_alui =>
-- rn = tr5
adin_mux_sel_int <= adin_mux_sel_tr5;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_int | ic_into =>
-- try writting word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_iret =>
mdri_ce_int <= '1';
-- try reading word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when others =>
nxt_state <= halted; -- @new
----------------------------------------------
end case;
--///////////////////////////////////////
when exec4 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp =>
if ack_sync = '1' then
adin_mux_sel_int <= adin_mux_sel_mdri;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
mdri_ce_int <= '1';
-- read data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_st_rn_rb_disp | ic_st_rn_sp_disp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- write data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_lbzx_rn_rb_disp =>
if ack_sync = '1' then
mdri_hl_zse_sign_int <= '0';
if mar0 = '0' then
adin_mux_sel_int <= adin_mux_sel_mdri_high;
else
adin_mux_sel_int <= adin_mux_sel_mdri_low;
end if;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
mdri_ce_int <= '1';
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_lbsx_rn_rb_disp =>
if ack_sync = '1' then
mdri_hl_zse_sign_int <= '1';
if mar0 = '0' then
adin_mux_sel_int <= adin_mux_sel_mdri_high;
else
adin_mux_sel_int <= adin_mux_sel_mdri_low;
end if;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
mdri_ce_int <= '1';
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_sb_rn_rb_disp =>
-- write byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec5;
----------------------------------------------
when ic_int | ic_into =>
if ack_sync = '1' then
-- pc = ext(ir(3..0))
intno_mux_sel_int <= intno_mux_sel_ir;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- write word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- flags = mdri
coszin_mux_sel_int <= coszin_mux_sel_mdri;
flags_ce_int <= '1';
flags_cfce_int <= '1';
flags_ifce_int <= '1';
--
nxt_state <= int_chk;
else
mdri_ce_int <= '1';
-- try reading word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when others =>
nxt_state <= halted; -- @new;
----------------------------------------------
end case;
--///////////////////////////////////////
when exec5 =>
case cur_ic is
when ic_sb_rn_rb_disp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
-- write byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec5;
end if;
when others =>
nxt_state <= halted; -- @new
end case;
--///////////////////////////////////////
when int_chk =>
if int_flag = '1' then
if intr_sync = '1' then
-- read vector no.
SEL_O_int <= "10"; STB_O_int <= '1'; CYC_O_int <= '1'; INTA_CYC_O_int <= '1';
-- prepare intr
intr_ce_int <= '1';
-- clear intr_sync
intr_sync_rst_int <= '1';
-- clear IF
flags_cli_int <= '1';
--
nxt_state <= int0;
else
nxt_state <= fetch0;
end if;
else
nxt_state <= fetch0;
end if;
--///////////////////////////////////////
when int0 =>
if ack_sync = '1' then
if sp0 = '0' then
-- mar = old sp - 2
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = flags
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--
nxt_state <= int1;
else
-- mdro = intno
intno_mux_sel_int <= intno_mux_sel_intr;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
else
-- try reading vector number
SEL_O_int <= "10"; STB_O_int <= '0'; CYC_O_int <= '1'; INTA_CYC_O_int <= '1';
--
intr_ce_int <= '1';
--
nxt_state <= int0;
end if;
--///////////////////////////////////////
when int1 =>
-- write flags
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= int2;
--///////////////////////////////////////
when int2 =>
if ack_sync = '1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--
nxt_state <= int3;
else
-- try writing data word (flags)
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= int2;
end if;
--///////////////////////////////////////
when int3 =>
-- write pc
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= int4;
--///////////////////////////////////////
when int4 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_intr;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= int4;
end if;
--///////////////////////////////////////
when invalid0 =>
if sp0= '0' then
-- push flag
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--
nxt_state <= invalid1;
else
-- in case of df
-- move the vector no to
intno_mux_sel_int <= intno_mux_sel_invalid;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
--
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
--///////////////////////////////////////
when invalid1 =>
-- write flags
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= invalid2;
--///////////////////////////////////////
when invalid2 =>
if ack_sync = '1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--
nxt_state <= invalid3;
else
-- try writing data word (flags)
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= invalid2;
end if;
--///////////////////////////////////////
when invalid3 =>
-- write pc
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= invalid4;
--///////////////////////////////////////
when invalid4 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_intr;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= invalid4;
end if;
--///////////////////////////////////////
when align0 =>
if sp0= '0' then
-- push flag
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--
nxt_state <= align1;
else
-- in case of df
-- move the vector no to
intno_mux_sel_int <= intno_mux_sel_align;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
--
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
--///////////////////////////////////////
when align1 =>
-- write flags
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= align2;
--///////////////////////////////////////
when align2 =>
if ack_sync = '1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--
nxt_state <= align3;
else
-- try writing data word (flags)
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= align2;
end if;
--///////////////////////////////////////
when align3 =>
-- write pc
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= align4;
--///////////////////////////////////////
when align4 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_intr;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= align4;
end if;
--///////////////////////////////////////
when stkerr0 =>
sp_pre_int <= '1';
nxt_state <= stkerr1;
--//////////////////////////////////////
when stkerr1 =>
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_dfh;
mdro_ce_int <= '1';
--
nxt_state <= stkerr2;
--///////////////////////////////////////
when stkerr2 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= stkerr3;
--///////////////////////////////////////
when stkerr3 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--
nxt_state <= stkerr4;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= stkerr3;
end if;
--///////////////////////////////////////
when stkerr4 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= stkerr5;
--///////////////////////////////////////
when stkerr5 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--
nxt_state <= stkerr6;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= stkerr5;
end if;
--///////////////////////////////////////
when stkerr6 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= stkerr7;
--///////////////////////////////////////
when stkerr7 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_df;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= stkerr7;
end if;
--///////////////////////////////////////
when df0 =>
sp_pre_int <= '1';
nxt_state <= df1;
--//////////////////////////////////////
when df1 =>
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
nxt_state <= df2;
--//////////////////////////////////////
when df2 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= df3;
--//////////////////////////////////////
when df3 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_dfh;
mdro_ce_int <= '1';
--
nxt_state <= df4;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= df3;
end if;
--///////////////////////////////////////
when df4 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= df5;
--///////////////////////////////////////
when df5 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--
nxt_state <= df6;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= df5;
end if;
--///////////////////////////////////////
when df6 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= df7;
--///////////////////////////////////////
when df7 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--
nxt_state <= df8;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= df7;
end if;
--///////////////////////////////////////
when df8 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
nxt_state <= df9;
--///////////////////////////////////////
when df9 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_df;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
--
nxt_state <= df9;
end if;
--///////////////////////////////////////
when halted =>
if int_flag = '1' and intr_sync = '1' then
-- read vector no.
SEL_O_int <= "10"; STB_O_int <= '1'; CYC_O_int <= '1'; INTA_CYC_O_int <= '1';
-- prepare intr
intr_ce_int <= '1';
--
nxt_state <= int0;
else
nxt_state <= halted;
end if;
--//////////////////////////////////////
end case;
end process;
 
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
SEL_O <= "00";
STB_O <= '0';
CYC_O <= '0';
WE_O <= '0';
INTA_CYC_O <= '0';
C_CYC_O <= '0';
I_CYC_O <= '0';
D_CYC_O <= '0';
intr_ce <= '0';
ir_ce <= '0';
mdri_ce <= '0';
mdri_hl_zse_sign <= '0';
intno_mux_sel <= "000";
adin_mux_sel <= "000";
rf_adwe <= '0';
pcin_mux_sel <= "00";
pc_pre <= '0';
pc_ce <= '0';
spin_mux_sel <= '0';
sp_pre <= '0';
sp_ce <= '0';
alua_mux_sel <= "00";
alub_mux_sel <= "000";
sbin_mux_sel <= '0';
asopsel <= "0000";
coszin_mux_sel <= '0';
flags_rst <= '0';
flags_ce <= '0';
flags_cfce <= '0';
flags_ifce <= '0';
flags_clc <= '0';
flags_cmc <= '0';
flags_stc <= '0';
flags_cli <= '0';
flags_sti <= '0';
marin_mux_sel <= "00";
mar_ce <= '0';
dfh_ce <= '0';
mdroin_mux_sel <= "000";
mdro_ce <= '0';
intr_sync_rst <= '0';
elsif rising_edge(CLK_I) then
SEL_O <= SEL_O_int ;
STB_O <= STB_O_int ;
CYC_O <= CYC_O_int ;
WE_O <= WE_O_int ;
INTA_CYC_O <= INTA_CYC_O_int ;
C_CYC_O <= C_CYC_O_int ;
I_CYC_O <= I_CYC_O_int ;
D_CYC_O <= D_CYC_O_int ;
intr_ce <= intr_ce_int ;
ir_ce <= ir_ce_int ;
mdri_ce <= mdri_ce_int ;
mdri_hl_zse_sign <= mdri_hl_zse_sign_int ;
intno_mux_sel <= intno_mux_sel_int ;
adin_mux_sel <= adin_mux_sel_int ;
rf_adwe <= rf_adwe_int ;
pcin_mux_sel <= pcin_mux_sel_int ;
pc_pre <= pc_pre_int ;
pc_ce <= pc_ce_int ;
spin_mux_sel <= spin_mux_sel_int ;
sp_pre <= sp_pre_int ;
sp_ce <= sp_ce_int ;
alua_mux_sel <= alua_mux_sel_int ;
alub_mux_sel <= alub_mux_sel_int ;
sbin_mux_sel <= sbin_mux_sel_int ;
asopsel <= asopsel_int ;
coszin_mux_sel <= coszin_mux_sel_int ;
flags_rst <= flags_rst_int ;
flags_ce <= flags_ce_int ;
flags_cfce <= flags_cfce_int ;
flags_ifce <= flags_ifce_int ;
flags_clc <= flags_clc_int ;
flags_cmc <= flags_cmc_int ;
flags_stc <= flags_stc_int ;
flags_cli <= flags_cli_int ;
flags_sti <= flags_sti_int ;
marin_mux_sel <= marin_mux_sel_int ;
mar_ce <= mar_ce_int ;
dfh_ce <= dfh_ce_int ;
mdroin_mux_sel <= mdroin_mux_sel_int ;
mdro_ce <= mdro_ce_int ;
intr_sync_rst <= intr_sync_rst_int ;
end if;
end process;
-- since alu & shifter are not used simultanously...
aopsel <= asopsel(2 downto 0);
sopsel <= asopsel(2 downto 0);
asresult_mux_sel <= asopsel(3);
end rtlfast;
/vhdl/nontri/dp.vhd
0,0 → 1,663
--------------------------------------------------------------
-- 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 --
-- --
------------------------------------------------------------------------------------
--------------------------------
-- --
-- non-tristate version --
-- --
--------------------------------
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_I: in std_logic_vector(15 downto 0);
DAT_O: out 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
);
end dp;
 
architecture rtl of dp is
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
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.
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_O <= mdro_out;
end rtl;
/vhdl/nontri/cpu_pkg.vhd
0,0 → 1,153
--------------------------------------------------------------
-- cpu_pkg.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: component declaration of datapath and control unit
--
-- dependency: dp.vhd, con1.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 --
-- --
------------------------------------------------------------------------------------
--------------------------------
-- --
-- non-tristate version --
-- --
--------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
 
package cpu_pkg is
COMPONENT con1
PORT(
CLK_I : IN std_logic;
RST_I : IN std_logic;
ACK_I : IN std_logic;
INTR_I : IN std_logic;
jcc_ok : IN std_logic;
int_flag : IN std_logic;
pc0 : IN std_logic;
sp0 : IN std_logic;
mar0 : IN std_logic;
tr20 : IN std_logic;
ir_high : IN std_logic_vector(7 downto 0);
SEL_O : OUT std_logic_vector(1 downto 0);
STB_O : OUT std_logic;
CYC_O : OUT std_logic;
WE_O : OUT std_logic;
INTA_CYC_O : OUT std_logic;
C_CYC_O : OUT std_logic;
I_CYC_O : OUT std_logic;
D_CYC_O : OUT std_logic;
intr_ce : OUT std_logic;
ir_ce : OUT std_logic;
mdri_ce : OUT std_logic;
mdri_hl_zse_sign : OUT std_logic;
intno_mux_sel : OUT std_logic_vector(2 downto 0);
adin_mux_sel : OUT std_logic_vector(2 downto 0);
rf_adwe : OUT std_logic;
pcin_mux_sel : OUT std_logic_vector(1 downto 0);
pc_pre : OUT std_logic;
pc_ce : OUT std_logic;
spin_mux_sel : OUT std_logic;
sp_pre : OUT std_logic;
sp_ce : OUT std_logic;
dfh_ce : OUT std_logic;
alua_mux_sel : OUT std_logic_vector(1 downto 0);
alub_mux_sel : OUT std_logic_vector(2 downto 0);
aopsel : OUT std_logic_vector(2 downto 0);
sopsel : OUT std_logic_vector(2 downto 0);
sbin_mux_sel : OUT std_logic;
asresult_mux_sel : OUT std_logic;
coszin_mux_sel : OUT std_logic;
flags_rst : OUT std_logic;
flags_ce : OUT std_logic;
flags_cfce : OUT std_logic;
flags_ifce : OUT std_logic;
flags_clc : OUT std_logic;
flags_cmc : OUT std_logic;
flags_stc : OUT std_logic;
flags_cli : OUT std_logic;
flags_sti : OUT std_logic;
marin_mux_sel : OUT std_logic_vector(1 downto 0);
mar_ce : OUT std_logic;
mdroin_mux_sel : OUT std_logic_vector(2 downto 0);
mdro_ce : OUT std_logic
);
END COMPONENT;
COMPONENT dp
generic
( pc_preset_value : std_logic_vector(15 downto 0) ;
sp_preset_value : std_logic_vector(15 downto 0)
);
PORT(
CLK_I : IN std_logic;
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 : IN 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;
DAT_I : IN std_logic_vector(15 downto 0);
DAT_O : OUT 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)
);
END COMPONENT;
end cpu_pkg;
/vhdl/con1.vhd
0,0 → 1,2174
--------------------------------------------------------------
-- con1.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: control unit of microprocessor
--
-- dependency: con_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 work.con_pkg.all;
 
entity con1 is
port(
CLK_I : in std_logic;
RST_I : in std_logic;
ACK_I : in std_logic;
INTR_I : in std_logic;
--
SEL_O : out std_logic_vector(1 downto 0);
STB_O : out std_logic;
CYC_O : out std_logic;
WE_O : out std_logic;
INTA_CYC_O : out std_logic;
C_CYC_O : out std_logic;
I_CYC_O : out std_logic;
D_CYC_O : out std_logic;
--
jcc_ok : in std_logic;
int_flag : in std_logic;
pc0 : in std_logic;
sp0 : in std_logic;
mar0 : in std_logic;
tr20 : in std_logic;
ir_high : in std_logic_vector(7 downto 0);
--
intr_ce : out std_logic;
ir_ce : out std_logic;
mdri_ce : out std_logic;
mdri_hl_zse_sign : out std_logic;
intno_mux_sel : out std_logic_vector(2 downto 0);
adin_mux_sel : out std_logic_vector(2 downto 0);
rf_adwe : out std_logic;
pcin_mux_sel : out std_logic_vector(1 downto 0);
pc_pre : out std_logic;
pc_ce : out std_logic;
spin_mux_sel : out std_logic;
sp_pre : out std_logic;
sp_ce : out std_logic;
dfh_ce : out std_logic;
alua_mux_sel : out std_logic_vector(1 downto 0);
alub_mux_sel : out std_logic_vector(2 downto 0);
aopsel : out std_logic_vector(2 downto 0);
sopsel : out std_logic_vector(2 downto 0);
sbin_mux_sel : out std_logic;
asresult_mux_sel : out std_logic;
coszin_mux_sel : out std_logic;
flags_rst : out std_logic;
flags_ce : out std_logic;
flags_cfce : out std_logic;
flags_ifce : out std_logic;
flags_clc : out std_logic;
flags_cmc : out std_logic;
flags_stc : out std_logic;
flags_cli : out std_logic;
flags_sti : out std_logic;
marin_mux_sel : out std_logic_vector(1 downto 0);
mar_ce : out std_logic;
mdroin_mux_sel : out std_logic_vector(2 downto 0);
mdro_ce : out std_logic;
mdro_oe : out std_logic
);
end con1;
architecture rtl of con1 is
signal rst_sync : std_logic;
signal ack_sync : std_logic;
signal intr_sync : std_logic;
signal cur_state , nxt_state : state;
signal cur_ic : ic;
signal asopsel : std_logic_vector(3 downto 0);
 
signal rsync_stage0 : std_logic;
signal rsync_stage1 : std_logic;
 
signal isync_stage0 : std_logic;
signal isync_stage1 : std_logic;
signal isync_stage2 : std_logic;
signal isync : std_logic;
signal intr_sync_rst : std_logic;
begin
process(CLK_I)
begin
if rising_edge(CLK_I) then
rsync_stage0 <= RST_I;
rsync_stage1 <= rsync_stage0;
rst_sync <= rsync_stage1;
end if;
end process;
 
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
ack_sync <= '0';
elsif rising_edge(CLK_I)then
ack_sync <= ACK_I;
end if;
end process;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
isync_stage0 <= '0';
isync_stage1 <= '0';
isync_stage2 <= '0';
elsif rising_edge(CLK_I)then
isync_stage0 <= INTR_I;
isync_stage1 <= isync_stage0;
isync_stage2 <= isync_stage1;
end if;
end process;
isync <= isync_stage0 and isync_stage1 and not isync_stage2;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
intr_sync <= '0';
elsif rising_edge(CLK_I) then
if intr_sync_rst = '1' then
intr_sync <= '0';
elsif isync = '1' then
intr_sync <= '1';
end if;
end if;
end process;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
cur_state <= reset;
elsif rising_edge(CLK_I) then
cur_state <= nxt_state;
end if;
end process;
decode:
cur_ic <= ic_mov_rn_rm when ir_high = mov_rn_rm else
ic_mov_sp_rm when ir_high = mov_sp_rm else
ic_mov_rn_sp when ir_high = mov_rn_sp else
ic_ld_rn_rb when ir_high = ld_rn_rb else
ic_ld_rn_rb_disp when ir_high = ld_rn_rb_disp else
ic_ld_rn_sp when ir_high = ld_rn_sp else
ic_ld_rn_sp_disp when ir_high = ld_rn_sp_disp else
ic_st_rn_rb when ir_high = st_rn_rb else
ic_st_rn_rb_disp when ir_high = st_rn_rb_disp else
ic_st_rn_sp when ir_high = st_rn_sp else
ic_st_rn_sp_disp when ir_high = st_rn_sp_disp else
ic_lbzx_rn_rb when ir_high = lbzx_rn_rb else
ic_lbzx_rn_rb_disp when ir_high = lbzx_rn_rb_disp else
ic_lbsx_rn_rb when ir_high = lbsx_rn_rb else
ic_lbsx_rn_rb_disp when ir_high = lbsx_rn_rb_disp else
ic_sb_rn_rb when ir_high = sb_rn_rb else
ic_sb_rn_rb_disp when ir_high = sb_rn_rb_disp else
ic_sing_dec when ir_high = sing_dec else
ic_sing_inc when ir_high = sing_inc else
ic_alur when ir_high(7 downto 3) = alur else
ic_shiftr when ir_high(7 downto 3) = shiftr else
ic_cmp_cmp when ir_high = cmp_cmp else
ic_cmp_tst when ir_high = cmp_tst else
ic_li_rn when ir_high = li_rn else
ic_li_sp when ir_high = li_sp else
ic_alui when ir_high(7 downto 3) = alui else
ic_shifti when ir_high(7 downto 3) = shifti else
ic_cmpi_cmp when ir_high = cmpi_cmp else
ic_cmpi_tst when ir_high = cmpi_tst else
ic_alusp_sub when ir_high = alusp_sub else
ic_alusp_add when ir_high = alusp_add else
ic_stk_pushr when ir_high = stk_pushr else
ic_stk_pushf when ir_high = stk_pushf else
ic_stk_popr when ir_high = stk_popr else
ic_stk_popf when ir_high = stk_popf else
ic_acall when ir_high = acall else
ic_lcall when ir_high = lcall else
ic_scall when ir_high(7 downto 3) = scall else
ic_ret when ir_high(7 downto 3) = ret else
ic_int when ir_high(7 downto 3) = int else
ic_into when ir_high(7 downto 3) = into else
ic_iret when ir_high(7 downto 3) = iret else
ic_ajmp when ir_high = ajmp else
ic_ljmp when ir_high = ljmp else
ic_sjmp when ir_high(7 downto 3) = sjmp else
ic_jcc when ir_high(7 downto 3) = jcc else
ic_fop_clc when ir_high = fop_clc else
ic_fop_stc when ir_high = fop_stc else
ic_fop_cmc when ir_high = fop_cmc else
ic_fop_cli when ir_high = fop_cli else
ic_fop_sti when ir_high = fop_sti else
ic_nop when ir_high(7 downto 3) = nop else
ic_hlt when ir_high(7 downto 3) = hlt else
ic_invalid;
 
process(cur_state, cur_ic, jcc_ok, int_flag, pc0, sp0, tr20, mar0, ir_high,
ack_sync, intr_sync, rst_sync)
begin
SEL_O <= "00";
STB_O <= '0';
CYC_O <= '0';
WE_O <= '0';
INTA_CYC_O <= '0';
C_CYC_O <= '0';
I_CYC_O <= '0';
D_CYC_O <= '0';
intr_ce <= '0';
ir_ce <= '0';
mdri_ce <= '0';
mdri_hl_zse_sign <= '0';
intno_mux_sel <= "000";
adin_mux_sel <= "000";
rf_adwe <= '0';
pcin_mux_sel <= "00";
pc_pre <= '0';
pc_ce <= '0';
spin_mux_sel <= '0';
sp_pre <= '0';
sp_ce <= '0';
alua_mux_sel <= "00";
alub_mux_sel <= "000";
sbin_mux_sel <= '0';
asopsel <= "0000";
coszin_mux_sel <= '0';
flags_rst <= '0';
flags_ce <= '0';
flags_cfce <= '0';
flags_ifce <= '0';
flags_clc <= '0';
flags_cmc <= '0';
flags_stc <= '0';
flags_cli <= '0';
flags_sti <= '0';
marin_mux_sel <= "00";
mar_ce <= '0';
dfh_ce <= '0';
mdroin_mux_sel <= "000";
mdro_ce <= '0';
mdro_oe <= '0';
intr_sync_rst <= '0';
case cur_state is
--//////////////////////////////////////
when reset =>
pc_pre <= '1';
flags_rst <= '1';
-- @new start
sp_pre <= '1';
-- @new end
if rst_sync = '0' then
nxt_state <= fetch0;
else
nxt_state <= reset;
end if;
--//////////////////////////////////////
when fetch0 =>
if pc0 = '0' then
-- mar = pc
marin_mux_sel <= marin_mux_sel_pc;
mar_ce <= '1';
-- pc += 2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= fetch1;
else
nxt_state <= align0;
end if;
--///////////////////////////////////////
when fetch1 =>
-- read instruction; note STB_O is one shot
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; I_CYC_O <= '1';
-- prepare ir
ir_ce <= '1';
--
nxt_state <= fetch2;
--///////////////////////////////////////
when fetch2 =>
if ack_sync = '1' then
-- read end
nxt_state <= exec0;
else
-- continue read & prepare ir
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; I_CYC_O <= '1';
ir_ce <= '1';
--
nxt_state <= fetch2;
end if;
--///////////////////////////////////////
when exec0 =>
case cur_ic is
----------------------------------------------
when ic_mov_rn_rm =>
-- rn = tr2
adin_mux_sel <= adin_mux_sel_tr2;
rf_adwe <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_mov_sp_rm =>
-- sp = (tr2 + 0)
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_mov_rn_sp =>
-- rn = sp
adin_mux_sel <= adin_mux_sel_sp;
rf_adwe <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_ld_rn_rb =>
if tr20 = '0' then
-- mar = tr2 + 0
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
nxt_state <= exec1;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp |
ic_st_rn_rb_disp | ic_st_rn_sp_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp |
ic_sb_rn_rb_disp | ic_li_rn |
ic_li_sp | ic_alui | ic_cmpi_cmp |
ic_cmpi_tst | ic_alusp_add | ic_alusp_sub =>
-- mar = pc
marin_mux_sel <= marin_mux_sel_pc;
mar_ce <= '1';
-- pc += 2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_ld_rn_sp =>
if sp0 = '0' then
-- mar = sp
marin_mux_sel <= marin_mux_sel_sp;
mar_ce <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_st_rn_rb =>
if tr20 = '0' then
-- mar = tr2 + 0
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec1;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_st_rn_sp =>
if sp0 = '0' then
-- mar = sp
marin_mux_sel <= marin_mux_sel_sp;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_lbzx_rn_rb | ic_lbsx_rn_rb =>
-- mar = tr2 + 0
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sb_rn_rb =>
-- mar = tr2 + 0
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
if tr20 = '0' then
-- mdro = tr1(7..0) & 0000_0000
mdroin_mux_sel <= mdroin_mux_sel_tr1_loweven;
else
-- mdro = 0000_0000 & tr1(7..0)
mdroin_mux_sel <= mdroin_mux_sel_tr1_lowodd;
end if;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sing_inc =>
-- tr5 = tr1 + 1
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_1;
asopsel <= asopsel_add;
-- flags updated (except cf, if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sing_dec =>
-- tr5 = tr1 - 1
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_1;
asopsel <= asopsel_sub;
-- flags updated (except cf, if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_alur =>
-- tr5 = tr1 aluop tr2
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_tr2;
case ir_high(2 downto 0) is
when a_sub =>
asopsel <= asopsel_sub;
when a_add =>
asopsel <= asopsel_add;
when a_sbb =>
asopsel <= asopsel_sbb;
when a_adc =>
asopsel <= asopsel_adc;
when a_not =>
asopsel <= asopsel_not;
when a_and =>
asopsel <= asopsel_and;
when a_or =>
asopsel <= asopsel_or;
when a_xor =>
asopsel <= asopsel_xor;
when others =>
asopsel <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_shiftr =>
-- tr5 = tr1 shiftop tr2
sbin_mux_sel <= sbin_mux_sel_tr2;
case ir_high(2 downto 0) is
when s_sll =>
asopsel <= asopsel_sll;
when s_slr =>
asopsel <= asopsel_slr;
when s_sal =>
asopsel <= asopsel_sal;
when s_sar =>
asopsel <= asopsel_sar;
when s_rol =>
asopsel <= asopsel_rol;
when s_ror =>
asopsel <= asopsel_ror;
when s_rcl =>
asopsel <= asopsel_rcl;
when s_rcr =>
asopsel <= asopsel_rcr;
when others =>
asopsel <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_cmp_cmp =>
-- tr5 = tr1 - tr2
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_tr2;
asopsel <= asopsel_sub;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_cmp_tst =>
-- tr5 = tr1 and tr2
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_tr2;
asopsel <= asopsel_and;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_shifti =>
-- tr5 = tr1 shiftop ir(3..0)
sbin_mux_sel <= sbin_mux_sel_ir;
case ir_high(2 downto 0) is
when s_sll =>
asopsel <= asopsel_sll;
when s_slr =>
asopsel <= asopsel_slr;
when s_sal =>
asopsel <= asopsel_sal;
when s_sar =>
asopsel <= asopsel_sar;
when s_rol =>
asopsel <= asopsel_rol;
when s_ror =>
asopsel <= asopsel_ror;
when s_rcl =>
asopsel <= asopsel_rcl;
when s_rcr =>
asopsel <= asopsel_rcr;
when others =>
asopsel <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_stk_pushr =>
if sp0 = '0' then
--
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_stk_pushf =>
if sp0 = '0' then
--
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = flags
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_stk_popr | ic_stk_popf | ic_ret | ic_iret =>
if sp0 = '0' then
--
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_add;
-- sp = old sp + 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp
marin_mux_sel <= marin_mux_sel_sp;
mar_ce <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
---------------------------------------------
when ic_acall | ic_lcall | ic_scall =>
if sp0 = '0' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec1;
else
-- dfh =sp
dfh_ce <= '1';
--
nxt_state <= stkerr0;
end if;
---------------------------------------------
when ic_int =>
if sp0 = '0' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = flags
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec1;
else
-- mdro = intno
intno_mux_sel <= intno_mux_sel_ir;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
--! mdro_oe <= '1';
-- dfh =sp
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
---------------------------------------------
when ic_into =>
if sp0 = '0' then
if jcc_ok = '0' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = flags
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec1;
else
nxt_state <= int_chk;
end if;
else
-- mdro = intno
intno_mux_sel <= intno_mux_sel_ir;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
--! mdro_oe <= '1';
-- dfh =sp
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
---------------------------------------------
when ic_ajmp =>
-- pc = tr2
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
--------------------------------------------
when ic_ljmp =>
-- pc += tr2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr2;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
---------------------------------------------
when ic_sjmp =>
-- pc += tr3
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr3;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_jcc =>
if jcc_ok = '1' then
-- pc += tr4
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr4;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
else
null;
end if;
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_clc =>
flags_clc <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_cmc =>
flags_cmc <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_stc =>
flags_stc <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_cli =>
flags_cli <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_sti =>
flags_sti <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_nop =>
nxt_state <= int_chk;
----------------------------------------------
when ic_hlt =>
--flags_sti <= '1';
nxt_state <= halted;
----------------------------------------------
when ic_invalid =>
nxt_state <= invalid0;
----------------------------------------------
end case;
--///////////////////////////////////////
when exec1 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb | ic_ld_rn_sp | ic_stk_popr |
ic_stk_popf | ic_ret | ic_iret =>
-- read data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
---------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp |
ic_st_rn_rb_disp | ic_st_rn_sp_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp |
ic_sb_rn_rb_disp | ic_li_rn | ic_li_sp |
ic_alui | ic_cmpi_cmp | ic_cmpi_tst |
ic_alusp_add | ic_alusp_sub =>
-- read const word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_st_rn_rb | ic_st_rn_sp | ic_stk_pushr |
ic_stk_pushf | ic_acall | ic_lcall | ic_scall |
ic_int | ic_into =>
mdro_oe <= '1';
-- write data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
-------------------------------------------
when ic_lbzx_rn_rb | ic_lbsx_rn_rb =>
-- read data byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_sb_rn_rb =>
mdro_oe <= '1';
-- write data byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_sing_inc | ic_sing_dec | ic_alur |
ic_shiftr | ic_shifti =>
-- rn = tr5
adin_mux_sel <= adin_mux_sel_tr5;
rf_adwe <= '1';
--
nxt_state <= int_chk;
--------------------------------------------
when others =>
nxt_state <= halted; -- @new
end case;
--///////////////////////////////////////
when exec2 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb | ic_ld_rn_sp =>
if ack_sync = '1' then
-- rn = mdri
adin_mux_sel <= adin_mux_sel_mdri;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
-- try reading data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_ld_rn_rb_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_ld_rn_sp_disp =>
if ack_sync = '1' then
-- mar = sp + mdri
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_sp_disp =>
if ack_sync = '1' then
-- mar = sp + mdri
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- mdro = tr1
mdroin_mux_sel <= mdroin_mux_sel_tr1;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_rb | ic_st_rn_sp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- try write data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lbzx_rn_rb =>
if ack_sync = '1' then
mdri_hl_zse_sign <= '0';
if mar0 = '0' then
adin_mux_sel <= adin_mux_sel_mdri_high;
else
adin_mux_sel <= adin_mux_sel_mdri_low;
end if;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
-- try read byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lbsx_rn_rb =>
if ack_sync = '1' then
mdri_hl_zse_sign <= '1';
if mar0 = '0' then
adin_mux_sel <= adin_mux_sel_mdri_high;
else
adin_mux_sel <= adin_mux_sel_mdri_low;
end if;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
-- try read byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_sb_rn_rb =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- try writing byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_sb_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
nxt_state <= exec3;
else
-- try reading const word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_li_rn =>
if ack_sync = '1' then
-- rn = mdri
adin_mux_sel <= adin_mux_sel_mdri;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_li_sp =>
if ack_sync = '1' then
-- sp = mdri
spin_mux_sel <= spin_mux_sel_mdri;
sp_ce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alui =>
if ack_sync = '1' then
-- tr5 = tr1 aluop mdri
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_mdri;
case ir_high(2 downto 0) is
when a_sub =>
asopsel <= asopsel_sub;
when a_add =>
asopsel <= asopsel_add;
when a_sbb =>
asopsel <= asopsel_sbb;
when a_adc =>
asopsel <= asopsel_adc;
when a_and =>
asopsel <= asopsel_and;
when a_or =>
asopsel <= asopsel_or;
when a_xor =>
asopsel <= asopsel_xor;
when others =>
asopsel <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= exec3;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_cmpi_cmp =>
if ack_sync = '1' then
-- tr5 = tr1 - mdri
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_sub;
-- flags updated
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_cmpi_tst =>
if ack_sync = '1' then
-- tr5 = tr1 and mdri
alua_mux_sel <= alua_mux_sel_tr1;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_and;
-- flags updated
coszin_mux_sel <= coszin_mux_sel_asresult;
flags_ce <= '1';
flags_cfce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alusp_sub =>
if ack_sync = '1' then
-- sp = sp - mdri
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_sub;
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alusp_add =>
if ack_sync = '1' then
-- sp = sp + mdri
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_mdri;
asopsel <= asopsel_add;
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; C_CYC_O <= '1';
-- prepare mdri
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_pushr | ic_stk_pushf =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_popr =>
if ack_sync = '1'then
-- rn = mdri
adin_mux_sel <= adin_mux_sel_mdri;
rf_adwe <= '1';
nxt_state <= int_chk;
else
-- try reading data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_popf =>
if ack_sync = '1' then
-- flags = mdri
coszin_mux_sel <= coszin_mux_sel_mdri;
flags_ce <= '1';
flags_cfce <= '1';
flags_ifce <= '1';
--
nxt_state <= int_chk;
else
-- try reading word data
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_acall =>
if ack_sync = '1' then
-- pc = tr2
alua_mux_sel <= alua_mux_sel_tr2;
alub_mux_sel <= alub_mux_sel_0;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lcall =>
if ack_sync = '1' then
-- pc += tr2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr2;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
------------------------------------------
when ic_scall =>
if ack_sync = '1' then
-- pc += tr2
alua_mux_sel <= alua_mux_sel_pc;
alub_mux_sel <= alub_mux_sel_tr3;
asopsel <= asopsel_add;
pcin_mux_sel <= pcin_mux_sel_aluout;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_ret =>
if ack_sync = '1' then
-- pc = mdri
pcin_mux_sel <= pcin_mux_sel_mdri;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
-- try reading data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
-------------------------------------------
when ic_int | ic_into =>
if ack_sync = '1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- mar = old sp -2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= exec3;
else
mdro_oe <= '1';
-- try writing data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- pc = mdri
pcin_mux_sel <= pcin_mux_sel_mdri;
pc_ce <= '1';
-- sp = old sp + 2
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_add;
spin_mux_sel <= spin_mux_sel_aluout;
-- mar = sp
marin_mux_sel <= marin_mux_sel_sp;
mar_ce <= '1';
--
nxt_state <= exec3;
else
-- try reading data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when others =>
nxt_state <= halted; -- @new
-------------------------------------------
end case;
--///////////////////////////////////////
when exec3 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp =>
if mar0 = '0' then
-- try reading data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec4;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_st_rn_rb_disp | ic_st_rn_sp_disp =>
if mar0 = '0' then
mdro_oe <= '1';
-- try writing data word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp =>
-- try reading data byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
--
mdri_ce <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_sb_rn_rb_disp =>
--! mdro_oe <= '1';
mdro_ce <= '1';
if mar0 = '0' then
mdroin_mux_sel <= mdroin_mux_sel_tr1_loweven;
else
mdroin_mux_sel <= mdroin_mux_sel_tr1_lowodd;
end if;
nxt_state <= exec4;
----------------------------------------------
when ic_alui =>
-- rn = tr5
adin_mux_sel <= adin_mux_sel_tr5;
rf_adwe <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_int | ic_into =>
mdro_oe <= '1';
-- try writting word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_iret =>
mdri_ce <= '1';
-- try reading word
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when others =>
nxt_state <= halted; -- @new
----------------------------------------------
end case;
--///////////////////////////////////////
when exec4 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp =>
if ack_sync = '1' then
adin_mux_sel <= adin_mux_sel_mdri;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
-- read data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_st_rn_rb_disp | ic_st_rn_sp_disp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- write data word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_lbzx_rn_rb_disp =>
if ack_sync = '1' then
mdri_hl_zse_sign <= '0';
if mar0 = '0' then
adin_mux_sel <= adin_mux_sel_mdri_high;
else
adin_mux_sel <= adin_mux_sel_mdri_low;
end if;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_lbsx_rn_rb_disp =>
if ack_sync = '1' then
mdri_hl_zse_sign <= '1';
if mar0 = '0' then
adin_mux_sel <= adin_mux_sel_mdri_high;
else
adin_mux_sel <= adin_mux_sel_mdri_low;
end if;
rf_adwe <= '1';
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_sb_rn_rb_disp =>
mdro_oe <= '1';
-- write byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec5;
----------------------------------------------
when ic_int | ic_into =>
if ack_sync = '1' then
-- pc = ext(ir(3..0))
intno_mux_sel <= intno_mux_sel_ir;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- write word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- flags = mdri
coszin_mux_sel <= coszin_mux_sel_mdri;
flags_ce <= '1';
flags_cfce <= '1';
flags_ifce <= '1';
--
nxt_state <= int_chk;
else
mdri_ce <= '1';
-- try reading word
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when others =>
nxt_state <= halted; -- @new
----------------------------------------------
end case;
--///////////////////////////////////////
when exec5 =>
case cur_ic is
when ic_sb_rn_rb_disp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe <= '1';
-- write byte
if mar0 = '0' then
SEL_O <= "10";
else
SEL_O <= "01";
end if;
STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
nxt_state <= exec5;
end if;
when others =>
nxt_state <= halted; -- @new
end case;
--///////////////////////////////////////
when int_chk =>
if int_flag = '1' then
if intr_sync = '1' then
-- read vector no.
SEL_O <= "10"; STB_O <= '1'; CYC_O <= '1'; INTA_CYC_O <= '1';
-- prepare intr
intr_ce <= '1';
-- clear intr_sync
intr_sync_rst <= '1';
-- clear IF
flags_cli <= '1';
--
nxt_state <= int0;
else
nxt_state <= fetch0;
end if;
else
nxt_state <= fetch0;
end if;
--///////////////////////////////////////
when int0 =>
if ack_sync = '1' then
if sp0 = '0' then
-- mar = old sp - 2
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = flags
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= int1;
else
-- mdro = intno
intno_mux_sel <= intno_mux_sel_intr;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
--! mdro_oe <= '1';
-- dfh = sp
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
else
-- try reading vector number
SEL_O <= "10"; STB_O <= '0'; CYC_O <= '1'; INTA_CYC_O <= '1';
--
intr_ce <= '1';
--
nxt_state <= int0;
end if;
--///////////////////////////////////////
when int1 =>
-- write flags
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= int2;
--///////////////////////////////////////
when int2 =>
if ack_sync = '1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= int3;
else
-- try writing data word (flags)
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= int2;
end if;
--///////////////////////////////////////
when int3 =>
-- write pc
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= int4;
--///////////////////////////////////////
when int4 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_intr;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= int4;
end if;
--///////////////////////////////////////
when invalid0 =>
if sp0= '0' then
-- push flag
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= invalid1;
else
-- in case of df
-- move the vector no to
intno_mux_sel <= intno_mux_sel_invalid;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
--///////////////////////////////////////
when invalid1 =>
-- write flags
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= invalid2;
--///////////////////////////////////////
when invalid2 =>
if ack_sync = '1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= invalid3;
else
-- try writing data word (flags)
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= invalid2;
end if;
--///////////////////////////////////////
when invalid3 =>
-- write pc
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= invalid4;
--///////////////////////////////////////
when invalid4 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_intr;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= invalid4;
end if;
--///////////////////////////////////////
when align0 =>
if sp0= '0' then
-- push flag
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= align1;
else
-- in case of df
-- move the vector no to
intno_mux_sel <= intno_mux_sel_align;
mdroin_mux_sel <= mdroin_mux_sel_intno;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
dfh_ce <= '1';
--
nxt_state <= df0;
end if;
--///////////////////////////////////////
when align1 =>
-- write flags
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= align2;
--///////////////////////////////////////
when align2 =>
if ack_sync = '1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
-- sp = old sp - 2
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
-- mdro = pc
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= align3;
else
-- try writing data word (flags)
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= align2;
end if;
--///////////////////////////////////////
when align3 =>
-- write pc
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= align4;
--///////////////////////////////////////
when align4 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_intr;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= align4;
end if;
--///////////////////////////////////////
when stkerr0 =>
sp_pre <= '1';
nxt_state <= stkerr1;
--//////////////////////////////////////
when stkerr1 =>
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_dfh;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= stkerr2;
--///////////////////////////////////////
when stkerr2 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= stkerr3;
--///////////////////////////////////////
when stkerr3 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= stkerr4;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= stkerr3;
end if;
--///////////////////////////////////////
when stkerr4 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= stkerr5;
--///////////////////////////////////////
when stkerr5 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= stkerr6;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= stkerr5;
end if;
--///////////////////////////////////////
when stkerr6 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= stkerr7;
--///////////////////////////////////////
when stkerr7 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_df;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= stkerr7;
end if;
--///////////////////////////////////////
when df0 =>
sp_pre <= '1';
nxt_state <= df1;
--//////////////////////////////////////
when df1 =>
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
nxt_state <= df2;
--//////////////////////////////////////
when df2 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= df3;
--//////////////////////////////////////
when df3 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_dfh;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= df4;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= df3;
end if;
--///////////////////////////////////////
when df4 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= df5;
--///////////////////////////////////////
when df5 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_flags;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= df6;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= df5;
end if;
--///////////////////////////////////////
when df6 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= df7;
--///////////////////////////////////////
when df7 =>
if ack_sync ='1' then
alua_mux_sel <= alua_mux_sel_sp;
alub_mux_sel <= alub_mux_sel_2;
asopsel <= asopsel_sub;
--
marin_mux_sel <= marin_mux_sel_aluout;
mar_ce <= '1';
--
spin_mux_sel <= spin_mux_sel_aluout;
sp_ce <= '1';
--
mdroin_mux_sel <= mdroin_mux_sel_pc;
mdro_ce <= '1';
--! mdro_oe <= '1';
--
nxt_state <= df8;
else
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= df7;
end if;
--///////////////////////////////////////
when df8 =>
SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
mdro_oe <= '1';
nxt_state <= df9;
--///////////////////////////////////////
when df9 =>
if ack_sync = '1' then
intno_mux_sel <= intno_mux_sel_df;
pcin_mux_sel <= pcin_mux_sel_intno;
pc_ce <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O <= "11"; STB_O <= '0'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1';
--
mdro_oe <= '1';
--
nxt_state <= df9;
end if;
--///////////////////////////////////////
when halted =>
if int_flag = '1' and intr_sync = '1' then
-- read vector no.
SEL_O <= "10"; STB_O <= '1'; CYC_O <= '1'; INTA_CYC_O <= '1';
-- prepare intr
intr_ce <= '1';
--
nxt_state <= int0;
else
nxt_state <= halted;
end if;
--//////////////////////////////////////
end case;
end process;
-- since alu & shifter are not used simultanously...
aopsel <= asopsel(2 downto 0);
sopsel <= asopsel(2 downto 0);
asresult_mux_sel <= asopsel(3);
end rtl;
/vhdl/con1_arch_rtlfast.vhd
0,0 → 1,2243
--------------------------------------------------------------
-- con1_arch_rtlfast.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: "fast arch" of control unit of microprocessor
--
-- dependency: con1.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 --
-- --
------------------------------------------------------------------------------------
 
architecture rtlfast of con1 is
signal rst_sync : std_logic;
signal ack_sync : std_logic;
signal intr_sync : std_logic;
signal cur_state , nxt_state : state;
signal cur_ic : ic;
signal asopsel : std_logic_vector(3 downto 0);
 
signal rsync_stage0 : std_logic;
signal rsync_stage1 : std_logic;
 
signal isync_stage0 : std_logic;
signal isync_stage1 : std_logic;
signal isync_stage2 : std_logic;
signal isync : std_logic;
signal intr_sync_rst : std_logic;
 
signal intr_sync_rst_int : std_logic;
signal SEL_O_int : std_logic_vector(1 downto 0);
signal STB_O_int : std_logic;
signal CYC_O_int : std_logic;
signal WE_O_int : std_logic;
signal INTA_CYC_O_int : std_logic;
signal C_CYC_O_int : std_logic;
signal I_CYC_O_int : std_logic;
signal D_CYC_O_int : std_logic;
signal intr_ce_int : std_logic;
signal ir_ce_int : std_logic;
signal mdri_ce_int : std_logic;
signal mdri_hl_zse_sign_int : std_logic;
signal intno_mux_sel_int : std_logic_vector(2 downto 0);
signal adin_mux_sel_int : std_logic_vector(2 downto 0);
signal rf_adwe_int : std_logic;
signal pcin_mux_sel_int : std_logic_vector(1 downto 0);
signal pc_pre_int : std_logic;
signal pc_ce_int : std_logic;
signal spin_mux_sel_int : std_logic;
signal sp_pre_int : std_logic;
signal sp_ce_int : std_logic;
signal dfh_ce_int : std_logic;
signal alua_mux_sel_int : std_logic_vector(1 downto 0);
signal alub_mux_sel_int : std_logic_vector(2 downto 0);
signal asopsel_int : std_logic_vector(3 downto 0);
signal sbin_mux_sel_int : std_logic;
signal coszin_mux_sel_int : std_logic;
signal flags_rst_int : std_logic;
signal flags_ce_int : std_logic;
signal flags_cfce_int : std_logic;
signal flags_ifce_int : std_logic;
signal flags_clc_int : std_logic;
signal flags_cmc_int : std_logic;
signal flags_stc_int : std_logic;
signal flags_cli_int : std_logic;
signal flags_sti_int : std_logic;
signal marin_mux_sel_int : std_logic_vector(1 downto 0);
signal mar_ce_int : std_logic;
signal mdroin_mux_sel_int : std_logic_vector(2 downto 0);
signal mdro_ce_int : std_logic;
signal mdro_oe_int : std_logic;
begin
process(CLK_I)
begin
if rising_edge(CLK_I) then
rsync_stage0 <= RST_I;
rsync_stage1 <= rsync_stage0;
rst_sync <= rsync_stage1;
end if;
end process;
 
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
ack_sync <= '0';
elsif rising_edge(CLK_I)then
ack_sync <= ACK_I;
end if;
end process;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
isync_stage0 <= '0';
isync_stage1 <= '0';
isync_stage2 <= '0';
elsif rising_edge(CLK_I)then
isync_stage0 <= INTR_I;
isync_stage1 <= isync_stage0;
isync_stage2 <= isync_stage1;
end if;
end process;
isync <= isync_stage0 and isync_stage1 and not isync_stage2;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
intr_sync <= '0';
elsif rising_edge(CLK_I) then
if intr_sync_rst = '1' then
intr_sync <= '0';
elsif isync = '1' then
intr_sync <= '1';
end if;
end if;
end process;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
cur_state <= reset;
elsif rising_edge(CLK_I) then
cur_state <= nxt_state;
end if;
end process;
decode:
cur_ic <= ic_mov_rn_rm when ir_high = mov_rn_rm else
ic_mov_sp_rm when ir_high = mov_sp_rm else
ic_mov_rn_sp when ir_high = mov_rn_sp else
ic_ld_rn_rb when ir_high = ld_rn_rb else
ic_ld_rn_rb_disp when ir_high = ld_rn_rb_disp else
ic_ld_rn_sp when ir_high = ld_rn_sp else
ic_ld_rn_sp_disp when ir_high = ld_rn_sp_disp else
ic_st_rn_rb when ir_high = st_rn_rb else
ic_st_rn_rb_disp when ir_high = st_rn_rb_disp else
ic_st_rn_sp when ir_high = st_rn_sp else
ic_st_rn_sp_disp when ir_high = st_rn_sp_disp else
ic_lbzx_rn_rb when ir_high = lbzx_rn_rb else
ic_lbzx_rn_rb_disp when ir_high = lbzx_rn_rb_disp else
ic_lbsx_rn_rb when ir_high = lbsx_rn_rb else
ic_lbsx_rn_rb_disp when ir_high = lbsx_rn_rb_disp else
ic_sb_rn_rb when ir_high = sb_rn_rb else
ic_sb_rn_rb_disp when ir_high = sb_rn_rb_disp else
ic_sing_dec when ir_high = sing_dec else
ic_sing_inc when ir_high = sing_inc else
ic_alur when ir_high(7 downto 3) = alur else
ic_shiftr when ir_high(7 downto 3) = shiftr else
ic_cmp_cmp when ir_high = cmp_cmp else
ic_cmp_tst when ir_high = cmp_tst else
ic_li_rn when ir_high = li_rn else
ic_li_sp when ir_high = li_sp else
ic_alui when ir_high(7 downto 3) = alui else
ic_shifti when ir_high(7 downto 3) = shifti else
ic_cmpi_cmp when ir_high = cmpi_cmp else
ic_cmpi_tst when ir_high = cmpi_tst else
ic_alusp_sub when ir_high = alusp_sub else
ic_alusp_add when ir_high = alusp_add else
ic_stk_pushr when ir_high = stk_pushr else
ic_stk_pushf when ir_high = stk_pushf else
ic_stk_popr when ir_high = stk_popr else
ic_stk_popf when ir_high = stk_popf else
ic_acall when ir_high = acall else
ic_lcall when ir_high = lcall else
ic_scall when ir_high(7 downto 3) = scall else
ic_ret when ir_high(7 downto 3) = ret else
ic_int when ir_high(7 downto 3) = int else
ic_into when ir_high(7 downto 3) = into else
ic_iret when ir_high(7 downto 3) = iret else
ic_ajmp when ir_high = ajmp else
ic_ljmp when ir_high = ljmp else
ic_sjmp when ir_high(7 downto 3) = sjmp else
ic_jcc when ir_high(7 downto 3) = jcc else
ic_fop_clc when ir_high = fop_clc else
ic_fop_stc when ir_high = fop_stc else
ic_fop_cmc when ir_high = fop_cmc else
ic_fop_cli when ir_high = fop_cli else
ic_fop_sti when ir_high = fop_sti else
ic_nop when ir_high(7 downto 3) = nop else
ic_hlt when ir_high(7 downto 3) = hlt else
ic_invalid;
 
process(cur_state, cur_ic, jcc_ok, int_flag, pc0, sp0, tr20, mar0, ir_high,
ack_sync, intr_sync, rst_sync)
begin
SEL_O_int <= "00";
STB_O_int <= '0';
CYC_O_int <= '0';
WE_O_int <= '0';
INTA_CYC_O_int <= '0';
C_CYC_O_int <= '0';
I_CYC_O_int <= '0';
D_CYC_O_int <= '0';
intr_ce_int <= '0';
ir_ce_int <= '0';
mdri_ce_int <= '0';
mdri_hl_zse_sign_int <= '0';
intno_mux_sel_int <= "000";
adin_mux_sel_int <= "000";
rf_adwe_int <= '0';
pcin_mux_sel_int <= "00";
pc_pre_int <= '0';
pc_ce_int <= '0';
spin_mux_sel_int <= '0';
sp_pre_int <= '0';
sp_ce_int <= '0';
alua_mux_sel_int <= "00";
alub_mux_sel_int <= "000";
sbin_mux_sel_int <= '0';
asopsel_int <= "0000";
coszin_mux_sel_int <= '0';
flags_rst_int <= '0';
flags_ce_int <= '0';
flags_cfce_int <= '0';
flags_ifce_int <= '0';
flags_clc_int <= '0';
flags_cmc_int <= '0';
flags_stc_int <= '0';
flags_cli_int <= '0';
flags_sti_int <= '0';
marin_mux_sel_int <= "00";
mar_ce_int <= '0';
dfh_ce_int <= '0';
mdroin_mux_sel_int <= "000";
mdro_ce_int <= '0';
mdro_oe_int <= '0';
intr_sync_rst_int <= '0';
case cur_state is
--//////////////////////////////////////
when reset =>
pc_pre_int <= '1';
flags_rst_int <= '1';
-- @new start
sp_pre_int <= '1';
-- @new end
if rst_sync = '0' then
nxt_state <= fetch0;
else
nxt_state <= reset;
end if;
--//////////////////////////////////////
when fetch0 =>
if pc0 = '0' then
-- mar = pc
marin_mux_sel_int <= marin_mux_sel_pc;
mar_ce_int <= '1';
-- pc += 2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= fetch1;
else
nxt_state <= align0;
end if;
--///////////////////////////////////////
when fetch1 =>
-- read instruction; note STB_O_int is one shot
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; I_CYC_O_int <= '1';
-- prepare ir
ir_ce_int <= '1';
--
nxt_state <= fetch2;
--///////////////////////////////////////
when fetch2 =>
if ack_sync = '1' then
-- read end
nxt_state <= exec0;
else
-- continue read & prepare ir
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; I_CYC_O_int <= '1';
ir_ce_int <= '1';
--
nxt_state <= fetch2;
end if;
--///////////////////////////////////////
when exec0 =>
case cur_ic is
----------------------------------------------
when ic_mov_rn_rm =>
-- rn = tr2
adin_mux_sel_int <= adin_mux_sel_tr2;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_mov_sp_rm =>
-- sp = (tr2 + 0)
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_mov_rn_sp =>
-- rn = sp
adin_mux_sel_int <= adin_mux_sel_sp;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_ld_rn_rb =>
if tr20 = '0' then
-- mar = tr2 + 0
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
nxt_state <= exec1;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp |
ic_st_rn_rb_disp | ic_st_rn_sp_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp |
ic_sb_rn_rb_disp | ic_li_rn |
ic_li_sp | ic_alui | ic_cmpi_cmp |
ic_cmpi_tst | ic_alusp_add | ic_alusp_sub =>
-- mar = pc
marin_mux_sel_int <= marin_mux_sel_pc;
mar_ce_int <= '1';
-- pc += 2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_ld_rn_sp =>
if sp0 = '0' then
-- mar = sp
marin_mux_sel_int <= marin_mux_sel_sp;
mar_ce_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_st_rn_rb =>
if tr20 = '0' then
-- mar = tr2 + 0
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec1;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_st_rn_sp =>
if sp0 = '0' then
-- mar = sp
marin_mux_sel_int <= marin_mux_sel_sp;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_lbzx_rn_rb | ic_lbsx_rn_rb =>
-- mar = tr2 + 0
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sb_rn_rb =>
-- mar = tr2 + 0
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
if tr20 = '0' then
-- mdro = tr1(7..0) & 0000_0000
mdroin_mux_sel_int <= mdroin_mux_sel_tr1_loweven;
else
-- mdro = 0000_0000 & tr1(7..0)
mdroin_mux_sel_int <= mdroin_mux_sel_tr1_lowodd;
end if;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sing_inc =>
-- tr5 = tr1 + 1
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_1;
asopsel_int <= asopsel_add;
-- flags updated (except cf, if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_sing_dec =>
-- tr5 = tr1 - 1
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_1;
asopsel_int <= asopsel_sub;
-- flags updated (except cf, if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_alur =>
-- tr5 = tr1 aluop tr2
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_tr2;
case ir_high(2 downto 0) is
when a_sub =>
asopsel_int <= asopsel_sub;
when a_add =>
asopsel_int <= asopsel_add;
when a_sbb =>
asopsel_int <= asopsel_sbb;
when a_adc =>
asopsel_int <= asopsel_adc;
when a_not =>
asopsel_int <= asopsel_not;
when a_and =>
asopsel_int <= asopsel_and;
when a_or =>
asopsel_int <= asopsel_or;
when a_xor =>
asopsel_int <= asopsel_xor;
when others =>
asopsel_int <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_shiftr =>
-- tr5 = tr1 shiftop tr2
sbin_mux_sel_int <= sbin_mux_sel_tr2;
case ir_high(2 downto 0) is
when s_sll =>
asopsel_int <= asopsel_sll;
when s_slr =>
asopsel_int <= asopsel_slr;
when s_sal =>
asopsel_int <= asopsel_sal;
when s_sar =>
asopsel_int <= asopsel_sar;
when s_rol =>
asopsel_int <= asopsel_rol;
when s_ror =>
asopsel_int <= asopsel_ror;
when s_rcl =>
asopsel_int <= asopsel_rcl;
when s_rcr =>
asopsel_int <= asopsel_rcr;
when others =>
asopsel_int <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_cmp_cmp =>
-- tr5 = tr1 - tr2
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_tr2;
asopsel_int <= asopsel_sub;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_cmp_tst =>
-- tr5 = tr1 and tr2
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_tr2;
asopsel_int <= asopsel_and;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_shifti =>
-- tr5 = tr1 shiftop ir(3..0)
sbin_mux_sel_int <= sbin_mux_sel_ir;
case ir_high(2 downto 0) is
when s_sll =>
asopsel_int <= asopsel_sll;
when s_slr =>
asopsel_int <= asopsel_slr;
when s_sal =>
asopsel_int <= asopsel_sal;
when s_sar =>
asopsel_int <= asopsel_sar;
when s_rol =>
asopsel_int <= asopsel_rol;
when s_ror =>
asopsel_int <= asopsel_ror;
when s_rcl =>
asopsel_int <= asopsel_rcl;
when s_rcr =>
asopsel_int <= asopsel_rcr;
when others =>
asopsel_int <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= exec1;
----------------------------------------------
when ic_stk_pushr =>
if sp0 = '0' then
--
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_stk_pushf =>
if sp0 = '0' then
--
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = flags
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
----------------------------------------------
when ic_stk_popr | ic_stk_popf | ic_ret | ic_iret =>
if sp0 = '0' then
--
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_add;
-- sp = old sp + 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp
marin_mux_sel_int <= marin_mux_sel_sp;
mar_ce_int <= '1';
--
nxt_state <= exec1;
else
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
---------------------------------------------
when ic_acall | ic_lcall | ic_scall =>
if sp0 = '0' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec1;
else
-- dfh =sp
dfh_ce_int <= '1';
--
nxt_state <= stkerr0;
end if;
---------------------------------------------
when ic_int =>
if sp0 = '0' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = flags
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec1;
else
-- mdro = intno
intno_mux_sel_int <= intno_mux_sel_ir;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
-- dfh =sp
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
---------------------------------------------
when ic_into =>
if sp0 = '0' then
if jcc_ok = '0' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = flags
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec1;
else
nxt_state <= int_chk;
end if;
else
-- mdro = intno
intno_mux_sel_int <= intno_mux_sel_ir;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
-- dfh =sp
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
---------------------------------------------
when ic_ajmp =>
-- pc = tr2
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
--------------------------------------------
when ic_ljmp =>
-- pc += tr2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr2;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
---------------------------------------------
when ic_sjmp =>
-- pc += tr3
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr3;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_jcc =>
if jcc_ok = '1' then
-- pc += tr4
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr4;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
else
null;
end if;
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_clc =>
flags_clc_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_cmc =>
flags_cmc_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_stc =>
flags_stc_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_cli =>
flags_cli_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_fop_sti =>
flags_sti_int <= '1';
nxt_state <= int_chk;
----------------------------------------------
when ic_nop =>
nxt_state <= int_chk;
----------------------------------------------
when ic_hlt =>
--flags_sti_int <= '1';
nxt_state <= halted;
----------------------------------------------
when ic_invalid =>
nxt_state <= invalid0;
----------------------------------------------
end case;
--///////////////////////////////////////
when exec1 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb | ic_ld_rn_sp | ic_stk_popr |
ic_stk_popf | ic_ret | ic_iret =>
-- read data word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
---------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp |
ic_st_rn_rb_disp | ic_st_rn_sp_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp |
ic_sb_rn_rb_disp | ic_li_rn | ic_li_sp |
ic_alui | ic_cmpi_cmp | ic_cmpi_tst |
ic_alusp_add | ic_alusp_sub =>
-- read const word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_st_rn_rb | ic_st_rn_sp | ic_stk_pushr |
ic_stk_pushf | ic_acall | ic_lcall | ic_scall |
ic_int | ic_into =>
mdro_oe_int <= '1';
-- write data word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
-------------------------------------------
when ic_lbzx_rn_rb | ic_lbsx_rn_rb =>
-- read data byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_sb_rn_rb =>
mdro_oe_int <= '1';
-- write data byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
--------------------------------------------
when ic_sing_inc | ic_sing_dec | ic_alur |
ic_shiftr | ic_shifti =>
-- rn = tr5
adin_mux_sel_int <= adin_mux_sel_tr5;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
--------------------------------------------
when others =>
nxt_state <= halted; -- @new
end case;
--///////////////////////////////////////
when exec2 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb | ic_ld_rn_sp =>
if ack_sync = '1' then
-- rn = mdri
adin_mux_sel_int <= adin_mux_sel_mdri;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_ld_rn_rb_disp |
ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_ld_rn_sp_disp =>
if ack_sync = '1' then
-- mar = sp + mdri
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_sp_disp =>
if ack_sync = '1' then
-- mar = sp + mdri
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- mdro = tr1
mdroin_mux_sel_int <= mdroin_mux_sel_tr1;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_st_rn_rb | ic_st_rn_sp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- try write data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lbzx_rn_rb =>
if ack_sync = '1' then
mdri_hl_zse_sign_int <= '0';
if mar0 = '0' then
adin_mux_sel_int <= adin_mux_sel_mdri_high;
else
adin_mux_sel_int <= adin_mux_sel_mdri_low;
end if;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
-- try read byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lbsx_rn_rb =>
if ack_sync = '1' then
mdri_hl_zse_sign_int <= '1';
if mar0 = '0' then
adin_mux_sel_int <= adin_mux_sel_mdri_high;
else
adin_mux_sel_int <= adin_mux_sel_mdri_low;
end if;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
-- try read byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_sb_rn_rb =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- try writing byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_sb_rn_rb_disp =>
if ack_sync = '1' then
-- mar = tr2 + mdri
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
nxt_state <= exec3;
else
-- try reading const word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_li_rn =>
if ack_sync = '1' then
-- rn = mdri
adin_mux_sel_int <= adin_mux_sel_mdri;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_li_sp =>
if ack_sync = '1' then
-- sp = mdri
spin_mux_sel_int <= spin_mux_sel_mdri;
sp_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alui =>
if ack_sync = '1' then
-- tr5 = tr1 aluop mdri
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_mdri;
case ir_high(2 downto 0) is
when a_sub =>
asopsel_int <= asopsel_sub;
when a_add =>
asopsel_int <= asopsel_add;
when a_sbb =>
asopsel_int <= asopsel_sbb;
when a_adc =>
asopsel_int <= asopsel_adc;
when a_and =>
asopsel_int <= asopsel_and;
when a_or =>
asopsel_int <= asopsel_or;
when a_xor =>
asopsel_int <= asopsel_xor;
when others =>
asopsel_int <= (others => '0');
end case;
-- flags updated (except if)
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_cmpi_cmp =>
if ack_sync = '1' then
-- tr5 = tr1 - mdri
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_sub;
-- flags updated
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_cmpi_tst =>
if ack_sync = '1' then
-- tr5 = tr1 and mdri
alua_mux_sel_int <= alua_mux_sel_tr1;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_and;
-- flags updated
coszin_mux_sel_int <= coszin_mux_sel_asresult;
flags_ce_int <= '1';
flags_cfce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alusp_sub =>
if ack_sync = '1' then
-- sp = sp - mdri
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_sub;
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_alusp_add =>
if ack_sync = '1' then
-- sp = sp + mdri
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_mdri;
asopsel_int <= asopsel_add;
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading const word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; C_CYC_O_int <= '1';
-- prepare mdri
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_pushr | ic_stk_pushf =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_popr =>
if ack_sync = '1'then
-- rn = mdri
adin_mux_sel_int <= adin_mux_sel_mdri;
rf_adwe_int <= '1';
nxt_state <= int_chk;
else
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_stk_popf =>
if ack_sync = '1' then
-- flags = mdri
coszin_mux_sel_int <= coszin_mux_sel_mdri;
flags_ce_int <= '1';
flags_cfce_int <= '1';
flags_ifce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading word data
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_acall =>
if ack_sync = '1' then
-- pc = tr2
alua_mux_sel_int <= alua_mux_sel_tr2;
alub_mux_sel_int <= alub_mux_sel_0;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when ic_lcall =>
if ack_sync = '1' then
-- pc += tr2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr2;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
------------------------------------------
when ic_scall =>
if ack_sync = '1' then
-- pc += tr2
alua_mux_sel_int <= alua_mux_sel_pc;
alub_mux_sel_int <= alub_mux_sel_tr3;
asopsel_int <= asopsel_add;
pcin_mux_sel_int <= pcin_mux_sel_aluout;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_ret =>
if ack_sync = '1' then
-- pc = mdri
pcin_mux_sel_int <= pcin_mux_sel_mdri;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
-------------------------------------------
when ic_int | ic_into =>
if ack_sync = '1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- mar = old sp -2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= exec3;
else
mdro_oe_int <= '1';
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec2;
end if;
-----------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- pc = mdri
pcin_mux_sel_int <= pcin_mux_sel_mdri;
pc_ce_int <= '1';
-- sp = old sp + 2
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_add;
spin_mux_sel_int <= spin_mux_sel_aluout;
-- mar = sp
marin_mux_sel_int <= marin_mux_sel_sp;
mar_ce_int <= '1';
--
nxt_state <= exec3;
else
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec2;
end if;
--------------------------------------------
when others =>
nxt_state <= halted; -- @new
-------------------------------------------
end case;
--///////////////////////////////////////
when exec3 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp =>
if mar0 = '0' then
-- try reading data word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec4;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_st_rn_rb_disp | ic_st_rn_sp_disp =>
if mar0 = '0' then
mdro_oe_int <= '1';
-- try writing data word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
else
nxt_state <= align0;
end if;
----------------------------------------------
when ic_lbzx_rn_rb_disp | ic_lbsx_rn_rb_disp =>
-- try reading data byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
mdri_ce_int <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_sb_rn_rb_disp =>
--! mdro_oe_int <= '1';
mdro_ce_int <= '1';
if mar0 = '0' then
mdroin_mux_sel_int <= mdroin_mux_sel_tr1_loweven;
else
mdroin_mux_sel_int <= mdroin_mux_sel_tr1_lowodd;
end if;
nxt_state <= exec4;
----------------------------------------------
when ic_alui =>
-- rn = tr5
adin_mux_sel_int <= adin_mux_sel_tr5;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
----------------------------------------------
when ic_int | ic_into =>
mdro_oe_int <= '1';
-- try writting word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when ic_iret =>
mdri_ce_int <= '1';
-- try reading word
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
----------------------------------------------
when others =>
nxt_state <= halted; -- @new
----------------------------------------------
end case;
--///////////////////////////////////////
when exec4 =>
case cur_ic is
----------------------------------------------
when ic_ld_rn_rb_disp | ic_ld_rn_sp_disp =>
if ack_sync = '1' then
adin_mux_sel_int <= adin_mux_sel_mdri;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
mdri_ce_int <= '1';
-- read data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_st_rn_rb_disp | ic_st_rn_sp_disp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- write data word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_lbzx_rn_rb_disp =>
if ack_sync = '1' then
mdri_hl_zse_sign_int <= '0';
if mar0 = '0' then
adin_mux_sel_int <= adin_mux_sel_mdri_high;
else
adin_mux_sel_int <= adin_mux_sel_mdri_low;
end if;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
mdri_ce_int <= '1';
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_lbsx_rn_rb_disp =>
if ack_sync = '1' then
mdri_hl_zse_sign_int <= '1';
if mar0 = '0' then
adin_mux_sel_int <= adin_mux_sel_mdri_high;
else
adin_mux_sel_int <= adin_mux_sel_mdri_low;
end if;
rf_adwe_int <= '1';
--
nxt_state <= int_chk;
else
mdri_ce_int <= '1';
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_sb_rn_rb_disp =>
mdro_oe_int <= '1';
-- write byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec5;
----------------------------------------------
when ic_int | ic_into =>
if ack_sync = '1' then
-- pc = ext(ir(3..0))
intno_mux_sel_int <= intno_mux_sel_ir;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- write word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when ic_iret =>
if ack_sync = '1' then
-- flags = mdri
coszin_mux_sel_int <= coszin_mux_sel_mdri;
flags_ce_int <= '1';
flags_cfce_int <= '1';
flags_ifce_int <= '1';
--
nxt_state <= int_chk;
else
mdri_ce_int <= '1';
-- try reading word
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec4;
end if;
----------------------------------------------
when others =>
nxt_state <= halted; -- @new
----------------------------------------------
end case;
--///////////////////////////////////////
when exec5 =>
case cur_ic is
when ic_sb_rn_rb_disp =>
if ack_sync = '1' then
nxt_state <= int_chk;
else
mdro_oe_int <= '1';
-- write byte
if mar0 = '0' then
SEL_O_int <= "10";
else
SEL_O_int <= "01";
end if;
STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
nxt_state <= exec5;
end if;
when others =>
nxt_state <= halted; -- @new
end case;
--///////////////////////////////////////
when int_chk =>
if int_flag = '1' then
if intr_sync = '1' then
-- read vector no.
SEL_O_int <= "10"; STB_O_int <= '1'; CYC_O_int <= '1'; INTA_CYC_O_int <= '1';
-- prepare intr
intr_ce_int <= '1';
-- clear intr_sync
intr_sync_rst_int <= '1';
-- clear IF
flags_cli_int <= '1';
--
nxt_state <= int0;
else
nxt_state <= fetch0;
end if;
else
nxt_state <= fetch0;
end if;
--///////////////////////////////////////
when int0 =>
if ack_sync = '1' then
if sp0 = '0' then
-- mar = old sp - 2
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = flags
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= int1;
else
-- mdro = intno
intno_mux_sel_int <= intno_mux_sel_intr;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
-- dfh = sp
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
else
-- try reading vector number
SEL_O_int <= "10"; STB_O_int <= '0'; CYC_O_int <= '1'; INTA_CYC_O_int <= '1';
--
intr_ce_int <= '1';
--
nxt_state <= int0;
end if;
--///////////////////////////////////////
when int1 =>
-- write flags
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= int2;
--///////////////////////////////////////
when int2 =>
if ack_sync = '1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= int3;
else
-- try writing data word (flags)
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= int2;
end if;
--///////////////////////////////////////
when int3 =>
-- write pc
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= int4;
--///////////////////////////////////////
when int4 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_intr;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= int4;
end if;
--///////////////////////////////////////
when invalid0 =>
if sp0= '0' then
-- push flag
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= invalid1;
else
-- in case of df
-- move the vector no to
intno_mux_sel_int <= intno_mux_sel_invalid;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
--///////////////////////////////////////
when invalid1 =>
-- write flags
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= invalid2;
--///////////////////////////////////////
when invalid2 =>
if ack_sync = '1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= invalid3;
else
-- try writing data word (flags)
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= invalid2;
end if;
--///////////////////////////////////////
when invalid3 =>
-- write pc
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= invalid4;
--///////////////////////////////////////
when invalid4 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_intr;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= invalid4;
end if;
--///////////////////////////////////////
when align0 =>
if sp0= '0' then
-- push flag
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= align1;
else
-- in case of df
-- move the vector no to
intno_mux_sel_int <= intno_mux_sel_align;
mdroin_mux_sel_int <= mdroin_mux_sel_intno;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
dfh_ce_int <= '1';
--
nxt_state <= df0;
end if;
--///////////////////////////////////////
when align1 =>
-- write flags
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= align2;
--///////////////////////////////////////
when align2 =>
if ack_sync = '1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
-- mar = old sp - 2
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
-- sp = old sp - 2
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
-- mdro = pc
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= align3;
else
-- try writing data word (flags)
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= align2;
end if;
--///////////////////////////////////////
when align3 =>
-- write pc
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= align4;
--///////////////////////////////////////
when align4 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_intr;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= align4;
end if;
--///////////////////////////////////////
when stkerr0 =>
sp_pre_int <= '1';
nxt_state <= stkerr1;
--//////////////////////////////////////
when stkerr1 =>
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_dfh;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= stkerr2;
--///////////////////////////////////////
when stkerr2 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= stkerr3;
--///////////////////////////////////////
when stkerr3 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= stkerr4;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= stkerr3;
end if;
--///////////////////////////////////////
when stkerr4 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= stkerr5;
--///////////////////////////////////////
when stkerr5 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= stkerr6;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= stkerr5;
end if;
--///////////////////////////////////////
when stkerr6 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= stkerr7;
--///////////////////////////////////////
when stkerr7 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_df;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= stkerr7;
end if;
--///////////////////////////////////////
when df0 =>
sp_pre_int <= '1';
nxt_state <= df1;
--//////////////////////////////////////
when df1 =>
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
nxt_state <= df2;
--//////////////////////////////////////
when df2 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= df3;
--//////////////////////////////////////
when df3 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_dfh;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= df4;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= df3;
end if;
--///////////////////////////////////////
when df4 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= df5;
--///////////////////////////////////////
when df5 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_flags;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= df6;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= df5;
end if;
--///////////////////////////////////////
when df6 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= df7;
--///////////////////////////////////////
when df7 =>
if ack_sync ='1' then
alua_mux_sel_int <= alua_mux_sel_sp;
alub_mux_sel_int <= alub_mux_sel_2;
asopsel_int <= asopsel_sub;
--
marin_mux_sel_int <= marin_mux_sel_aluout;
mar_ce_int <= '1';
--
spin_mux_sel_int <= spin_mux_sel_aluout;
sp_ce_int <= '1';
--
mdroin_mux_sel_int <= mdroin_mux_sel_pc;
mdro_ce_int <= '1';
--! mdro_oe_int <= '1';
--
nxt_state <= df8;
else
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= df7;
end if;
--///////////////////////////////////////
when df8 =>
SEL_O_int <= "11"; STB_O_int <= '1'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
mdro_oe_int <= '1';
nxt_state <= df9;
--///////////////////////////////////////
when df9 =>
if ack_sync = '1' then
intno_mux_sel_int <= intno_mux_sel_df;
pcin_mux_sel_int <= pcin_mux_sel_intno;
pc_ce_int <= '1';
--
nxt_state <= fetch0;
else
-- writing pc
SEL_O_int <= "11"; STB_O_int <= '0'; CYC_O_int <= '1'; WE_O_int <= '1'; D_CYC_O_int <= '1';
--
mdro_oe_int <= '1';
--
nxt_state <= df9;
end if;
--///////////////////////////////////////
when halted =>
if int_flag = '1' and intr_sync = '1' then
-- read vector no.
SEL_O_int <= "10"; STB_O_int <= '1'; CYC_O_int <= '1'; INTA_CYC_O_int <= '1';
-- prepare intr
intr_ce_int <= '1';
--
nxt_state <= int0;
else
nxt_state <= halted;
end if;
--//////////////////////////////////////
end case;
end process;
process(CLK_I, rst_sync)
begin
if rst_sync = '1' then
SEL_O <= "00";
STB_O <= '0';
CYC_O <= '0';
WE_O <= '0';
INTA_CYC_O <= '0';
C_CYC_O <= '0';
I_CYC_O <= '0';
D_CYC_O <= '0';
intr_ce <= '0';
ir_ce <= '0';
mdri_ce <= '0';
mdri_hl_zse_sign <= '0';
intno_mux_sel <= "000";
adin_mux_sel <= "000";
rf_adwe <= '0';
pcin_mux_sel <= "00";
pc_pre <= '0';
pc_ce <= '0';
spin_mux_sel <= '0';
sp_pre <= '0';
sp_ce <= '0';
alua_mux_sel <= "00";
alub_mux_sel <= "000";
sbin_mux_sel <= '0';
asopsel <= "0000";
coszin_mux_sel <= '0';
flags_rst <= '0';
flags_ce <= '0';
flags_cfce <= '0';
flags_ifce <= '0';
flags_clc <= '0';
flags_cmc <= '0';
flags_stc <= '0';
flags_cli <= '0';
flags_sti <= '0';
marin_mux_sel <= "00";
mar_ce <= '0';
dfh_ce <= '0';
mdroin_mux_sel <= "000";
mdro_ce <= '0';
mdro_oe <= '0';
intr_sync_rst <= '0';
elsif rising_edge(CLK_I) then
SEL_O <= SEL_O_int ;
STB_O <= STB_O_int ;
CYC_O <= CYC_O_int ;
WE_O <= WE_O_int ;
INTA_CYC_O <= INTA_CYC_O_int ;
C_CYC_O <= C_CYC_O_int ;
I_CYC_O <= I_CYC_O_int ;
D_CYC_O <= D_CYC_O_int ;
intr_ce <= intr_ce_int ;
ir_ce <= ir_ce_int ;
mdri_ce <= mdri_ce_int ;
mdri_hl_zse_sign <= mdri_hl_zse_sign_int ;
intno_mux_sel <= intno_mux_sel_int ;
adin_mux_sel <= adin_mux_sel_int ;
rf_adwe <= rf_adwe_int ;
pcin_mux_sel <= pcin_mux_sel_int ;
pc_pre <= pc_pre_int ;
pc_ce <= pc_ce_int ;
spin_mux_sel <= spin_mux_sel_int ;
sp_pre <= sp_pre_int ;
sp_ce <= sp_ce_int ;
alua_mux_sel <= alua_mux_sel_int ;
alub_mux_sel <= alub_mux_sel_int ;
sbin_mux_sel <= sbin_mux_sel_int ;
asopsel <= asopsel_int ;
coszin_mux_sel <= coszin_mux_sel_int ;
flags_rst <= flags_rst_int ;
flags_ce <= flags_ce_int ;
flags_cfce <= flags_cfce_int ;
flags_ifce <= flags_ifce_int ;
flags_clc <= flags_clc_int ;
flags_cmc <= flags_cmc_int ;
flags_stc <= flags_stc_int ;
flags_cli <= flags_cli_int ;
flags_sti <= flags_sti_int ;
marin_mux_sel <= marin_mux_sel_int ;
mar_ce <= mar_ce_int ;
dfh_ce <= dfh_ce_int ;
mdroin_mux_sel <= mdroin_mux_sel_int ;
mdro_ce <= mdro_ce_int ;
mdro_oe <= mdro_oe_int ;
intr_sync_rst <= intr_sync_rst_int ;
end if;
end process;
-- since alu & shifter are not used simultanously...
aopsel <= asopsel(2 downto 0);
sopsel <= asopsel(2 downto 0);
asresult_mux_sel <= asopsel(3);
end rtlfast;
/vhdl/arith_arch_neutral.vhd
0,0 → 1,84
--------------------------------------------------------------
-- arith_arch_neutral.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: Generic Arithmetic unit of hpc-16 ALU
--
-- dependency: con_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_UNSIGNED.ALL;
 
entity arith is
PORT( c_out : OUT STD_LOGIC;
ofl_out : OUT STD_LOGIC;
s0 : IN STD_LOGIC;
c_in : IN STD_LOGIC;
s1 : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
b : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);
end arith;
 
--(s1,s0)---|--Operation--
---00-------|--sub--------
---01-------|--add--------
---10-------|--sbb--------
---11-------|--adc--------
 
architecture rtl of arith is
signal ci : std_logic;
signal sum : STD_LOGIC_VECTOR (15 DOWNTO 0);
signal temp : std_logic_vector(17 downto 0);
begin
ci <= c_in when s1 = '1' else
'0';
process (a, b, s0, ci)
begin
if(s0 = '1') then
temp <= ("0" & a & ci) + ("0" & b & "1");
else
temp <= ("0" & a & ci) - ("0" & b & "1");
end if;
end process;
sum <= temp(16 downto 1);
c_out <= temp(17) when s0 = '1' else
not temp(17);
ofl_out <= temp(17) xor sum(15) xor a(15) xor b(15);
result <= sum;
 
end rtl;
/vhdl/fcmp.vhd
0,0 → 1,155
--------------------------------------------------------------
-- fcmp.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: helps in conditional execution of jump and interrupts
--
-- dependency: none
--
-- 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;
 
 
entity fcmp is
port( tttnField_in : in std_logic_vector(3 downto 0); ---(COSZ)
flags_in : in std_logic_vector(3 downto 0);
result_out : out std_logic
);
end fcmp;
 
architecture Behavioral of fcmp is
begin
process(tttnField_in, flags_in) is
-----------------------------------------------------
-- "refactored" on 14Jan2006
-----------------------------------------------------
variable CF_in : std_logic;
variable OF_in : std_logic;
variable SF_in : std_logic;
variable ZF_in : std_logic;
begin
CF_in := flags_in(3);
OF_in := flags_in(2);
SF_in := flags_in(1);
ZF_in := flags_in(0);
 
case tttnField_in is
when "0000" => -- JO
if OF_in = '1' then
result_out <= '1';
else
result_out <= '0';
end if;
when "0001" => -- JNO
if OF_in = '0' then
result_out <= '1';
else
result_out <= '0';
end if;
when "0010" => -- JB or JNAE
if CF_in = '1' then
result_out <= '1';
else
result_out <= '0';
end if;
when "0011" => -- JNB or JAE
if CF_in = '0' then
result_out <= '1';
else
result_out <= '0';
end if;
when "0100" => -- JE or JZ
if ZF_in = '1' then
result_out <= '1';
else
result_out <= '0';
end if;
when "0101" => -- JNE or JNZ
if ZF_in = '0' then
result_out <= '1';
else
result_out <= '0';
end if;
when "0110" => -- JBE or JNA
if (CF_in or ZF_in) = '1' then
result_out <= '1';
else
result_out <= '0';
end if;
when "0111" => -- JNBE or JA
if (CF_in or ZF_in) = '0' then
result_out <= '1';
else
result_out <= '0';
end if;
when "1000" => -- JS
if SF_in = '1' then
result_out <= '1';
else
result_out <= '0';
end if;
when "1001" => -- JNS
if SF_in = '0' then
result_out <= '1';
else
result_out <= '0';
end if;
when "1010" =>
result_out <= '0';
when "1011" =>
result_out <= '0';
when "1100" => -- JL or JNGE
if (SF_in xor OF_in) = '1' then
result_out <= '1';
else
result_out <= '0';
end if;
when "1101" => -- JNL or JGE
if (SF_in xor OF_in) = '0' then
result_out <= '1';
else
result_out <= '0';
end if;
when "1110" => -- JLE or JNG
if ((SF_in xor OF_in) or ZF_in) = '1' then
result_out <= '1';
else
result_out <= '0';
end if;
when "1111" => -- JNLE or JG
if ((SF_in xor OF_in) or ZF_in) = '0' then
result_out <= '1';
else
result_out <= '0';
end if;
when others =>
result_out <= '0';
end case;
end process;
 
end Behavioral;
/vhdl/con_pkg.vhd
0,0 → 1,290
--------------------------------------------------------------
-- con_pkg.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: constants, component and type declarations for control unit(fsm)
--
-- dependency: sync.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;
 
package con_pkg is
 
-- intruction catagories
constant mov_rn_rm : std_logic_vector(7 downto 0) := b"00000_001";
constant mov_sp_rm : std_logic_vector(7 downto 0) := b"00000_010";
constant mov_rn_sp : std_logic_vector(7 downto 0) := b"00000_100";
 
constant ld_rn_rb : std_logic_vector(7 downto 0) := b"00001_000";
constant ld_rn_rb_disp : std_logic_vector(7 downto 0) := b"00001_001";
constant ld_rn_sp : std_logic_vector(7 downto 0) := b"00001_010";
constant ld_rn_sp_disp : std_logic_vector(7 downto 0) := b"00001_100";
 
constant st_rn_rb : std_logic_vector(7 downto 0) := b"00010_000";
constant st_rn_rb_disp : std_logic_vector(7 downto 0) := b"00010_001";
constant st_rn_sp : std_logic_vector(7 downto 0) := b"00010_010";
constant st_rn_sp_disp : std_logic_vector(7 downto 0) := b"00010_100";
constant lbzx_rn_rb : std_logic_vector(7 downto 0) := b"00011_000";
constant lbzx_rn_rb_disp : std_logic_vector(7 downto 0) := b"00011_100";
constant lbsx_rn_rb : std_logic_vector(7 downto 0) := b"00011_001";
constant lbsx_rn_rb_disp : std_logic_vector(7 downto 0) := b"00011_101";
 
constant sb_rn_rb : std_logic_vector(7 downto 0) := b"00100_001";
constant sb_rn_rb_disp : std_logic_vector(7 downto 0) := b"00100_010";
constant sing_dec : std_logic_vector(7 downto 0) := b"00101_000";
constant sing_inc : std_logic_vector(7 downto 0) := b"00101_001";
constant alur : std_logic_vector(4 downto 0) := "00110";
constant shiftr : std_logic_vector(4 downto 0) := "00111";
constant cmp_cmp : std_logic_vector(7 downto 0) := b"01000_000";
constant cmp_tst : std_logic_vector(7 downto 0) := b"01000_101";
constant li_rn : std_logic_vector(7 downto 0) := b"01001_001";
constant li_sp : std_logic_vector(7 downto 0) := b"01001_010";
constant alui : std_logic_vector(4 downto 0) := "01010";
constant shifti : std_logic_vector(4 downto 0) := "01011";
constant cmpi_cmp : std_logic_vector(7 downto 0) := b"01100_000";
constant cmpi_tst : std_logic_vector(7 downto 0) := b"01100_101";
constant alusp_sub : std_logic_vector(7 downto 0) := b"01101_000";
constant alusp_add : std_logic_vector(7 downto 0) := b"01101_001";
constant stk_pushr : std_logic_vector(7 downto 0) := b"01110_000";
constant stk_pushf : std_logic_vector(7 downto 0) := b"01110_001";
constant stk_popr : std_logic_vector(7 downto 0) := b"01110_100";
constant stk_popf : std_logic_vector(7 downto 0) := b"01110_101";
constant acall : std_logic_vector(7 downto 0) := b"01111_001";
 
constant lcall : std_logic_vector(7 downto 0) := b"01111_010";
constant scall : std_logic_vector(4 downto 0) := "10000";
constant ret : std_logic_vector(4 downto 0) := "10001";
constant int : std_logic_vector(4 downto 0) := "10010";
constant into : std_logic_vector(4 downto 0) := "10011";
constant iret : std_logic_vector(4 downto 0) := "10100";
constant ajmp : std_logic_vector(7 downto 0) := b"10101_001";
 
constant ljmp : std_logic_vector(7 downto 0) := b"10101_010";
constant sjmp : std_logic_vector(4 downto 0) := "10110";
constant jcc : std_logic_vector(4 downto 0) := "10111";
constant fop_clc : std_logic_vector(7 downto 0) := b"11000_000";
constant fop_stc : std_logic_vector(7 downto 0) := b"11000_001";
constant fop_cmc : std_logic_vector(7 downto 0) := b"11000_010";
constant fop_cli : std_logic_vector(7 downto 0) := b"11000_100";
constant fop_sti : std_logic_vector(7 downto 0) := b"11000_101";
constant nop : std_logic_vector(4 downto 0) := "11110";
constant hlt : std_logic_vector(4 downto 0) := "11111";
 
-- subop/subtype field
 
constant a_sub : std_logic_vector(2 downto 0) := "000";
constant a_add : std_logic_vector(2 downto 0) := "001";
constant a_sbb : std_logic_vector(2 downto 0) := "010";
constant a_adc : std_logic_vector(2 downto 0) := "011";
constant a_not : std_logic_vector(2 downto 0) := "100";
constant a_and : std_logic_vector(2 downto 0) := "101";
constant a_or : std_logic_vector(2 downto 0) := "110";
constant a_xor : std_logic_vector(2 downto 0) := "111";
 
constant s_sll : std_logic_vector(2 downto 0) := "000";
constant s_slr : std_logic_vector(2 downto 0) := "001";
constant s_sal : std_logic_vector(2 downto 0) := "010";
constant s_sar : std_logic_vector(2 downto 0) := "011";
constant s_rol : std_logic_vector(2 downto 0) := "100";
constant s_ror : std_logic_vector(2 downto 0) := "101";
constant s_rcl : std_logic_vector(2 downto 0) := "110";
constant s_rcr : std_logic_vector(2 downto 0) := "111";
 
-- alu operations
constant asopsel_sub : std_logic_vector(3 downto 0) := "0000";
constant asopsel_add : std_logic_vector(3 downto 0) := "0001";
constant asopsel_sbb : std_logic_vector(3 downto 0) := "0010";
constant asopsel_adc : std_logic_vector(3 downto 0) := "0011";
constant asopsel_not : std_logic_vector(3 downto 0) := "0100";
constant asopsel_and : std_logic_vector(3 downto 0) := "0101";
constant asopsel_or : std_logic_vector(3 downto 0) := "0110";
constant asopsel_xor : std_logic_vector(3 downto 0) := "0111";
 
-- shifter operations
constant asopsel_sll : std_logic_vector(3 downto 0) := "1000";
constant asopsel_slr : std_logic_vector(3 downto 0) := "1001";
constant asopsel_sal : std_logic_vector(3 downto 0) := "1010";
constant asopsel_sar : std_logic_vector(3 downto 0) := "1011";
constant asopsel_rol : std_logic_vector(3 downto 0) := "1100";
constant asopsel_ror : std_logic_vector(3 downto 0) := "1101";
constant asopsel_rcl : std_logic_vector(3 downto 0) := "1110";
constant asopsel_rcr : std_logic_vector(3 downto 0) := "1111";
 
constant intno_mux_sel_invalid : std_logic_vector(2 downto 0) := "000";
constant intno_mux_sel_align : std_logic_vector(2 downto 0) := "001";
constant intno_mux_sel_stk : std_logic_vector(2 downto 0) := "010";
constant intno_mux_sel_df : std_logic_vector(2 downto 0) := "011";
constant intno_mux_sel_ir : std_logic_vector(2 downto 0) := "100";
constant intno_mux_sel_intr : std_logic_vector(2 downto 0) := "101";
 
constant adin_mux_sel_tr2 : std_logic_vector(2 downto 0) := "000";
constant adin_mux_sel_tr5 : std_logic_vector(2 downto 0) := "001";
constant adin_mux_sel_sp : std_logic_vector(2 downto 0) := "010";
constant adin_mux_sel_mdri : std_logic_vector(2 downto 0) := "011";
constant adin_mux_sel_mdri_high : std_logic_vector(2 downto 0) := "100";
constant adin_mux_sel_mdri_low : std_logic_vector(2 downto 0) := "101";
 
constant pcin_mux_sel_aluout : std_logic_vector(1 downto 0) := "00";
constant pcin_mux_sel_intno : std_logic_vector(1 downto 0) := "01";
constant pcin_mux_sel_mdri : std_logic_vector(1 downto 0) := "10";
 
constant spin_mux_sel_aluout : std_logic := '0';
constant spin_mux_sel_mdri : std_logic := '1';
 
constant alua_mux_sel_pc : std_logic_vector(1 downto 0) := "00";
constant alua_mux_sel_sp : std_logic_vector(1 downto 0) := "01";
constant alua_mux_sel_tr1 : std_logic_vector(1 downto 0) := "10";
constant alua_mux_sel_tr2 : std_logic_vector(1 downto 0) := "11";
 
constant alub_mux_sel_tr2 : std_logic_vector(2 downto 0) := "000";
constant alub_mux_sel_2 : std_logic_vector(2 downto 0) := "001";
constant alub_mux_sel_1 : std_logic_vector(2 downto 0) := "010";
constant alub_mux_sel_0 : std_logic_vector(2 downto 0) := "011";
constant alub_mux_sel_tr3 : std_logic_vector(2 downto 0) := "100";
constant alub_mux_sel_tr4 : std_logic_vector(2 downto 0) := "101";
constant alub_mux_sel_mdri : std_logic_vector(2 downto 0) := "110";
 
constant sbin_mux_sel_tr2 : std_logic := '0';
constant sbin_mux_sel_ir : std_logic := '1';
 
constant coszin_mux_sel_asresult : std_logic := '0';
constant coszin_mux_sel_mdri : std_logic := '1';
 
constant marin_mux_sel_pc : std_logic_vector(1 downto 0) := "00";
constant marin_mux_sel_aluout : std_logic_vector(1 downto 0) := "01";
constant marin_mux_sel_sp : std_logic_vector(1 downto 0) := "10";
 
constant mdroin_mux_sel_pc : std_logic_vector(2 downto 0) := "000";
constant mdroin_mux_sel_tr1 : std_logic_vector(2 downto 0) := "001";
constant mdroin_mux_sel_flags : std_logic_vector(2 downto 0) := "010";
constant mdroin_mux_sel_dfh : std_logic_vector(2 downto 0) := "011";
constant mdroin_mux_sel_intno : std_logic_vector(2 downto 0) := "100";
constant mdroin_mux_sel_tr1_loweven : std_logic_vector(2 downto 0) := "101";
constant mdroin_mux_sel_tr1_lowodd : std_logic_vector(2 downto 0) := "110";
type ic is (
ic_mov_rn_rm, ic_mov_sp_rm, ic_mov_rn_sp,
 
ic_ld_rn_rb, ic_ld_rn_rb_disp, ic_ld_rn_sp, ic_ld_rn_sp_disp,
 
ic_st_rn_rb, ic_st_rn_rb_disp, ic_st_rn_sp, ic_st_rn_sp_disp,
ic_lbzx_rn_rb, ic_lbzx_rn_rb_disp, ic_lbsx_rn_rb, ic_lbsx_rn_rb_disp,
 
ic_sb_rn_rb, ic_sb_rn_rb_disp,
ic_sing_dec, ic_sing_inc,
ic_alur,
ic_shiftr,
ic_cmp_cmp, ic_cmp_tst,
ic_li_rn, ic_li_sp,
ic_alui,
ic_shifti,
ic_cmpi_cmp, ic_cmpi_tst,
ic_alusp_sub, ic_alusp_add,
ic_stk_pushr, ic_stk_pushf, ic_stk_popr, ic_stk_popf,
ic_acall, ic_lcall, ic_scall,
ic_ret,
ic_int,
ic_into,
ic_iret,
ic_ajmp, ic_ljmp, ic_sjmp,
ic_jcc,
ic_fop_clc, ic_fop_stc, ic_fop_cmc, ic_fop_cli, ic_fop_sti,
ic_nop,
ic_hlt,
 
ic_invalid);
 
type state is (
reset,
fetch0, fetch1, fetch2,
exec0, exec1, exec2, exec3, exec4, exec5,
int_chk,
int0, int1, int2, int3, int4,
align0, align1, align2, align3, align4,
stkerr0, stkerr1, stkerr2, stkerr3, stkerr4, stkerr5, stkerr6, stkerr7,
invalid0, invalid1, invalid2, invalid3, invalid4,
df0, df1, df2, df3, df4, df5, df6, df7, df8, df9,
halted
);
component sync is
port
(
d : in std_logic;
clk : in std_logic;
q : out std_logic
);
end component;
end package;
/vhdl/sync.vhd
0,0 → 1,60
--------------------------------------------------------------
-- sync.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: synchronizer, 2 cascaded DFF
--
-- dependency: none
--
-- 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;
 
entity sync is
port
(
d : in std_logic;
clk : in std_logic;
q : out std_logic
);
end sync;
 
architecture behave2 of sync is
signal t : std_logic;
begin
process(clk , d)
begin
if d = '1' then
t <= '1';
q <= '1';
elsif rising_edge(clk) then
t <= '0';
q <= t;
end if;
end process;
end behave2;
 
/vhdl/alu.vhd
0,0 → 1,119
--------------------------------------------------------------
-- alu.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: ALU of microprocessor
--
-- dependency: log.vhd, arith.sch
--
-- 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;
 
--Opsel_in--|--ALU Operation--
--000-------|--sub------------
--001-------|--add------------
--010-------|--sbb------------
--011-------|--adc------------
--100-------|--not------------
--101-------|--and------------
--110-------|--or-------------
--111-------|--xor------------
 
entity alu is
port(
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
opsel : in std_logic_vector(2 downto 0);
c_in : in std_logic;
result: out std_logic_vector(15 downto 0);
c_out: out std_logic;
ofl_out: out std_logic
);
end alu;
 
architecture struct of alu is
COMPONENT arith
PORT( c_out : OUT STD_LOGIC;
ofl_out : OUT STD_LOGIC;
s0 : IN STD_LOGIC;
c_in : IN STD_LOGIC;
s1 : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
b : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
result : OUT STD_LOGIC_VECTOR (15 DOWNTO 0));
END COMPONENT;
 
component log
port ( a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
s0 : in std_logic;
s1 : in std_logic;
result : out std_logic_vector(15 downto 0)
);
end component;
signal cout_temp : std_logic;
signal ofl_temp : std_logic;
signal result_arith : std_logic_vector(15 downto 0);
signal result_log : std_logic_vector(15 downto 0);
signal result_temp : std_logic_vector(15 downto 0);
 
begin
u1 : arith
PORT map ( c_out => cout_temp,
ofl_out => ofl_temp,
s0 => opsel(0),
c_in => c_in,
s1 => opsel(1),
a => a,
b => b,
result => result_arith
);
 
u2 : log
port map ( a => a,
b => b,
s0 => opsel(0),
s1 => opsel(1),
result => result_log
);
 
 
result_temp <= result_arith when opsel(2) = '0' else
result_log;
result <= result_temp;
 
c_out <= cout_temp when opsel(2) = '0' else
'0';
ofl_out <= ofl_temp when opsel(2) = '0' else
'0';
 
end struct;
/vhdl/log.vhd
0,0 → 1,55
--------------------------------------------------------------
-- log.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: component of ALU, performs logical operations
--
-- dependency: none
--
-- 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;
 
entity log is
port ( a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
s0 : in std_logic;
s1 : in std_logic;
result : out std_logic_vector(15 downto 0)
);
end log;
 
architecture dataflow of log is
signal sel : std_logic_vector(1 downto 0);
begin
sel <= s1 & s0;
result <= not a when sel = "00" else
a and b when sel = "01" else
a or b when sel = "10" else
a xor b;
end dataflow;
/vhdl/arith.sch
0,0 → 1,238
VERSION 6
BEGIN SCHEMATIC
BEGIN ATTR DeviceFamilyName "spartan3"
DELETE all:0
EDITNAME all:0
EDITTRAIT all:0
END ATTR
BEGIN NETLIST
SIGNAL c_out
SIGNAL ofl_out
SIGNAL XLXN_14
SIGNAL XLXN_15
SIGNAL s0
SIGNAL XLXN_18
SIGNAL zero_i
SIGNAL XLXN_24
SIGNAL c_in
SIGNAL XLXN_29
SIGNAL XLXN_30
SIGNAL s1
SIGNAL a(15:0)
SIGNAL b(15:0)
SIGNAL XLXN_35
SIGNAL result(15:0)
PORT Output c_out
PORT Output ofl_out
PORT Input s0
PORT Input c_in
PORT Input s1
PORT Input a(15:0)
PORT Input b(15:0)
PORT Output result(15:0)
BEGIN BLOCKDEF adsu16
TIMESTAMP 2001 2 2 12 35 41
LINE N 240 -64 384 -64
LINE N 240 -124 240 -64
RECTANGLE N 0 -204 64 -180
RECTANGLE N 0 -332 64 -308
RECTANGLE N 384 -268 448 -244
LINE N 128 -448 64 -448
LINE N 128 -416 128 -448
LINE N 128 -64 48 -64
LINE N 128 -96 128 -64
LINE N 64 -288 64 -432
LINE N 128 -256 64 -288
LINE N 64 -224 128 -256
LINE N 64 -80 64 -224
LINE N 384 -160 64 -80
LINE N 384 -336 384 -160
LINE N 384 -352 384 -336
LINE N 64 -432 384 -352
LINE N 336 -128 336 -148
LINE N 384 -128 336 -128
LINE N 448 -256 384 -256
LINE N 448 -128 384 -128
LINE N 448 -64 384 -64
LINE N 0 -448 64 -448
LINE N 0 -192 64 -192
LINE N 0 -320 64 -320
LINE N 0 -64 64 -64
END BLOCKDEF
BEGIN BLOCKDEF m2_1
TIMESTAMP 2001 2 2 12 39 29
LINE N 96 -64 96 -192
LINE N 256 -96 96 -64
LINE N 256 -160 256 -96
LINE N 96 -192 256 -160
LINE N 176 -32 96 -32
LINE N 176 -80 176 -32
LINE N 0 -32 96 -32
LINE N 320 -128 256 -128
LINE N 0 -96 96 -96
LINE N 0 -160 96 -160
END BLOCKDEF
BEGIN BLOCKDEF gnd
TIMESTAMP 2001 2 2 12 37 29
LINE N 64 -64 64 -96
LINE N 76 -48 52 -48
LINE N 68 -32 60 -32
LINE N 88 -64 40 -64
LINE N 64 -64 64 -80
LINE N 64 -128 64 -96
END BLOCKDEF
BEGIN BLOCKDEF inv
TIMESTAMP 2001 2 2 12 38 38
LINE N 0 -32 64 -32
LINE N 224 -32 160 -32
LINE N 64 -64 128 -32
LINE N 128 -32 64 0
LINE N 64 0 64 -64
CIRCLE N 128 -48 160 -16
END BLOCKDEF
BEGIN BLOCK XLXI_1 adsu16
PIN A(15:0) a(15:0)
PIN ADD s0
PIN B(15:0) b(15:0)
PIN CI XLXN_35
PIN CO XLXN_14
PIN OFL ofl_out
PIN S(15:0) result(15:0)
END BLOCK
BEGIN BLOCK XLXI_2 m2_1
PIN D0 XLXN_15
PIN D1 XLXN_14
PIN S0 s0
PIN O c_out
END BLOCK
BEGIN BLOCK XLXI_10 inv
PIN I XLXN_14
PIN O XLXN_15
END BLOCK
BEGIN BLOCK XLXI_3 m2_1
PIN D0 XLXN_29
PIN D1 XLXN_30
PIN S0 s1
PIN O XLXN_35
END BLOCK
BEGIN BLOCK XLXI_11 m2_1
PIN D0 XLXN_18
PIN D1 zero_i
PIN S0 s0
PIN O XLXN_29
END BLOCK
BEGIN BLOCK XLXI_8 inv
PIN I zero_i
PIN O XLXN_18
END BLOCK
BEGIN BLOCK XLXI_4 m2_1
PIN D0 XLXN_24
PIN D1 c_in
PIN S0 s0
PIN O XLXN_30
END BLOCK
BEGIN BLOCK XLXI_13 inv
PIN I c_in
PIN O XLXN_24
END BLOCK
BEGIN BLOCK XLXI_14 gnd
PIN G zero_i
END BLOCK
END NETLIST
BEGIN SHEET 1 3520 2720
INSTANCE XLXI_1 1824 1552 R0
INSTANCE XLXI_2 2576 1648 R0
BEGIN BRANCH c_out
WIRE 2896 1520 2960 1520
WIRE 2960 1520 3024 1520
BEGIN DISPLAY 2960 1520 ATTR Name
ALIGNMENT SOFT-BCENTER
END DISPLAY
END BRANCH
BEGIN BRANCH ofl_out
WIRE 2272 1424 2336 1424
WIRE 2336 1424 2416 1424
BEGIN DISPLAY 2336 1424 ATTR Name
ALIGNMENT SOFT-BCENTER
END DISPLAY
END BRANCH
INSTANCE XLXI_10 2320 1520 R0
BEGIN BRANCH XLXN_14
WIRE 2272 1488 2320 1488
WIRE 2272 1488 2272 1552
WIRE 2272 1552 2576 1552
END BRANCH
BEGIN BRANCH XLXN_15
WIRE 2544 1488 2576 1488
END BRANCH
BEGIN BRANCH s0
WIRE 544 1616 816 1616
WIRE 816 1616 1824 1616
WIRE 1824 1616 2576 1616
WIRE 816 912 944 912
WIRE 816 912 816 1232
WIRE 816 1232 816 1616
WIRE 816 1232 944 1232
WIRE 1824 1488 1824 1616
BEGIN DISPLAY 816 912 ATTR Name
ALIGNMENT SOFT-BCENTER
END DISPLAY
END BRANCH
INSTANCE XLXI_3 1360 1232 R0
BEGIN BRANCH XLXN_18
WIRE 912 784 944 784
END BRANCH
INSTANCE XLXI_11 944 944 R0
INSTANCE XLXI_8 688 816 R0
BEGIN BRANCH zero_i
WIRE 592 784 656 784
WIRE 656 784 656 848
WIRE 656 848 944 848
WIRE 656 784 688 784
END BRANCH
INSTANCE XLXI_4 944 1264 R0
INSTANCE XLXI_13 640 1136 R0
BEGIN BRANCH XLXN_24
WIRE 864 1104 944 1104
END BRANCH
BEGIN BRANCH c_in
WIRE 464 1104 528 1104
WIRE 528 1104 640 1104
WIRE 528 1104 528 1168
WIRE 528 1168 944 1168
END BRANCH
BEGIN BRANCH XLXN_29
WIRE 1264 816 1312 816
WIRE 1312 816 1312 1072
WIRE 1312 1072 1360 1072
END BRANCH
BEGIN BRANCH XLXN_30
WIRE 1264 1136 1360 1136
END BRANCH
BEGIN BRANCH s1
WIRE 1152 1296 1360 1296
WIRE 1360 1200 1360 1296
END BRANCH
BEGIN BRANCH a(15:0)
WIRE 1648 1232 1824 1232
END BRANCH
BEGIN BRANCH b(15:0)
WIRE 1648 1360 1824 1360
END BRANCH
BEGIN BRANCH XLXN_35
WIRE 1680 1104 1824 1104
END BRANCH
BEGIN BRANCH result(15:0)
WIRE 2272 1296 2448 1296
END BRANCH
INSTANCE XLXI_14 528 912 R0
IOMARKER 3024 1520 c_out R0 28
IOMARKER 2416 1424 ofl_out R0 28
IOMARKER 464 1104 c_in R180 28
IOMARKER 1152 1296 s1 R180 28
IOMARKER 544 1616 s0 R180 28
IOMARKER 1648 1232 a(15:0) R180 28
IOMARKER 1648 1360 b(15:0) R180 28
IOMARKER 2448 1296 result(15:0) R0 28
END SHEET
END SCHEMATIC
/vhdl/dp.vhd
0,0 → 1,663
--------------------------------------------------------------
-- 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;
/vhdl/dp_pkg.vhd
0,0 → 1,112
--------------------------------------------------------------
-- dp_pkg.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: component declarations for datapath, constant
-- declarations for predefined interrupt vectors
--
-- dependency: alu.vhd, shifter.vhd, regfile.vhd, flags.vhd, fcmp.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;
 
package dp_pkg is
component alu is
port(
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
opsel : in std_logic_vector(2 downto 0);
c_in : in std_logic;
result: out std_logic_vector(15 downto 0);
c_out: out std_logic;
ofl_out: out std_logic
);
end component;
component shifter is
port
(
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(3 downto 0);
c_in : in std_logic;
opsel : in std_logic_vector(2 downto 0);
result : out std_logic_vector(15 downto 0);
c_out : out std_logic;
ofl_out : out std_logic
);
end component;
component regfile is
port(
aadr : in std_logic_vector(3 downto 0);
badr : in std_logic_vector(3 downto 0);
ad : in std_logic_vector(15 downto 0);
adwe : in std_logic;
clk : in std_logic;
aq : out std_logic_vector(15 downto 0);
bq : out std_logic_vector(15 downto 0)
);
end component;
component flags is
port(
 
Flags_in : in std_logic_vector(4 downto 0);
CLK_in : in std_logic;
 
ResetAll_in : in std_logic;
CE_in : in std_logic;
CFCE_in : in std_logic;
IFCE_in : in std_logic;
CLC_in : in std_logic;
CMC_in : in std_logic;
STC_in : in std_logic;
STI_in : in std_logic;
CLI_in : in std_logic;
 
Flags_out : out std_logic_vector(4 downto 0)
 
);
 
end component;
component fcmp is
port( tttnField_in : in std_logic_vector(3 downto 0); ---(COSZ)
flags_in : in std_logic_vector(3 downto 0);
result_out : out std_logic
);
end component;
constant invaild_inst_vec : std_logic_vector(3 downto 0) := "0001";
constant align_err_vec : std_logic_vector(3 downto 0) := "0010";
constant stack_err_vec : std_logic_vector(3 downto 0) := "0011";
constant df_err_vec : std_logic_vector(3 downto 0) := "0100";
end package;
/vhdl/shifter.vhd
0,0 → 1,271
--------------------------------------------------------------
-- shifter.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: combinational shifter
--
-- dependency: none
--
-- 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 ieee.std_logic_unsigned.all;
 
--Opsel-----|--shifter Operation--
--000-------|--sll----------------
--001-------|--slr----------------
--010-------|--sal----------------
--011-------|--sar----------------
--100-------|--rol----------------
--101-------|--ror----------------
--110-------|--rcl----------------
--111-------|--rcr----------------
 
entity shifter is
port
(
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(3 downto 0);
c_in : in std_logic;
opsel : in std_logic_vector(2 downto 0);
result : out std_logic_vector(15 downto 0);
c_out : out std_logic;
ofl_out : out std_logic
);
end shifter;
 
architecture dataflow of shifter is
signal shltemp, shrtemp, saltemp, sartemp, roltemp,
rortemp, rcltemp, rcrtemp, carry_result : std_logic_vector(16 downto 0);
begin
ShiftLogicalLeft: process(a , b, c_in) is
begin
case b is
when "0000" => shltemp <= c_in & a(15 downto 0);
when "0001" => shltemp <= a(15) & a(14 downto 0) & "0";
when "0010" => shltemp <= a(14) & a(13 downto 0) & "00";
when "0011" => shltemp <= a(13) & a(12 downto 0) & "000";
when "0100" => shltemp <= a(12) & a(11 downto 0) & "0000";
when "0101" => shltemp <= a(11) & a(10 downto 0) & "00000";
when "0110" => shltemp <= a(10) & a(09 downto 0) & "000000";
when "0111" => shltemp <= a(09) & a(08 downto 0) & "0000000";
when "1000" => shltemp <= a(08) & a(07 downto 0) & "00000000";
when "1001" => shltemp <= a(07) & a(06 downto 0) & "000000000";
when "1010" => shltemp <= a(06) & a(05 downto 0) & "0000000000";
when "1011" => shltemp <= a(05) & a(04 downto 0) & "00000000000";
when "1100" => shltemp <= a(04) & a(03 downto 0) & "000000000000";
when "1101" => shltemp <= a(03) & a(02 downto 0) & "0000000000000";
when "1110" => shltemp <= a(02) & a(01 downto 0) & "00000000000000";
when "1111" => shltemp <= a(01) & a(00) & "000000000000000";
when others => shltemp <= (others => '0');
end case;
end process;
ShiftLogicalRight: process(a, b, c_in) is
begin
case b is
when "0000" => shrtemp <= c_in & a(15 downto 0);
when "0001" => shrtemp <= a(00) & "0" & a(15 downto 01);
when "0010" => shrtemp <= a(01) & "00" & a(15 downto 02);
when "0011" => shrtemp <= a(02) & "000" & a(15 downto 03);
when "0100" => shrtemp <= a(03) & "0000" & a(15 downto 04);
when "0101" => shrtemp <= a(04) & "00000" & a(15 downto 05);
when "0110" => shrtemp <= a(05) & "000000" & a(15 downto 06);
when "0111" => shrtemp <= a(06) & "0000000" & a(15 downto 07);
when "1000" => shrtemp <= a(07) & "00000000" & a(15 downto 08);
when "1001" => shrtemp <= a(08) & "000000000" & a(15 downto 09);
when "1010" => shrtemp <= a(09) & "0000000000" & a(15 downto 10);
when "1011" => shrtemp <= a(10) & "00000000000" & a(15 downto 11);
when "1100" => shrtemp <= a(11) & "000000000000" & a(15 downto 12);
when "1101" => shrtemp <= a(12) & "0000000000000" & a(15 downto 13);
when "1110" => shrtemp <= a(13) & "00000000000000" & a(15 downto 14);
when "1111" => shrtemp <= a(14) & "000000000000000" & a(15);
when others => shrtemp <= (others => '0');
end case;
end process;
ShiftArithmaticLeft: saltemp <= shltemp;
ShiftArithmaticRight: process(a, b, c_in) is
variable s : std_logic;
begin
s := a(15);
case b is
when "0000" => sartemp <= c_in & a(15 downto 0);
when "0001" => sartemp <= a(00) & s & a(15 downto 01);
when "0010" => sartemp <= a(01) & s & s & a(15 downto 02);
when "0011" => sartemp <= a(02) & s & s & s & a(15 downto 03);
when "0100" => sartemp <= a(03) & s & s & s & s & a(15 downto 04);
when "0101" => sartemp <= a(04) & s & s & s & s & s & a(15 downto 05);
when "0110" => sartemp <= a(05) & s & s & s & s & s & s & a(15 downto 06);
when "0111" => sartemp <= a(06) & s & s & s & s & s & s & s & a(15 downto 07);
when "1000" => sartemp <= a(07) & s & s & s & s & s & s & s & s & a(15 downto 08);
when "1001" => sartemp <= a(08) & s & s & s & s & s & s & s & s & s & a(15 downto 09);
when "1010" => sartemp <= a(09) & s & s & s & s & s & s & s & s & s & s & a(15 downto 10);
when "1011" => sartemp <= a(10) & s & s & s & s & s & s & s & s & s & s & s & a(15 downto 11);
when "1100" => sartemp <= a(11) & s & s & s & s & s & s & s & s & s & s & s & s & a(15 downto 12);
when "1101" => sartemp <= a(12) & s & s & s & s & s & s & s & s & s & s & s & s & s & a(15 downto 13);
when "1110" => sartemp <= a(13) & s & s & s & s & s & s & s & s & s & s & s & s & s & s & a(15 downto 14);
when "1111" => sartemp <= a(14) & s & s & s & s & s & s & s & s & s & s & s & s & s & s & s & a(15);
when others => sartemp <= (others => '0');
end case;
end process;
RotateLeft: process(a, b, c_in) is
begin
case b is
when "0000" => roltemp <= c_in & a(15 downto 0);
when "0001" => roltemp <= a(15) & a(14 downto 0) & a(15);
when "0010" => roltemp <= a(14) & a(13 downto 0) & a(15 downto 14);
when "0011" => roltemp <= a(13) & a(12 downto 0) & a(15 downto 13);
when "0100" => roltemp <= a(12) & a(11 downto 0) & a(15 downto 12);
when "0101" => roltemp <= a(11) & a(10 downto 0) & a(15 downto 11);
when "0110" => roltemp <= a(10) & a(09 downto 0) & a(15 downto 10);
when "0111" => roltemp <= a(09) & a(08 downto 0) & a(15 downto 09);
when "1000" => roltemp <= a(08) & a(07 downto 0) & a(15 downto 08);
when "1001" => roltemp <= a(07) & a(06 downto 0) & a(15 downto 07);
when "1010" => roltemp <= a(06) & a(05 downto 0) & a(15 downto 06);
when "1011" => roltemp <= a(05) & a(04 downto 0) & a(15 downto 05);
when "1100" => roltemp <= a(04) & a(03 downto 0) & a(15 downto 04);
when "1101" => roltemp <= a(03) & a(02 downto 0) & a(15 downto 03);
when "1110" => roltemp <= a(02) & a(01 downto 0) & a(15 downto 02);
when "1111" => roltemp <= a(01) & a(00) & a(15 downto 01);
when others => roltemp <= (others => '0');
end case;
end process;
 
RotateRight: process(a, b, c_in) is
begin
case b is
when "0000" => rortemp <= c_in & a(15 downto 0);
when "0001" => rortemp <= a(00) & a(00) & a(15 downto 1);
when "0010" => rortemp <= a(01) & a(01 downto 0) & a(15 downto 02);
when "0011" => rortemp <= a(02) & a(02 downto 0) & a(15 downto 03);
when "0100" => rortemp <= a(03) & a(03 downto 0) & a(15 downto 04);
when "0101" => rortemp <= a(04) & a(04 downto 0) & a(15 downto 05);
when "0110" => rortemp <= a(05) & a(05 downto 0) & a(15 downto 06);
when "0111" => rortemp <= a(06) & a(06 downto 0) & a(15 downto 07);
when "1000" => rortemp <= a(07) & a(07 downto 0) & a(15 downto 08);
when "1001" => rortemp <= a(08) & a(08 downto 0) & a(15 downto 09);
when "1010" => rortemp <= a(09) & a(09 downto 0) & a(15 downto 10);
when "1011" => rortemp <= a(10) & a(10 downto 0) & a(15 downto 11);
when "1100" => rortemp <= a(11) & a(11 downto 0) & a(15 downto 12);
when "1101" => rortemp <= a(12) & a(12 downto 0) & a(15 downto 13);
when "1110" => rortemp <= a(13) & a(13 downto 0) & a(15 downto 14);
when "1111" => rortemp <= a(14) & a(14 downto 0) & a(15);
when others => rortemp <= (others => '0');
end case;
end process;
 
RotateCarryLeft: process(a, b, c_in) is
begin
case b is
when "0000" => rcltemp <= c_in & a(15 downto 0);
when "0001" => rcltemp <= a(15) & a(14 downto 0) & c_in;
when "0010" => rcltemp <= a(14) & a(13 downto 0) & c_in & a(15);
when "0011" => rcltemp <= a(13) & a(12 downto 0) & c_in & a(15 downto 14);
when "0100" => rcltemp <= a(12) & a(11 downto 0) & c_in & a(15 downto 13);
when "0101" => rcltemp <= a(11) & a(10 downto 0) & c_in & a(15 downto 12);
when "0110" => rcltemp <= a(10) & a(09 downto 0) & c_in & a(15 downto 11);
when "0111" => rcltemp <= a(09) & a(08 downto 0) & c_in & a(15 downto 10);
when "1000" => rcltemp <= a(08) & a(07 downto 0) & c_in & a(15 downto 09);
when "1001" => rcltemp <= a(07) & a(06 downto 0) & c_in & a(15 downto 08);
when "1010" => rcltemp <= a(06) & a(05 downto 0) & c_in & a(15 downto 07);
when "1011" => rcltemp <= a(05) & a(04 downto 0) & c_in & a(15 downto 06);
when "1100" => rcltemp <= a(04) & a(03 downto 0) & c_in & a(15 downto 05);
when "1101" => rcltemp <= a(03) & a(02 downto 0) & c_in & a(15 downto 04);
when "1110" => rcltemp <= a(02) & a(01 downto 0) & c_in & a(15 downto 03);
when "1111" => rcltemp <= a(01) & a(00) & c_in & a(15 downto 02);
when others => rcltemp <= (others => '0');
end case;
end process;
 
RotateCarryRight: process(a, b, c_in) is
begin
case b is
when "0000" => rcrtemp <= c_in & a(15 downto 0);
when "0001" => rcrtemp <= a(00) & c_in & a(15 downto 1);
when "0010" => rcrtemp <= a(01) & a(0) & c_in & a(15 downto 2);
when "0011" => rcrtemp <= a(02) & a(01 downto 0) & c_in & a(15 downto 03);
when "0100" => rcrtemp <= a(03) & a(02 downto 0) & c_in & a(15 downto 04);
when "0101" => rcrtemp <= a(04) & a(03 downto 0) & c_in & a(15 downto 05);
when "0110" => rcrtemp <= a(05) & a(04 downto 0) & c_in & a(15 downto 06);
when "0111" => rcrtemp <= a(06) & a(05 downto 0) & c_in & a(15 downto 07);
when "1000" => rcrtemp <= a(07) & a(06 downto 0) & c_in & a(15 downto 08);
when "1001" => rcrtemp <= a(08) & a(07 downto 0) & c_in & a(15 downto 09);
when "1010" => rcrtemp <= a(09) & a(08 downto 0) & c_in & a(15 downto 10);
when "1011" => rcrtemp <= a(10) & a(09 downto 0) & c_in & a(15 downto 11);
when "1100" => rcrtemp <= a(11) & a(10 downto 0) & c_in & a(15 downto 12);
when "1101" => rcrtemp <= a(12) & a(11 downto 0) & c_in & a(15 downto 13);
when "1110" => rcrtemp <= a(13) & a(12 downto 0) & c_in & a(15 downto 14);
when "1111" => rcrtemp <= a(14) & a(13 downto 0) & c_in & a(15);
when others => rcrtemp <= (others => '0');
end case;
end process;
 
with opsel select
carry_result <= shltemp when "000",
shrtemp when "001",
saltemp when "010",
sartemp when "011",
roltemp when "100",
rortemp when "101",
rcltemp when "110",
rcrtemp when "111",
(others => '0') when others;
 
result <= carry_result(15 downto 0);
 
c_out <= carry_result(16);
 
-- overflow is defined for 1-bit shift/rotates
process(carry_result, opsel, a) is begin
case opsel is
when "000" => -- sll
ofl_out <= carry_result(15) xor carry_result(16);
when "001" => -- slr
ofl_out <= a(15);
when "010" => -- sal
ofl_out <= carry_result(15) xor carry_result(16);
when "011" => -- sar
ofl_out <= '0';
when "100" => -- rol
ofl_out <= carry_result(15) xor carry_result(16);
when "101" => -- ror
ofl_out <= carry_result(15) xor carry_result(14);
when "110" => -- rcl
ofl_out <= carry_result(15) xor carry_result(16);
when "111" => -- rcr
ofl_out <= carry_result(15) xor carry_result(14);
when others =>
ofl_out <= '0';
end case;
end process;
 
end dataflow;
/vhdl/cpu_pkg.vhd
0,0 → 1,149
--------------------------------------------------------------
-- cpu_pkg.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: component declaration of datapath and control unit
--
-- dependency: dp.vhd, con1.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;
 
package cpu_pkg is
COMPONENT con1
PORT(
CLK_I : IN std_logic;
RST_I : IN std_logic;
ACK_I : IN std_logic;
INTR_I : IN std_logic;
jcc_ok : IN std_logic;
int_flag : IN std_logic;
pc0 : IN std_logic;
sp0 : IN std_logic;
mar0 : IN std_logic;
tr20 : IN std_logic;
ir_high : IN std_logic_vector(7 downto 0);
SEL_O : OUT std_logic_vector(1 downto 0);
STB_O : OUT std_logic;
CYC_O : OUT std_logic;
WE_O : OUT std_logic;
INTA_CYC_O : OUT std_logic;
C_CYC_O : OUT std_logic;
I_CYC_O : OUT std_logic;
D_CYC_O : OUT std_logic;
intr_ce : OUT std_logic;
ir_ce : OUT std_logic;
mdri_ce : OUT std_logic;
mdri_hl_zse_sign : OUT std_logic;
intno_mux_sel : OUT std_logic_vector(2 downto 0);
adin_mux_sel : OUT std_logic_vector(2 downto 0);
rf_adwe : OUT std_logic;
pcin_mux_sel : OUT std_logic_vector(1 downto 0);
pc_pre : OUT std_logic;
pc_ce : OUT std_logic;
spin_mux_sel : OUT std_logic;
sp_pre : OUT std_logic;
sp_ce : OUT std_logic;
dfh_ce : OUT std_logic;
alua_mux_sel : OUT std_logic_vector(1 downto 0);
alub_mux_sel : OUT std_logic_vector(2 downto 0);
aopsel : OUT std_logic_vector(2 downto 0);
sopsel : OUT std_logic_vector(2 downto 0);
sbin_mux_sel : OUT std_logic;
asresult_mux_sel : OUT std_logic;
coszin_mux_sel : OUT std_logic;
flags_rst : OUT std_logic;
flags_ce : OUT std_logic;
flags_cfce : OUT std_logic;
flags_ifce : OUT std_logic;
flags_clc : OUT std_logic;
flags_cmc : OUT std_logic;
flags_stc : OUT std_logic;
flags_cli : OUT std_logic;
flags_sti : OUT std_logic;
marin_mux_sel : OUT std_logic_vector(1 downto 0);
mar_ce : OUT std_logic;
mdroin_mux_sel : OUT std_logic_vector(2 downto 0);
mdro_ce : OUT std_logic;
mdro_oe : OUT std_logic
);
END COMPONENT;
COMPONENT dp
generic
( pc_preset_value : std_logic_vector(15 downto 0) ;
sp_preset_value : std_logic_vector(15 downto 0)
);
PORT(
CLK_I : IN std_logic;
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 : IN 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_oe : 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)
);
END COMPONENT;
end cpu_pkg;
/vhdl/flags.vhd
0,0 → 1,110
--------------------------------------------------------------
-- flags.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: FLAGS register implementation
--
-- dependency: none
--
-- 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;
 
entity flags is
port(
 
Flags_in : in std_logic_vector(4 downto 0);
CLK_in : in std_logic;
 
ResetAll_in : in std_logic;
CE_in : in std_logic;
CFCE_in : in std_logic;
IFCE_in : in std_logic;
CLC_in : in std_logic;
CMC_in : in std_logic;
STC_in : in std_logic;
STI_in : in std_logic;
CLI_in : in std_logic;
 
Flags_out : out std_logic_vector(4 downto 0)
 
);
 
end flags;
 
architecture Behavioral of flags is
signal CF_in : std_logic;
signal OF_in : std_logic;
signal SF_in : std_logic;
signal ZF_in : std_logic;
signal IF_in : std_logic;
signal CFout_temp : std_logic;
signal OFout_temp : std_logic;
signal SFout_temp : std_logic;
signal ZFout_temp : std_logic;
signal IFout_temp : std_logic;
begin
(CF_in, OF_in, SF_in, ZF_in, IF_in) <= Flags_in;
 
process(Clk_in, ResetAll_in) is
begin
if ResetAll_in = '1' then
CFout_temp <= '0';
OFout_temp <= '0';
SFout_temp <= '0';
ZFout_temp <= '0';
IFout_temp <= '0';
elsif rising_edge(CLK_in) then
if STI_in = '1' then
IFout_temp <= '1';
elsif CLI_in = '1' then
IFout_temp <= '0';
elsif STC_in = '1' then
CFout_temp <= '1';
elsif CLC_in = '1' then
CFout_temp <= '0';
elsif CMC_in = '1' then
CFout_temp <= not CFout_temp;
elsif CE_in = '1' then
if CFCE_in = '1' then
CFout_temp <= CF_in;
end if;
if IFCE_in = '1' then
IFout_temp <= IF_in;
end if;
SFout_temp <= SF_in;
OFout_temp <= OF_in;
ZFout_temp <= ZF_in;
end if;
end if;
end process;
 
Flags_out <= (CFout_temp, OFout_temp, SFout_temp, ZFout_temp, IFout_temp);
 
end Behavioral;
/vhdl/regfile.vhd
0,0 → 1,66
--------------------------------------------------------------
-- regfile.vhd
--------------------------------------------------------------
-- project: HPC-16 Microprocessor
--
-- usage: register file with async read and sync write operations
--
-- dependency: none
--
-- 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_unsigned.all;
 
 
entity regfile is
port(
aadr : in std_logic_vector(3 downto 0);
badr : in std_logic_vector(3 downto 0);
ad : in std_logic_vector(15 downto 0);
adwe : in std_logic;
clk : in std_logic;
aq : out std_logic_vector(15 downto 0);
bq : out std_logic_vector(15 downto 0)
);
end regfile;
 
architecture Behavioral of regfile is
type regfile_type is array(0 to 15) of std_logic_vector(15 downto 0);
signal regfile_data : regfile_type;
begin
process(clk)
begin
if rising_edge(clk) then
if adwe = '1' then
regfile_data(conv_integer(aadr)) <= ad;
end if;
end if;
end process;
aq <= regfile_data(conv_integer(aadr));
bq <= regfile_data(conv_integer(badr));
end Behavioral;

powered by: WebSVN 2.1.0

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