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
/
- from Rev 5 to Rev 6
- ↔ Reverse comparison
Rev 5 → Rev 6
/trunk/impl0/rtl/vhdl/fcmp.vhd
43,109 → 43,112
end fcmp; |
|
architecture Behavioral of fcmp is |
signal CF_in : std_logic; |
signal OF_in : std_logic; |
signal SF_in : std_logic; |
signal ZF_in : std_logic; |
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); |
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'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "0001" => -- JNO |
if OF_in = '0' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "0010" => -- JB or JNAE |
if CF_in = '1' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "0011" => -- JNB or JAE |
if CF_in = '0' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "0100" => -- JE or JZ |
if ZF_in = '1' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "0101" => -- JNE or JNZ |
if ZF_in = '0' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "0110" => -- JBE or JNA |
if (CF_in or ZF_in) = '1' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "0111" => -- JNBE or JA |
if (CF_in or ZF_in) = '0' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "1000" => -- JS |
if SF_in = '1' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "1001" => -- JNS |
if SF_in = '0' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "1010" => |
Result_out <= '0'; |
result_out <= '0'; |
when "1011" => |
Result_out <= '0'; |
result_out <= '0'; |
when "1100" => -- JL or JNGE |
if (SF_in xor OF_in) = '1' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "1101" => -- JNL or JGE |
if (SF_in xor OF_in) = '0' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "1110" => -- JLE or JNG |
if ((SF_in xor OF_in) or ZF_in) = '1' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when "1111" => -- JNLE or JG |
if ((SF_in xor OF_in) or ZF_in) = '0' then |
Result_out <= '1'; |
result_out <= '1'; |
else |
Result_out <= '0'; |
result_out <= '0'; |
end if; |
when others => |
Result_out <= '0'; |
result_out <= '0'; |
end case; |
end process; |
|
/trunk/impl0/rtl/vhdl/nontri/con1.vhd
0,0 → 1,2060
-------------------------------------------------------------- |
-- 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); |
|
begin |
rsync : sync |
port map |
( |
d => RST_I, clk => CLK_I, q => rst_sync |
); |
|
async : sync |
port map |
( |
d => ACK_I, clk => CLK_I, q => ack_sync |
); |
|
isync : sync |
port map |
( |
d => INTR_I, clk => CLK_I, q => intr_sync |
); |
|
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'; |
|
case cur_state is |
--////////////////////////////////////// |
when reset => |
pc_pre <= '1'; flags_rst <= '1'; |
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 |
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 <= '1'; 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_stc <= '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 => |
null; |
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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; CYC_O <= '1'; D_CYC_O <= '1'; |
-- |
mdri_ce <= '1'; |
-- |
nxt_state <= exec2; |
end if; |
-------------------------------------------- |
when others => |
null; |
------------------------------------------- |
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 => |
null; |
---------------------------------------------- |
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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; CYC_O <= '1'; D_CYC_O <= '1'; |
-- |
nxt_state <= exec4; |
end if; |
---------------------------------------------- |
when others => |
null; |
---------------------------------------------- |
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 <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1'; |
-- |
nxt_state <= exec5; |
end if; |
when others => |
null; |
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'; |
-- |
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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; 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 <= '1'; CYC_O <= '1'; WE_O <= '1'; D_CYC_O <= '1'; |
-- |
-- |
nxt_state <= df9; |
end if; |
--/////////////////////////////////////// |
when halted => |
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'; |
-- |
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; |
/trunk/impl0/rtl/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; |
/trunk/impl0/rtl/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); |
|
|
|
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; |
/trunk/impl0/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; |