URL
https://opencores.org/ocsvn/t48/t48/trunk
Subversion Repositories t48
Compare Revisions
- This comparison shows the changes necessary to convert path
/t48/tags/rel_0_1_beta/rtl
- from Rev 251 to Rev 292
- ↔ Reverse comparison
Rev 251 → Rev 292
/vhdl/t48_core.vhd
0,0 → 1,652
------------------------------------------------------------------------------- |
-- |
-- T48 Microcontroller Core |
-- |
-- $Id: t48_core.vhd,v 1.7 2004-05-01 11:58:04 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
-- Limitations : |
-- ============= |
-- |
-- Compared to the original MCS-48 architecture, the following limitations |
-- apply: |
-- |
-- * Nibble-wide instructions addressing expander port implemented but |
-- not verified in detail. |
-- |
-- * Single-step mode not implemented. |
-- Not selected for future implementation. |
-- |
-- * Reading of internal Program Memory not implemented. |
-- Not selected for future implementation. |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity t48_core is |
|
generic ( |
-- divide XTAL1 by 3 to derive Clock States |
xtal_div_3_g : integer := 1; |
-- store mnemonic in flip-flops (registered-out) |
register_mnemonic_g : integer := 1; |
-- include the port 1 module |
include_port1_g : integer := 1; |
-- include the port 2 module |
include_port2_g : integer := 1; |
-- include the BUS module |
include_bus_g : integer := 1; |
-- include the timer module |
include_timer_g : integer := 1; |
-- state in which T1 is sampled (3 or 4) |
sample_t1_state_g : integer := 4 |
); |
|
port ( |
-- T48 Interface ---------------------------------------------------------- |
xtal_i : in std_logic; |
reset_i : in std_logic; |
t0_i : in std_logic; |
t0_o : out std_logic; |
t0_dir_o : out std_logic; |
int_n_i : in std_logic; |
ea_i : in std_logic; |
rd_n_o : out std_logic; |
psen_n_o : out std_logic; |
wr_n_o : out std_logic; |
ale_o : out std_logic; |
db_i : in std_logic_vector( 7 downto 0); |
db_o : out std_logic_vector( 7 downto 0); |
db_dir_o : out std_logic; |
t1_i : in std_logic; |
p2_i : in std_logic_vector( 7 downto 0); |
p2_o : out std_logic_vector( 7 downto 0); |
p2_low_imp_o : out std_logic; |
p1_i : in std_logic_vector( 7 downto 0); |
p1_o : out std_logic_vector( 7 downto 0); |
p1_low_imp_o : out std_logic; |
prog_n_o : out std_logic; |
-- Core Interface --------------------------------------------------------- |
clk_i : in std_logic; |
en_clk_i : in std_logic; |
xtal3_o : out std_logic; |
dmem_addr_o : out std_logic_vector( 7 downto 0); |
dmem_we_o : out std_logic; |
dmem_data_i : in std_logic_vector( 7 downto 0); |
dmem_data_o : out std_logic_vector( 7 downto 0); |
pmem_addr_o : out std_logic_vector(11 downto 0); |
pmem_data_i : in std_logic_vector( 7 downto 0) |
); |
|
end t48_core; |
|
|
use work.alu_pack.alu_op_t; |
use work.cond_branch_pack.branch_conditions_t; |
use work.cond_branch_pack.comp_value_t; |
use work.dmem_ctrl_pack.dmem_addr_ident_t; |
use work.pmem_ctrl_pack.pmem_addr_ident_t; |
use work.t48_comp_pack.all; |
use work.t48_pack.bus_idle_level_c; |
use work.t48_pack.word_t; |
use work.t48_pack.pmem_addr_t; |
use work.t48_pack.mstate_t; |
use work.t48_pack.to_stdLogic; |
use work.t48_pack.to_boolean; |
|
architecture struct of t48_core is |
|
signal t48_data_s : word_t; |
|
signal en_clk_s : boolean; |
|
-- ALU signals |
signal alu_data_s : word_t; |
signal alu_write_accu_s : boolean; |
signal alu_write_shadow_s : boolean; |
signal alu_write_temp_reg_s : boolean; |
signal alu_read_alu_s : boolean; |
signal alu_carry_s : std_logic; |
signal alu_aux_carry_s : std_logic; |
signal alu_op_s : alu_op_t; |
signal alu_use_carry_s : boolean; |
signal alu_da_high_s : boolean; |
signal alu_da_overflow_s : boolean; |
signal alu_accu_low_s : boolean; |
signal alu_p06_temp_reg_s : boolean; |
signal alu_p60_temp_reg_s : boolean; |
|
-- BUS signals |
signal bus_write_bus_s : boolean; |
signal bus_read_bus_s : boolean; |
signal bus_output_pcl_s : boolean; |
signal bus_bidir_bus_s : boolean; |
signal bus_data_s : word_t; |
|
-- Clock Controller signals |
signal clk_multi_cycle_s : boolean; |
signal clk_assert_psen_s : boolean; |
signal clk_assert_prog_s : boolean; |
signal clk_assert_rd_s : boolean; |
signal clk_assert_wr_s : boolean; |
signal clk_mstate_s : mstate_t; |
signal clk_second_cycle_s : boolean; |
signal psen_s : boolean; |
signal prog_s : boolean; |
signal rd_s : boolean; |
signal wr_s : boolean; |
signal ale_s : boolean; |
signal xtal3_s : boolean; |
|
-- Conditional Branch Logic signals |
signal cnd_compute_take_s : boolean; |
signal cnd_branch_cond_s : branch_conditions_t; |
signal cnd_take_branch_s : boolean; |
signal cnd_comp_value_s : comp_value_t; |
signal cnd_f1_s : std_logic; |
signal cnd_tf_s : std_logic; |
|
-- Data Memory Controller signals |
signal dm_write_dmem_addr_s : boolean; |
signal dm_write_dmem_s : boolean; |
signal dm_read_dmem_s : boolean; |
signal dm_addr_type_s : dmem_addr_ident_t; |
signal dm_data_s : word_t; |
|
-- Decoder signals |
signal dec_data_s : word_t; |
|
-- Port 1 signals |
signal p1_write_p1_s : boolean; |
signal p1_read_p1_s : boolean; |
signal p1_read_reg_s : boolean; |
signal p1_data_s : word_t; |
|
-- Port 2 signals |
signal p2_write_p2_s : boolean; |
signal p2_write_exp_s : boolean; |
signal p2_read_p2_s : boolean; |
signal p2_read_reg_s : boolean; |
signal p2_read_exp_s : boolean; |
signal p2_output_pch_s : boolean; |
signal p2_output_exp_s : boolean; |
signal p2_data_s : word_t; |
|
-- Program Memory Controller signals |
signal pm_write_pcl_s : boolean; |
signal pm_read_pcl_s : boolean; |
signal pm_write_pch_s : boolean; |
signal pm_read_pch_s : boolean; |
signal pm_read_pmem_s : boolean; |
signal pm_inc_pc_s : boolean; |
signal pm_write_pmem_addr_s : boolean; |
signal pm_data_s : word_t; |
signal pm_addr_type_s : pmem_addr_ident_t; |
signal pmem_addr_s : pmem_addr_t; |
|
-- PSW signals |
signal psw_read_psw_s : boolean; |
signal psw_read_sp_s : boolean; |
signal psw_write_psw_s : boolean; |
signal psw_write_sp_s : boolean; |
signal psw_carry_s : std_logic; |
signal psw_aux_carry_s : std_logic; |
signal psw_f0_s : std_logic; |
signal psw_bs_s : std_logic; |
signal psw_special_data_s : std_logic; |
signal psw_inc_stackp_s : boolean; |
signal psw_dec_stackp_s : boolean; |
signal psw_write_carry_s : boolean; |
signal psw_write_aux_carry_s : boolean; |
signal psw_write_f0_s : boolean; |
signal psw_write_bs_s : boolean; |
signal psw_data_s : word_t; |
|
-- Timer signals |
signal tim_overflow_s : boolean; |
signal tim_of_s : std_logic; |
signal tim_read_timer_s : boolean; |
signal tim_write_timer_s : boolean; |
signal tim_start_t_s : boolean; |
signal tim_start_cnt_s : boolean; |
signal tim_stop_tcnt_s : boolean; |
signal tim_data_s : word_t; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Check generics for valid values. |
----------------------------------------------------------------------------- |
-- pragma translate_off |
assert include_timer_g = 0 or include_timer_g = 1 |
report "include_timer_g must be either 1 or 0!" |
severity failure; |
|
assert include_port1_g = 0 or include_port1_g = 1 |
report "include_port1_g must be either 1 or 0!" |
severity failure; |
|
assert include_port2_g = 0 or include_port2_g = 1 |
report "include_port2_g must be either 1 or 0!" |
severity failure; |
|
assert include_bus_g = 0 or include_bus_g = 1 |
report "include_bus_g must be either 1 or 0!" |
severity failure; |
-- pragma translate_on |
|
|
en_clk_s <= to_boolean(en_clk_i); |
|
alu_b : alu |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
data_i => t48_data_s, |
data_o => alu_data_s, |
write_accu_i => alu_write_accu_s, |
write_shadow_i => alu_write_shadow_s, |
write_temp_reg_i => alu_write_temp_reg_s, |
read_alu_i => alu_read_alu_s, |
carry_i => psw_carry_s, |
carry_o => alu_carry_s, |
aux_carry_o => alu_aux_carry_s, |
alu_op_i => alu_op_s, |
use_carry_i => alu_use_carry_s, |
da_high_i => alu_da_high_s, |
da_overflow_o => alu_da_overflow_s, |
accu_low_i => alu_accu_low_s, |
p06_temp_reg_i => alu_p06_temp_reg_s, |
p60_temp_reg_i => alu_p60_temp_reg_s |
); |
|
bus_mux_b : bus_mux |
port map ( |
alu_data_i => alu_data_s, |
bus_data_i => bus_data_s, |
dec_data_i => dec_data_s, |
dm_data_i => dm_data_s, |
pm_data_i => pm_data_s, |
p1_data_i => p1_data_s, |
p2_data_i => p2_data_s, |
psw_data_i => psw_data_s, |
tim_data_i => tim_data_s, |
data_o => t48_data_s |
); |
|
clock_ctrl_b : clock_ctrl |
generic map ( |
xtal_div_3_g => xtal_div_3_g |
) |
port map ( |
clk_i => clk_i, |
xtal_i => xtal_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
xtal3_o => xtal3_s, |
multi_cycle_i => clk_multi_cycle_s, |
assert_psen_i => clk_assert_psen_s, |
assert_prog_i => clk_assert_prog_s, |
assert_rd_i => clk_assert_rd_s, |
assert_wr_i => clk_assert_wr_s, |
mstate_o => clk_mstate_s, |
second_cycle_o => clk_second_cycle_s, |
ale_o => ale_s, |
psen_o => psen_s, |
prog_o => prog_s, |
rd_o => rd_s, |
wr_o => wr_s |
); |
|
cond_branch_b : cond_branch |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
compute_take_i => cnd_compute_take_s, |
branch_cond_i => cnd_branch_cond_s, |
take_branch_o => cnd_take_branch_s, |
accu_i => alu_data_s, |
t0_i => To_X01Z(t0_i), |
t1_i => To_X01Z(t1_i), |
int_n_i => int_n_i, |
f0_i => psw_f0_s, |
f1_i => cnd_f1_s, |
tf_i => cnd_tf_s, |
carry_i => psw_carry_s, |
comp_value_i => cnd_comp_value_s |
); |
|
use_db_bus: if include_bus_g = 1 generate |
db_bus_b : db_bus |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
ea_i => ea_i, |
data_i => t48_data_s, |
data_o => bus_data_s, |
write_bus_i => bus_write_bus_s, |
read_bus_i => bus_read_bus_s, |
output_pcl_i => bus_output_pcl_s, |
bidir_bus_i => bus_bidir_bus_s, |
pcl_i => pmem_addr_s(word_t'range), |
db_i => db_i, |
db_o => db_o, |
db_dir_o => db_dir_o |
); |
end generate; |
|
skip_db_bus: if include_bus_g = 0 generate |
bus_data_s <= (others => bus_idle_level_c); |
db_o <= (others => '0'); |
db_dir_o <= '0'; |
end generate; |
|
decoder_b : decoder |
generic map ( |
register_mnemonic_g => register_mnemonic_g |
) |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
ea_i => ea_i, |
ale_i => ale_s, |
int_n_i => int_n_i, |
t0_dir_o => t0_dir_o, |
data_i => t48_data_s, |
data_o => dec_data_s, |
alu_write_accu_o => alu_write_accu_s, |
alu_write_shadow_o => alu_write_shadow_s, |
alu_write_temp_reg_o => alu_write_temp_reg_s, |
alu_read_alu_o => alu_read_alu_s, |
bus_write_bus_o => bus_write_bus_s, |
bus_read_bus_o => bus_read_bus_s, |
dm_write_dmem_addr_o => dm_write_dmem_addr_s, |
dm_write_dmem_o => dm_write_dmem_s, |
dm_read_dmem_o => dm_read_dmem_s, |
p1_write_p1_o => p1_write_p1_s, |
p1_read_p1_o => p1_read_p1_s, |
pm_write_pcl_o => pm_write_pcl_s, |
p2_write_p2_o => p2_write_p2_s, |
p2_write_exp_o => p2_write_exp_s, |
p2_read_p2_o => p2_read_p2_s, |
pm_read_pcl_o => pm_read_pcl_s, |
pm_write_pch_o => pm_write_pch_s, |
pm_read_pch_o => pm_read_pch_s, |
pm_read_pmem_o => pm_read_pmem_s, |
psw_read_psw_o => psw_read_psw_s, |
psw_read_sp_o => psw_read_sp_s, |
psw_write_psw_o => psw_write_psw_s, |
psw_write_sp_o => psw_write_sp_s, |
alu_carry_i => alu_carry_s, |
alu_op_o => alu_op_s, |
alu_use_carry_o => alu_use_carry_s, |
alu_da_high_o => alu_da_high_s, |
alu_da_overflow_i => alu_da_overflow_s, |
alu_accu_low_o => alu_accu_low_s, |
alu_p06_temp_reg_o => alu_p06_temp_reg_s, |
alu_p60_temp_reg_o => alu_p60_temp_reg_s, |
bus_output_pcl_o => bus_output_pcl_s, |
bus_bidir_bus_o => bus_bidir_bus_s, |
clk_multi_cycle_o => clk_multi_cycle_s, |
clk_assert_psen_o => clk_assert_psen_s, |
clk_assert_prog_o => clk_assert_prog_s, |
clk_assert_rd_o => clk_assert_rd_s, |
clk_assert_wr_o => clk_assert_wr_s, |
clk_mstate_i => clk_mstate_s, |
clk_second_cycle_i => clk_second_cycle_s, |
cnd_compute_take_o => cnd_compute_take_s, |
cnd_branch_cond_o => cnd_branch_cond_s, |
cnd_take_branch_i => cnd_take_branch_s, |
cnd_comp_value_o => cnd_comp_value_s, |
cnd_f1_o => cnd_f1_s, |
cnd_tf_o => cnd_tf_s, |
dm_addr_type_o => dm_addr_type_s, |
tim_read_timer_o => tim_read_timer_s, |
tim_write_timer_o => tim_write_timer_s, |
tim_start_t_o => tim_start_t_s, |
tim_start_cnt_o => tim_start_cnt_s, |
tim_stop_tcnt_o => tim_stop_tcnt_s, |
p1_read_reg_o => p1_read_reg_s, |
p2_read_reg_o => p2_read_reg_s, |
p2_read_exp_o => p2_read_exp_s, |
p2_output_pch_o => p2_output_pch_s, |
p2_output_exp_o => p2_output_exp_s, |
pm_inc_pc_o => pm_inc_pc_s, |
pm_write_pmem_addr_o => pm_write_pmem_addr_s, |
pm_addr_type_o => pm_addr_type_s, |
psw_special_data_o => psw_special_data_s, |
psw_carry_i => psw_carry_s, |
psw_aux_carry_i => psw_aux_carry_s, |
psw_f0_i => psw_f0_s, |
psw_inc_stackp_o => psw_inc_stackp_s, |
psw_dec_stackp_o => psw_dec_stackp_s, |
psw_write_carry_o => psw_write_carry_s, |
psw_write_aux_carry_o => psw_write_aux_carry_s, |
psw_write_f0_o => psw_write_f0_s, |
psw_write_bs_o => psw_write_bs_s, |
tim_overflow_i => tim_overflow_s |
); |
|
dmem_ctrl_b : dmem_ctrl |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
data_i => t48_data_s, |
write_dmem_addr_i => dm_write_dmem_addr_s, |
write_dmem_i => dm_write_dmem_s, |
read_dmem_i => dm_read_dmem_s, |
addr_type_i => dm_addr_type_s, |
bank_select_i => psw_bs_s, |
data_o => dm_data_s, |
dmem_data_i => dmem_data_i, |
dmem_addr_o => dmem_addr_o, |
dmem_we_o => dmem_we_o, |
dmem_data_o => dmem_data_o |
); |
|
use_timer: if include_timer_g = 1 generate |
timer_b : timer |
generic map ( |
sample_t1_state_g => sample_t1_state_g |
) |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
t1_i => To_X01Z(t1_i), |
clk_mstate_i => clk_mstate_s, |
data_i => t48_data_s, |
data_o => tim_data_s, |
read_timer_i => tim_read_timer_s, |
write_timer_i => tim_write_timer_s, |
start_t_i => tim_start_t_s, |
start_cnt_i => tim_start_cnt_s, |
stop_tcnt_i => tim_stop_tcnt_s, |
overflow_o => tim_of_s |
); |
end generate; |
|
skip_timer: if include_timer_g = 0 generate |
tim_data_s <= (others => bus_idle_level_c); |
tim_of_s <= '0'; |
end generate; |
|
tim_overflow_s <= to_boolean(tim_of_s); |
|
use_p1: if include_port1_g = 1 generate |
p1_b : p1 |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
data_i => t48_data_s, |
data_o => p1_data_s, |
write_p1_i => p1_write_p1_s, |
read_p1_i => p1_read_p1_s, |
read_reg_i => p1_read_reg_s, |
p1_i => p1_i, |
p1_o => p1_o, |
p1_low_imp_o => p1_low_imp_o |
); |
end generate; |
|
skip_p1: if include_port1_g = 0 generate |
p1_data_s <= (others => bus_idle_level_c); |
p1_o <= (others => '0'); |
p1_low_imp_o <= '0'; |
end generate; |
|
use_p2: if include_port2_g = 1 generate |
p2_b : p2 |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
data_i => t48_data_s, |
data_o => p2_data_s, |
write_p2_i => p2_write_p2_s, |
write_exp_i => p2_write_exp_s, |
read_p2_i => p2_read_p2_s, |
read_reg_i => p2_read_reg_s, |
read_exp_i => p2_read_exp_s, |
output_pch_i => p2_output_pch_s, |
output_exp_i => p2_output_exp_s, |
pch_i => pmem_addr_s(11 downto 8), |
p2_i => p2_i, |
p2_o => p2_o, |
p2_low_imp_o => p2_low_imp_o |
); |
end generate; |
|
skip_p2: if include_port2_g = 0 generate |
p2_data_s <= (others => bus_idle_level_c); |
p2_o <= (others => '0'); |
p2_low_imp_o <= '0'; |
end generate; |
|
pmem_ctrl_b : pmem_ctrl |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
data_i => t48_data_s, |
data_o => pm_data_s, |
write_pcl_i => pm_write_pcl_s, |
read_pcl_i => pm_read_pcl_s, |
write_pch_i => pm_write_pch_s, |
read_pch_i => pm_read_pch_s, |
inc_pc_i => pm_inc_pc_s, |
write_pmem_addr_i => pm_write_pmem_addr_s, |
addr_type_i => pm_addr_type_s, |
read_pmem_i => pm_read_pmem_s, |
pmem_addr_o => pmem_addr_s, |
pmem_data_i => pmem_data_i |
); |
|
psw_b : psw |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
data_i => t48_data_s, |
data_o => psw_data_s, |
read_psw_i => psw_read_psw_s, |
read_sp_i => psw_read_sp_s, |
write_psw_i => psw_write_psw_s, |
write_sp_i => psw_write_sp_s, |
special_data_i => psw_special_data_s, |
inc_stackp_i => psw_inc_stackp_s, |
dec_stackp_i => psw_dec_stackp_s, |
write_carry_i => psw_write_carry_s, |
write_aux_carry_i => psw_write_aux_carry_s, |
write_f0_i => psw_write_f0_s, |
write_bs_i => psw_write_bs_s, |
carry_o => psw_carry_s, |
aux_carry_i => alu_aux_carry_s, |
aux_carry_o => psw_aux_carry_s, |
f0_o => psw_f0_s, |
bs_o => psw_bs_s |
); |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
ale_o <= to_stdLogic(ale_s); |
t0_o <= clk_i; |
psen_n_o <= to_stdLogic(not psen_s); |
prog_n_o <= to_stdLogic(not prog_s); |
rd_n_o <= to_stdLogic(not rd_s); |
wr_n_o <= to_stdLogic(not wr_s); |
xtal3_o <= to_stdLogic(xtal3_s); |
pmem_addr_o <= pmem_addr_s; |
|
end struct; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.6 2004/04/07 22:09:03 arniml |
-- remove unused signals |
-- |
-- Revision 1.5 2004/04/04 14:18:53 arniml |
-- add measures to implement XCHD |
-- |
-- Revision 1.4 2004/03/29 19:39:58 arniml |
-- rename pX_limp to pX_low_imp |
-- |
-- Revision 1.3 2004/03/28 21:27:50 arniml |
-- update wiring for DA support |
-- |
-- Revision 1.2 2004/03/28 13:13:20 arniml |
-- connect control signal for Port 2 expander |
-- |
-- Revision 1.1 2004/03/23 21:31:53 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/decoder.vhd
0,0 → 1,1919
------------------------------------------------------------------------------- |
-- |
-- The Decoder unit. |
-- It decodes the instruction opcodes and executes them. |
-- |
-- $Id: decoder.vhd,v 1.10 2004-04-25 16:22:03 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
use work.t48_pack.mstate_t; |
use work.alu_pack.alu_op_t; |
use work.cond_branch_pack.all; |
use work.dmem_ctrl_pack.all; |
use work.pmem_ctrl_pack.all; |
|
entity decoder is |
|
generic ( |
-- store mnemonic in flip-flops (registered-out) |
register_mnemonic_g : integer := 1 |
); |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
ea_i : in std_logic; |
ale_i : in boolean; |
int_n_i : in std_logic; |
t0_dir_o : out std_logic; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
data_o : out word_t; |
stack_high_o : out boolean; |
alu_write_accu_o : out boolean; |
alu_write_shadow_o : out boolean; |
alu_write_temp_reg_o : out boolean; |
alu_read_alu_o : out boolean; |
bus_write_bus_o : out boolean; |
bus_read_bus_o : out boolean; |
dm_write_dmem_addr_o : out boolean; |
dm_write_dmem_o : out boolean; |
dm_read_dmem_o : out boolean; |
p1_write_p1_o : out boolean; |
p1_read_p1_o : out boolean; |
p2_write_p2_o : out boolean; |
p2_write_exp_o : out boolean; |
p2_read_p2_o : out boolean; |
p2_read_exp_o : out boolean; |
pm_write_pcl_o : out boolean; |
pm_read_pcl_o : out boolean; |
pm_write_pch_o : out boolean; |
pm_read_pch_o : out boolean; |
pm_read_pmem_o : out boolean; |
psw_read_psw_o : out boolean; |
psw_read_sp_o : out boolean; |
psw_write_psw_o : out boolean; |
psw_write_sp_o : out boolean; |
-- ALU Interface ---------------------------------------------------------- |
alu_carry_i : in std_logic; |
alu_op_o : out alu_op_t; |
alu_use_carry_o : out boolean; |
alu_da_high_o : out boolean; |
alu_accu_low_o : out boolean; |
alu_p06_temp_reg_o : out boolean; |
alu_p60_temp_reg_o : out boolean; |
alu_da_overflow_i : in boolean; |
-- BUS Interface ---------------------------------------------------------- |
bus_output_pcl_o : out boolean; |
bus_bidir_bus_o : out boolean; |
-- Clock Controller Interface --------------------------------------------- |
clk_multi_cycle_o : out boolean; |
clk_assert_psen_o : out boolean; |
clk_assert_prog_o : out boolean; |
clk_assert_rd_o : out boolean; |
clk_assert_wr_o : out boolean; |
clk_mstate_i : in mstate_t; |
clk_second_cycle_i : in boolean; |
-- Conditional Branch Logic Interface ------------------------------------- |
cnd_compute_take_o : out boolean; |
cnd_branch_cond_o : out branch_conditions_t; |
cnd_take_branch_i : in boolean; |
cnd_comp_value_o : out comp_value_t; |
cnd_f1_o : out std_logic; |
cnd_tf_o : out std_logic; |
-- Data Memory Controller Interface --------------------------------------- |
dm_addr_type_o : out dmem_addr_ident_t; |
-- Port 1 Interface ------------------------------------------------------- |
p1_read_reg_o : out boolean; |
-- Port 2 Interface ------------------------------------------------------- |
p2_read_reg_o : out boolean; |
p2_output_pch_o : out boolean; |
p2_output_exp_o : out boolean; |
-- Program Memory Controller Interface ------------------------------------ |
pm_inc_pc_o : out boolean; |
pm_write_pmem_addr_o : out boolean; |
pm_addr_type_o : out pmem_addr_ident_t; |
-- Program Status Word Interface ------------------------------------------ |
psw_special_data_o : out std_logic; |
psw_carry_i : in std_logic; |
psw_aux_carry_i : in std_logic; |
psw_f0_i : in std_logic; |
psw_inc_stackp_o : out boolean; |
psw_dec_stackp_o : out boolean; |
psw_write_carry_o : out boolean; |
psw_write_aux_carry_o : out boolean; |
psw_write_f0_o : out boolean; |
psw_write_bs_o : out boolean; |
-- Timer Interface -------------------------------------------------------- |
tim_read_timer_o : out boolean; |
tim_write_timer_o : out boolean; |
tim_start_t_o : out boolean; |
tim_start_cnt_o : out boolean; |
tim_stop_tcnt_o : out boolean; |
tim_overflow_i : in boolean |
); |
|
end decoder; |
|
|
use work.t48_pack.all; |
use work.alu_pack.all; |
use work.decoder_pack.all; |
|
use work.t48_comp_pack.opc_decoder; |
use work.t48_comp_pack.int; |
|
-- pragma translate_off |
use work.t48_tb_pack.tb_istrobe_s; |
-- pragma translate_on |
|
architecture rtl of decoder is |
|
-- Opcode Decoder |
signal opc_multi_cycle_s : boolean; |
signal opc_read_bus_s : boolean; |
signal opc_inj_int_s : boolean; |
signal opc_opcode_s : word_t; |
signal opc_mnemonic_s : mnemonic_t; |
signal last_cycle_s : boolean; |
|
-- state translators |
signal assert_psen_s : boolean; |
|
-- branch taken handshake |
signal branch_taken_s, |
branch_taken_q : boolean; |
signal pm_inc_pc_s : boolean; |
signal pm_write_pmem_addr_s : boolean; |
-- additional signal to increment PC during CALL |
signal add_inc_pc_s : boolean; |
-- addtional signal to set PC during RET(R) |
signal add_write_pmem_addr_s : boolean; |
|
-- Flag 1 |
signal clear_f1_s, |
cpl_f1_s : boolean; |
signal f1_q : std_logic; |
-- memory bank select |
signal clear_mb_s, |
set_mb_s : boolean; |
signal mb_q : std_logic; |
|
-- T0 direction selection |
signal ent0_clk_s : boolean; |
signal t0_dir_q : std_logic; |
|
signal data_s : word_t; |
signal read_dec_s : boolean; |
|
signal tf_s : std_logic; |
|
signal bus_read_bus_s : boolean; |
signal add_read_bus_s : boolean; |
|
signal dm_write_dmem_s : boolean; |
|
-- interrupt handling |
signal jtf_executed_s : boolean; |
signal en_tcnti_s : boolean; |
signal dis_tcnti_s : boolean; |
signal en_i_s : boolean; |
signal dis_i_s : boolean; |
signal tim_int_s : boolean; |
signal retr_executed_s : boolean; |
signal int_executed_s : boolean; |
signal int_pending_s : boolean; |
|
-- pragma translate_off |
signal istrobe_res_q : std_logic; |
signal istrobe_q : std_logic; |
signal injected_int_q : std_logic; |
-- pragma translate_on |
|
begin |
|
----------------------------------------------------------------------------- |
-- Opcode Decoder |
----------------------------------------------------------------------------- |
opc_decoder_b : opc_decoder |
generic map ( |
register_mnemonic_g => register_mnemonic_g |
) |
port map ( |
clk_i => clk_i, |
res_i => res_i, |
en_clk_i => en_clk_i, |
data_i => data_i, |
read_bus_i => opc_read_bus_s, |
inj_int_i => opc_inj_int_s, |
opcode_o => opc_opcode_s, |
mnemonic_o => opc_mnemonic_s, |
multi_cycle_o => opc_multi_cycle_s |
); |
|
|
----------------------------------------------------------------------------- |
-- Interrupt Controller. |
----------------------------------------------------------------------------- |
int_b : int |
port map ( |
clk_i => clk_i, |
res_i => res_i, |
en_clk_i => en_clk_i, |
clk_mstate_i => clk_mstate_i, |
jtf_executed_i => jtf_executed_s, |
tim_overflow_i => tim_overflow_i, |
tf_o => tf_s, |
en_tcnti_i => en_tcnti_s, |
dis_tcnti_i => dis_tcnti_s, |
int_n_i => int_n_i, |
ale_i => ale_i, |
last_cycle_i => last_cycle_s, |
en_i_i => en_i_s, |
dis_i_i => dis_i_s, |
ext_int_o => open, |
tim_int_o => tim_int_s, |
retr_executed_i => retr_executed_s, |
int_executed_i => int_executed_s, |
int_pending_o => int_pending_s |
); |
|
last_cycle_s <= not opc_multi_cycle_s or |
(opc_multi_cycle_s and clk_second_cycle_i); |
|
----------------------------------------------------------------------------- |
-- Process machine_cycle |
-- |
-- Purpose: |
-- Generates the control signals that are basically needed for the |
-- handling of a machine cycle. |
-- |
machine_cycle: process (clk_mstate_i, |
clk_second_cycle_i, |
last_cycle_s, |
ea_i, |
assert_psen_s, |
branch_taken_q, |
int_pending_s) |
|
variable need_address_v : boolean; |
|
begin |
-- default assignments |
clk_assert_psen_o <= false; |
pm_inc_pc_s <= false; |
pm_write_pmem_addr_s <= false; |
pm_read_pmem_o <= false; |
bus_output_pcl_o <= false; |
p2_output_pch_o <= false; |
opc_read_bus_s <= false; |
opc_inj_int_s <= false; |
bus_read_bus_s <= false; |
|
need_address_v := not clk_second_cycle_i or |
(clk_second_cycle_i and assert_psen_s); |
|
case clk_mstate_i is |
when MSTATE1 => |
if need_address_v and not int_pending_s then |
if ea_i = '0' then |
pm_read_pmem_o <= true; |
else |
bus_read_bus_s <= true; |
p2_output_pch_o <= true; |
end if; |
end if; |
|
if not clk_second_cycle_i then |
if not int_pending_s then |
opc_read_bus_s <= true; |
else |
opc_inj_int_s <= true; -- inject interrupt call |
end if; |
end if; |
|
when MSTATE2 => |
if need_address_v and not branch_taken_q and |
not int_pending_s then |
pm_inc_pc_s <= true; |
end if; |
|
when MSTATE3 => |
if need_address_v then |
pm_write_pmem_addr_s <= true; |
end if; |
|
if ea_i = '1' and |
(need_address_v and last_cycle_s) then |
bus_output_pcl_o <= true; |
end if; |
|
when MSTATE4 => |
if ea_i = '1' and |
(need_address_v or last_cycle_s) then |
clk_assert_psen_o <= true; |
p2_output_pch_o <= true; |
bus_output_pcl_o <= true; |
end if; |
|
when MSTATE5 => |
if ea_i = '1' and |
(need_address_v and last_cycle_s) then |
clk_assert_psen_o <= true; |
p2_output_pch_o <= true; |
end if; |
|
when others => |
-- pragma translate_off |
assert false |
report "Unkown machine state!" |
severity error; |
-- pragma translate_on |
|
end case; |
|
end process machine_cycle; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process decode |
-- |
-- Purpose: |
-- Indentifies each single instruction and steps through the related |
-- execution sequence. |
-- |
decode: process (alu_carry_i, |
psw_aux_carry_i, |
alu_da_overflow_i, |
clk_mstate_i, |
clk_second_cycle_i, |
cnd_take_branch_i, |
opc_opcode_s, |
opc_mnemonic_s, |
psw_carry_i, |
psw_f0_i, |
f1_q, |
mb_q, |
tim_int_s, |
int_pending_s) |
|
procedure address_indirect_3_f is |
begin |
-- apply dmem address from selected register for indirect mode |
if opc_opcode_s(3) = '0' then |
dm_read_dmem_o <= true; |
dm_write_dmem_addr_o <= true; |
dm_addr_type_o <= DM_PLAIN; |
end if; |
end; |
|
procedure and_or_xor_add_4_f is |
begin |
-- write dmem contents to Temp Reg |
dm_read_dmem_o <= true; |
alu_write_temp_reg_o <= true; |
end; |
|
procedure and_or_xor_add_5_f (alu_op : alu_op_t) is |
begin |
-- perform ALU operation and store in Accumulator |
alu_op_o <= alu_op; |
alu_read_alu_o <= true; |
alu_write_accu_o <= true; |
end; |
|
procedure cond_jump_c2_m1_f is |
begin |
-- store address in Program Counter low byte if branch has to |
-- be taken |
if clk_mstate_i = MSTATE1 and cnd_take_branch_i then |
pm_write_pcl_o <= true; |
branch_taken_s <= true; |
end if; |
end; |
|
begin |
-- default assignments |
data_s <= (others => '-'); |
read_dec_s <= false; |
branch_taken_s <= false; |
clear_f1_s <= false; |
cpl_f1_s <= false; |
clear_mb_s <= false; |
set_mb_s <= false; |
add_inc_pc_s <= false; |
assert_psen_s <= false; |
stack_high_o <= false; |
alu_write_accu_o <= false; |
alu_write_shadow_o <= false; |
alu_write_temp_reg_o <= false; |
alu_p06_temp_reg_o <= false; |
alu_p60_temp_reg_o <= false; |
alu_read_alu_o <= false; |
bus_write_bus_o <= false; |
bus_bidir_bus_o <= false; |
dm_write_dmem_addr_o <= false; |
dm_write_dmem_s <= false; |
dm_read_dmem_o <= false; |
pm_write_pcl_o <= false; |
pm_read_pcl_o <= false; |
pm_write_pch_o <= false; |
pm_read_pch_o <= false; |
pm_addr_type_o <= PM_PC; |
psw_read_psw_o <= false; |
psw_read_sp_o <= false; |
psw_write_psw_o <= false; |
psw_write_sp_o <= false; |
alu_op_o <= ALU_NOP; |
alu_use_carry_o <= false; |
alu_da_high_o <= false; |
alu_accu_low_o <= false; |
clk_assert_prog_o <= false; |
clk_assert_rd_o <= false; |
clk_assert_wr_o <= false; |
cnd_branch_cond_o <= COND_ON_BIT; |
cnd_compute_take_o <= false; |
cnd_comp_value_o <= opc_opcode_s(7 downto 5); |
dm_addr_type_o <= DM_REG; |
tim_read_timer_o <= false; |
tim_write_timer_o <= false; |
tim_start_t_o <= false; |
tim_start_cnt_o <= false; |
tim_stop_tcnt_o <= false; |
p1_write_p1_o <= false; |
p1_read_p1_o <= false; |
p1_read_reg_o <= false; |
p2_write_p2_o <= false; |
p2_write_exp_o <= false; |
p2_read_p2_o <= false; |
p2_read_reg_o <= false; |
p2_read_exp_o <= false; |
p2_output_exp_o <= false; |
psw_special_data_o <= '0'; |
psw_inc_stackp_o <= false; |
psw_dec_stackp_o <= false; |
psw_write_carry_o <= false; |
psw_write_aux_carry_o <= false; |
psw_write_f0_o <= false; |
psw_write_bs_o <= false; |
jtf_executed_s <= false; |
en_tcnti_s <= false; |
dis_tcnti_s <= false; |
en_i_s <= false; |
dis_i_s <= false; |
retr_executed_s <= false; |
int_executed_s <= false; |
add_write_pmem_addr_s <= false; |
ent0_clk_s <= false; |
add_read_bus_s <= false; |
|
-- prepare potential register indirect address mode |
if not clk_second_cycle_i and clk_mstate_i = MSTATE2 then |
data_s <= (others => '0'); |
if opc_opcode_s(3) = '1' then |
data_s(2 downto 0) <= opc_opcode_s(2 downto 0); |
else |
data_s(2 downto 0) <= "00" & opc_opcode_s(0); |
end if; |
|
read_dec_s <= true; |
dm_write_dmem_addr_o <= true; |
dm_addr_type_o <= DM_REG; |
end if; |
|
case opc_mnemonic_s is |
|
-- Mnemonic ADD --------------------------------------------------------- |
when MN_ADD => |
case clk_mstate_i is |
-- read RAM once for indirect address mode |
when MSTATE3 => |
address_indirect_3_f; |
|
-- store data from RAM to Temp Reg |
when MSTATE4 => |
and_or_xor_add_4_f; |
|
-- perform ADD and store in Accumulator |
when MSTATE5 => |
and_or_xor_add_5_f(alu_op => ALU_ADD); |
|
if opc_opcode_s(4) = '1' then |
alu_use_carry_o <= true; |
end if; |
|
psw_special_data_o <= alu_carry_i; |
psw_write_carry_o <= true; |
psw_write_aux_carry_o <= true; |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic ADD_A_DATA -------------------------------------------------- |
when MN_ADD_A_DATA => |
assert_psen_s <= true; |
|
if clk_second_cycle_i then |
case clk_mstate_i is |
-- write Temp Reg when contents of Program Memory is on bus |
when MSTATE1 => |
alu_write_temp_reg_o <= true; |
|
-- perform ADD and store in Accumulator |
when MSTATE3 => |
and_or_xor_add_5_f(alu_op => ALU_ADD); |
|
if opc_opcode_s(4) = '1' then |
alu_use_carry_o <= true; |
end if; |
|
psw_special_data_o <= alu_carry_i; |
psw_write_carry_o <= true; |
psw_write_aux_carry_o <= true; |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic ANL --------------------------------------------------------- |
when MN_ANL => |
case clk_mstate_i is |
-- read RAM once for indirect address mode |
when MSTATE3 => |
address_indirect_3_f; |
|
-- store data from RAM to Temp Reg |
when MSTATE4 => |
and_or_xor_add_4_f; |
|
-- perform AND and store in Accumulator |
when MSTATE5 => |
and_or_xor_add_5_f(alu_op => ALU_AND); |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic ANL_A_DATA -------------------------------------------------- |
when MN_ANL_A_DATA => |
assert_psen_s <= true; |
|
if clk_second_cycle_i then |
case clk_mstate_i is |
-- write Temp Reg when contents of Program Memory is on bus |
when MSTATE1 => |
alu_write_temp_reg_o <= true; |
|
-- perform AND and store in Accumulator |
when MSTATE3 => |
and_or_xor_add_5_f(alu_op => ALU_AND); |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic ANL_EXT ----------------------------------------------------- |
when MN_ANL_EXT => |
assert_psen_s <= true; |
|
if not clk_second_cycle_i then |
-- read port to Temp Reg |
if clk_mstate_i = MSTATE5 then |
if opc_opcode_s(1 downto 0) = "00" then |
add_read_bus_s <= true; |
elsif opc_opcode_s(1) = '0' then |
p1_read_p1_o <= true; |
p1_read_reg_o <= true; |
else |
p2_read_p2_o <= true; |
p2_read_reg_o <= true; |
end if; |
|
alu_write_temp_reg_o <= true; |
end if; |
|
else |
case clk_mstate_i is |
-- write shadow Accumulator when contents of Program Memory is |
-- on bus |
when MSTATE1 => |
alu_write_shadow_o <= true; |
|
-- loop shadow Accumulator through ALU to prevent update from |
-- real Accumulator |
when MSTATE2 => |
alu_read_alu_o <= true; |
alu_write_shadow_o <= true; |
|
-- write result of AND operation back to port |
when MSTATE3 => |
alu_op_o <= ALU_AND; |
alu_read_alu_o <= true; |
|
if opc_opcode_s(1 downto 0) = "00" then |
bus_write_bus_o <= true; |
elsif opc_opcode_s(1) = '0' then |
p1_write_p1_o <= true; |
else |
p2_write_p2_o <= true; |
end if; |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic CALL -------------------------------------------------------- |
when MN_CALL => |
assert_psen_s <= true; |
|
if not clk_second_cycle_i then |
case clk_mstate_i is |
-- read Stack Pointer and address Data Memory for low byte |
-- also increment Program Counter to point to next instruction |
when MSTATE3 => |
psw_read_sp_o <= true; |
dm_write_dmem_addr_o <= true; |
dm_addr_type_o <= DM_STACK; |
|
-- only increment PC if this is not an injected CALL |
-- injected CALLS are not located in Program Memory, |
-- the PC points already to the instruction to be executed |
-- after the interrupt |
if not int_pending_s then |
add_inc_pc_s <= true; |
end if; |
|
-- store Program Counter low byte on stack |
when MSTATE4 => |
pm_read_pcl_o <= true; |
dm_write_dmem_s <= true; |
|
-- store Program Counter high byte and PSW on stack |
-- increment Stack pointer |
when MSTATE5 => |
psw_read_psw_o <= true; |
pm_read_pch_o <= true; |
dm_write_dmem_addr_o <= true; |
dm_addr_type_o <= DM_STACK_HIGH; |
dm_write_dmem_s <= true; |
psw_inc_stackp_o <= true; |
|
when others => |
null; |
|
end case; |
|
else |
case clk_mstate_i is |
-- store address in Program Counter low byte |
when MSTATE1 => |
pm_write_pcl_o <= true; |
branch_taken_s <= true; |
if int_pending_s then |
-- apply low part of vector address manually |
data_s <= (others => '0'); |
data_s(1 downto 0) <= "11"; |
if tim_int_s then |
data_s(2) <= '1'; |
end if; |
read_dec_s <= true; |
end if; |
|
when MSTATE2 => |
pm_write_pch_o <= true; |
read_dec_s <= true; |
if not int_pending_s then |
-- store high part of target address in Program Counter |
data_s <= "0000" & mb_q & opc_opcode_s(7 downto 5); |
else |
-- apply high part of vector address manually |
data_s <= (others => '0'); |
int_executed_s <= true; |
end if; |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic CLR_A ------------------------------------------------------- |
when MN_CLR_A => |
-- write CLR output of ALU to Accumulator |
if clk_mstate_i = MSTATE3 then |
alu_op_o <= ALU_CLR; |
alu_read_alu_o <= true; |
alu_write_accu_o <= true; |
end if; |
|
-- Mnemonic CLR_C ------------------------------------------------------- |
when MN_CLR_C => |
-- store 0 to Carry |
if clk_mstate_i = MSTATE3 then |
psw_special_data_o <= '0'; |
psw_write_carry_o <= true; |
end if; |
|
-- Mnemonic CLR_F ------------------------------------------------------- |
when MN_CLR_F => |
-- store 0 to selected flag |
if clk_mstate_i = MSTATE3 then |
if opc_opcode_s(5) = '0' then |
psw_special_data_o <= '0'; |
psw_write_f0_o <= true; |
else |
clear_f1_s <= true; |
end if; |
|
end if; |
|
-- Mnemonic CPL_A ------------------------------------------------------- |
when MN_CPL_A => |
-- write CPL output of ALU to Accumulator |
if clk_mstate_i = MSTATE3 then |
alu_op_o <= ALU_CPL; |
alu_read_alu_o <= true; |
alu_write_accu_o <= true; |
end if; |
|
-- Mnemnonic CPL_C ------------------------------------------------------ |
when MN_CPL_C => |
-- write inverse of Carry to PSW |
if clk_mstate_i = MSTATE3 then |
psw_special_data_o <= not psw_carry_i; |
psw_write_carry_o <= true; |
end if; |
|
-- Mnemonic CPL_F ------------------------------------------------------- |
when MN_CPL_f => |
-- write inverse of selected flag back to flag |
if clk_mstate_i = MSTATE3 then |
if opc_opcode_s(5) = '0' then |
psw_special_data_o <= not psw_f0_i; |
psw_write_f0_o <= true; |
else |
cpl_f1_s <= true; |
end if; |
|
end if; |
|
-- Mnemonic DA ---------------------------------------------------------- |
when MN_DA => |
alu_op_o <= ALU_ADD; |
|
case clk_mstate_i is |
-- Step 1: Preload Temp Reg with 0x06 |
when MSTATE3 => |
alu_p06_temp_reg_o <= true; |
|
-- Step 2: Check Auxiliary Carry and overflow on low nibble |
-- Add 0x06 to shadow Accumulator if one is true |
when MSTATE4 => |
if psw_aux_carry_i = '1' or alu_da_overflow_i then |
alu_read_alu_o <= true; |
alu_write_shadow_o <= true; |
end if; |
|
-- preload Temp Reg with 0x60 |
alu_p60_temp_reg_o <= true; |
|
-- Step 3: Check overflow on high nibble |
-- Add 0x60 to shadow Accumulator if true and store result |
-- in Accumulator and PSW (only Carry) |
when MSTATE5 => |
alu_da_high_o <= true; |
|
if alu_da_overflow_i then |
psw_special_data_o <= alu_carry_i; |
else |
alu_op_o <= ALU_NOP; |
psw_special_data_o <= '0'; |
end if; |
alu_read_alu_o <= true; |
alu_write_accu_o <= true; |
psw_write_carry_o <= true; |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic DEC --------------------------------------------------------- |
when MN_DEC => |
case clk_mstate_i is |
when MSTATE4 => |
-- DEC Rr: store data from RAM to shadow Accumulator |
if opc_opcode_s(6) = '1' then |
dm_read_dmem_o <= true; |
alu_write_shadow_o <= true; |
end if; |
|
when MSTATE5 => |
alu_op_o <= ALU_DEC; |
alu_read_alu_o <= true; |
|
if opc_opcode_s(6) = '0' then |
-- write DEC of Accumulator to Accumulator |
alu_write_accu_o <= true; |
else |
-- store DEC of shadow Accumulator back to dmem |
dm_write_dmem_s <= true; |
end if; |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic DIS_EN_I ---------------------------------------------------- |
when MN_DIS_EN_I => |
if clk_mstate_i = MSTATE3 then |
if opc_opcode_s(4) = '1' then |
dis_i_s <= true; |
else |
en_i_s <= true; |
end if; |
end if; |
|
-- Mnemonic DIS_EN_TCNTI ------------------------------------------------ |
when MN_DIS_EN_TCNTI => |
if clk_mstate_i = MSTATE3 then |
if opc_opcode_s(4) = '1' then |
dis_tcnti_s <= true; |
else |
en_tcnti_s <= true; |
end if; |
end if; |
|
-- Mnemonic DJNZ -------------------------------------------------------- |
when MN_DJNZ => |
assert_psen_s <= true; |
|
if not clk_second_cycle_i then |
case clk_mstate_i is |
-- store data from RAM to shadow Accumulator |
when MSTATE4 => |
dm_read_dmem_o <= true; |
alu_write_shadow_o <= true; |
|
-- write DEC result of shadow Accumulator back to dmem and |
-- conditional branch logic |
when MSTATE5 => |
alu_op_o <= ALU_DEC; |
alu_read_alu_o <= true; |
dm_write_dmem_s <= true; |
|
cnd_compute_take_o <= true; |
cnd_branch_cond_o <= COND_Z; |
cnd_comp_value_o(0) <= '0'; |
|
when others => |
null; |
|
end case; |
|
else |
-- store address in Program Counter low byte if branch has to |
-- be taken |
cond_jump_c2_m1_f; |
|
end if; |
|
-- Mnemonic ENT0_CLK ---------------------------------------------------- |
when MN_ENT0_CLK => |
if clk_mstate_i = MSTATE3 then |
ent0_clk_s <= true; |
end if; |
|
-- Mnemonic IN ---------------------------------------------------------- |
when MN_IN => |
-- read Port and store in Accumulator |
if clk_second_cycle_i and clk_mstate_i = MSTATE2 then |
alu_write_accu_o <= true; |
|
if opc_opcode_s(1) = '0' then |
p1_read_p1_o <= true; |
else |
p2_read_p2_o <= true; |
end if; |
end if; |
|
-- Mnemonic INS --------------------------------------------------------- |
when MN_INS => |
-- read BUS and store in Accumulator |
if clk_second_cycle_i and clk_mstate_i = MSTATE2 then |
alu_write_accu_o <= true; |
|
add_read_bus_s <= true; |
end if; |
|
-- Mnemonic INC --------------------------------------------------------- |
when MN_INC => |
case clk_mstate_i is |
-- read RAM once for indirect address mode |
when MSTATE3 => |
address_indirect_3_f; |
|
when MSTATE4 => |
-- INC Rr; INC @ Rr: store data from RAM to shadow Accumulator |
if opc_opcode_s(3 downto 2) /= "01" then |
dm_read_dmem_o <= true; |
alu_write_shadow_o <= true; |
end if; |
|
when MSTATE5 => |
alu_op_o <= ALU_INC; |
alu_read_alu_o <= true; |
|
if opc_opcode_s(3 downto 2) = "01" then |
-- write INC output of ALU to Accumulator |
alu_write_accu_o <= true; |
else |
-- store INC of shadow Accumulator back to dmem |
dm_write_dmem_s <= true; |
end if; |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic JBB --------------------------------------------------------- |
when MN_JBB => |
assert_psen_s <= true; |
cnd_branch_cond_o <= COND_ON_BIT; |
|
if not clk_second_cycle_i then |
-- read Accumulator and start branch calculation |
if clk_mstate_i = MSTATE3 then |
alu_read_alu_o <= true; |
cnd_compute_take_o <= true; |
-- cnd_comp_value_o is ok by default assignment |
end if; |
|
else |
-- store address in Program Counter low byte if branch has to |
-- be taken |
cond_jump_c2_m1_f; |
|
end if; |
|
-- Mnemonic JC ---------------------------------------------------------- |
when MN_JC => |
assert_psen_s <= true; |
cnd_branch_cond_o <= COND_C; |
|
if not clk_second_cycle_i then |
-- start branch calculation |
if clk_mstate_i = MSTATE3 then |
cnd_compute_take_o <= true; |
cnd_comp_value_o(0) <= opc_opcode_s(4); |
end if; |
|
else |
-- store address in Program Counter low byte if branch has to |
-- be taken |
cond_jump_c2_m1_f; |
|
end if; |
|
-- Mnemonic JF ---------------------------------------------------------- |
when MN_JF => |
assert_psen_s <= true; |
|
if not clk_second_cycle_i then |
-- start branch calculation |
if clk_mstate_i = MSTATE3 then |
cnd_compute_take_o <= true; |
if opc_opcode_s(7) = '1' then |
-- JF0 |
cnd_branch_cond_o <= COND_F0; |
else |
-- JF1 |
cnd_branch_cond_o <= COND_F1; |
end if; |
|
end if; |
|
else |
-- store address in Program Counter low byte if branch has to |
-- be taken |
cond_jump_c2_m1_f; |
|
end if; |
|
|
-- Mnemonic JMP --------------------------------------------------------- |
when MN_JMP => |
assert_psen_s <= true; |
|
if clk_second_cycle_i then |
case clk_mstate_i is |
-- store address in Program Counter low byte |
when MSTATE1 => |
pm_write_pcl_o <= true; |
branch_taken_s <= true; |
|
-- store high part of target address in Program Counter |
when MSTATE2 => |
data_s <= "0000" & mb_q & opc_opcode_s(7 downto 5); |
read_dec_s <= true; |
pm_write_pch_o <= true; |
|
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic JMPP -------------------------------------------------------- |
when MN_JMPP => |
assert_psen_s <= true; |
|
if not clk_second_cycle_i then |
-- write Accumulator to Program Memory address |
-- (skip page offset update from Program Counter) |
if clk_mstate_i = MSTATE3 then |
alu_read_alu_o <= true; |
pm_addr_type_o <= PM_PAGE; |
end if; |
|
else |
if clk_mstate_i = MSTATE1 then |
-- store address in Program Counter low byte |
pm_write_pcl_o <= true; |
branch_taken_s <= true; |
end if; |
|
end if; |
|
-- Mnemonic JNI --------------------------------------------------------- |
when MN_JNI => |
assert_psen_s <= true; |
cnd_branch_cond_o <= COND_INT; |
|
if not clk_second_cycle_i then |
-- start branch calculation |
if clk_mstate_i = MSTATE3 then |
cnd_compute_take_o <= true; |
end if; |
|
else |
-- store address in Program Counter low byte if branch has to |
-- be taken |
cond_jump_c2_m1_f; |
|
end if; |
|
-- Mnemonic JT ---------------------------------------------------------- |
when MN_JT => |
assert_psen_s <= true; |
if opc_opcode_s(6) = '0' then |
cnd_branch_cond_o <= COND_T0; |
else |
cnd_branch_cond_o <= COND_T1; |
end if; |
|
if not clk_second_cycle_i then |
-- start branch calculation |
if clk_mstate_i = MSTATE3 then |
cnd_compute_take_o <= true; |
cnd_comp_value_o(0) <= opc_opcode_s(4); |
end if; |
|
else |
-- store address in Program Counter low byte if branch has to |
-- be taken |
cond_jump_c2_m1_f; |
|
end if; |
|
-- Mnemonic JTF --------------------------------------------------------- |
when MN_JTF => |
assert_psen_s <= true; |
cnd_branch_cond_o <= COND_TF; |
|
if not clk_second_cycle_i then |
-- start branch calculation |
if clk_mstate_i = MSTATE3 then |
cnd_compute_take_o <= true; |
jtf_executed_s <= true; |
end if; |
|
else |
-- store address in Program Counter low byte if branch has to |
-- be taken |
cond_jump_c2_m1_f; |
|
end if; |
|
-- Mnemonic JZ ---------------------------------------------------------- |
when MN_JZ => |
assert_psen_s <= true; |
cnd_branch_cond_o <= COND_Z; |
|
if not clk_second_cycle_i then |
-- read Accumulator and start branch calculation |
if clk_mstate_i = MSTATE3 then |
alu_read_alu_o <= true; |
cnd_compute_take_o <= true; |
cnd_comp_value_o(0) <= opc_opcode_s(6); |
end if; |
|
else |
-- store address in Program Counter low byte if branch has to |
-- be taken |
cond_jump_c2_m1_f; |
|
end if; |
|
-- Mnemonic MOV_A_DATA -------------------------------------------------- |
when MN_MOV_A_DATA => |
assert_psen_s <= true; |
|
-- Write Accumulator when contents of Program Memory is on bus |
-- during machine state 1 of second cycle. |
if clk_second_cycle_i and clk_mstate_i = MSTATE1 then |
alu_write_accu_o <= true; |
end if; |
|
-- Mnemonic MOV_A_RR ---------------------------------------------------- |
when MN_MOV_A_RR => |
case clk_mstate_i is |
-- read RAM once for indirect address mode |
when MSTATE3 => |
address_indirect_3_f; |
|
-- read data from RAM and store in Accumulator |
when MSTATE4 => |
and_or_xor_add_4_f; |
alu_write_accu_o <= true; |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic MOV_A_PSW --------------------------------------------------- |
when MN_MOV_A_PSW => |
if clk_mstate_i = MSTATE3 then |
psw_read_psw_o <= true; |
psw_read_sp_o <= true; |
alu_write_accu_o <= true; |
end if; |
|
-- Mnemoniv MOV_PSW_A --------------------------------------------------- |
when MN_MOV_PSW_A => |
if clk_mstate_i = MSTATE3 then |
alu_read_alu_o <= true; |
psw_write_psw_o <= true; |
psw_write_sp_o <= true; |
end if; |
|
-- Mnemonic MOV_RR ------------------------------------------------------ |
when MN_MOV_RR => |
case clk_mstate_i is |
-- read RAM once for indirect address mode |
when MSTATE3 => |
address_indirect_3_f; |
|
-- write Accumulator to dmem |
when MSTATE5 => |
alu_read_alu_o <= true; |
dm_write_dmem_s <= true; |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic MOV_RR_DATA ------------------------------------------------- |
when MN_MOV_RR_DATA => |
assert_psen_s <= true; |
|
-- read RAM once for indirect address mode |
if not clk_second_cycle_i and clk_mstate_i = MSTATE3 then |
address_indirect_3_f; |
end if; |
|
-- Write Data Memory when contents of Program Memory is on bus |
-- during machine state 1 of second cycle. |
if clk_second_cycle_i and clk_mstate_i = MSTATE1 then |
dm_write_dmem_s <= true; |
end if; |
|
-- Mnemonic MOV_T ------------------------------------------------------- |
when MN_MOV_T => |
if clk_mstate_i = MSTATE3 then |
if opc_opcode_s(5) = '1' then |
alu_read_alu_o <= true; -- MOV T, A |
tim_write_timer_o <= true; |
else |
tim_read_timer_o <= true; -- MOV A, T |
alu_write_accu_o <= true; |
end if; |
end if; |
|
-- Mnemonic OUTD_PP_A --------------------------------------------------- |
when MN_OUTD_PP_A => |
clk_assert_prog_o <= true; |
|
if not clk_second_cycle_i then |
case clk_mstate_i is |
-- propagate expander port number to Port 2 |
when MSTATE3 => |
|
data_s(7 downto 4) <= (others => '0'); |
data_s(1 downto 0) <= opc_opcode_s(1 downto 0); |
-- decide which 8243 command to use |
case opc_opcode_s(7 downto 4) is |
when "1001" => |
data_s(3 downto 2) <= "11"; -- ANLD command |
when "1000" => |
data_s(3 downto 2) <= "10"; -- ORLD command |
when "0011" => |
data_s(3 downto 2) <= "01"; -- MOVD command |
when others => |
null; |
end case; |
|
read_dec_s <= true; |
p2_write_exp_o <= true; |
|
-- output expander port number on Port 2 while active edge of PROG |
-- write Accumulator to expander port |
when MSTATE4 => |
p2_output_exp_o <= true; |
|
alu_read_alu_o <= true; |
p2_write_exp_o <= true; |
|
when MSTATE5 => |
p2_output_exp_o <= true; |
|
when others => |
null; |
|
end case; |
|
else |
-- hold expander port until inactive edge of PROG |
if clk_mstate_i = MSTATE1 or clk_mstate_i = MSTATE2 then |
p2_output_exp_o <= true; |
end if; |
|
end if; |
|
-- Mnemonic MOVD_A_PP --------------------------------------------------- |
when MN_MOVD_A_PP => |
clk_assert_prog_o <= true; |
|
if not clk_second_cycle_i then |
case clk_mstate_i is |
-- propagate expander port number to Port 2 |
when MSTATE3 => |
data_s <= "0000" & |
"00" & -- 8243 command: read |
opc_opcode_s(1 downto 0); |
read_dec_s <= true; |
p2_write_exp_o <= true; |
|
-- output expander port number on Port 2 while active edge of PROG |
-- write 1's to expander port to set lower nibble of Port 2 to input |
when MSTATE4 => |
p2_output_exp_o <= true; |
|
data_s(nibble_t'range) <= (others => '1'); |
read_dec_s <= true; |
p2_write_exp_o <= true; |
|
when MSTATE5 => |
p2_output_exp_o <= true; |
|
when others => |
null; |
|
end case; |
|
else |
case clk_mstate_i is |
-- hold expander port until inactive edge of PROG |
when MSTATE1 => |
p2_output_exp_o <= true; |
|
-- hold expander port until inactive edge of PROG |
-- write Accumulator with nibble of expander port |
when MSTATE2 => |
p2_output_exp_o <= true; |
p2_read_exp_o <= true; |
alu_write_accu_o <= true; |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic MOVP -------------------------------------------------------- |
when MN_MOVP => |
assert_psen_s <= true; |
|
if not clk_second_cycle_i then |
-- write Accumulator to Program Memory address |
-- (skip page offset update from Program Counter) |
if clk_mstate_i = MSTATE3 then |
alu_read_alu_o <= true; |
if opc_opcode_s(6) = '0' then |
pm_addr_type_o <= PM_PAGE; |
else |
pm_addr_type_o <= PM_PAGE3; |
end if; |
end if; |
|
else |
if clk_mstate_i = MSTATE1 then |
-- store data from Program Memory in Accumulator |
alu_write_accu_o <= true; |
-- trick & treat to prevent additional PC increment |
-- our branch target is the previously incremented PC! |
branch_taken_s <= true; |
end if; |
|
end if; |
|
-- Mnemonic MOVX -------------------------------------------------------- |
when MN_MOVX => |
bus_bidir_bus_o <= true; |
|
if opc_opcode_s(4) = '0' then |
clk_assert_rd_o <= true; |
else |
clk_assert_wr_o <= true; |
end if; |
|
if not clk_second_cycle_i then |
case clk_mstate_i is |
-- read dmem and put contents on BUS as external address |
when MSTATE3 => |
dm_read_dmem_o <= true; |
bus_write_bus_o <= true; |
|
-- store contents of Accumulator to BUS |
when MSTATE5 => |
if opc_opcode_s(4) = '1' then |
alu_read_alu_o <= true; |
bus_write_bus_o <= true; |
end if; |
|
when others => |
null; |
end case; |
|
else |
if clk_mstate_i = MSTATE1 then |
if opc_opcode_s(4) = '0' then |
-- store contents of BUS in Accumulator |
add_read_bus_s <= true; |
alu_write_accu_o <= true; |
else |
-- store contents of Accumulator to BUS |
alu_read_alu_o <= true; |
bus_write_bus_o <= true; |
end if; |
end if; |
|
end if; |
|
-- Mnemonic NOP --------------------------------------------------------- |
when MN_NOP => |
-- nothing to do |
|
-- Mnemonic ORL --------------------------------------------------------- |
when MN_ORL => |
case clk_mstate_i is |
-- read RAM once for indirect address mode |
when MSTATE3 => |
address_indirect_3_f; |
|
-- store data from RAM to Temp Reg |
when MSTATE4 => |
and_or_xor_add_4_f; |
|
-- perform OR and store in Accumulator |
when MSTATE5 => |
and_or_xor_add_5_f(alu_op => ALU_OR); |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic ORL_A_DATA -------------------------------------------------- |
when MN_ORL_A_DATA => |
assert_psen_s <= true; |
|
if clk_second_cycle_i then |
case clk_mstate_i is |
-- write Temp Reg when contents of Program Memory is on bus |
when MSTATE1 => |
alu_write_temp_reg_o <= true; |
|
-- perform OR and store in Accumulator |
when MSTATE3 => |
and_or_xor_add_5_f(alu_op => ALU_OR); |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic ORL_EXT ----------------------------------------------------- |
when MN_ORL_EXT => |
assert_psen_s <= true; |
|
if not clk_second_cycle_i then |
-- read port to Temp Reg |
if clk_mstate_i = MSTATE5 then |
if opc_opcode_s(1 downto 0) = "00" then |
add_read_bus_s <= true; |
elsif opc_opcode_s(1) = '0' then |
p1_read_p1_o <= true; |
p1_read_reg_o <= true; |
else |
p2_read_p2_o <= true; |
p2_read_reg_o <= true; |
end if; |
|
alu_write_temp_reg_o <= true; |
end if; |
|
else |
case clk_mstate_i is |
-- write shadow Accumulator when contents of Program Memory is |
-- on bus |
when MSTATE1 => |
alu_write_shadow_o <= true; |
|
-- loop shadow Accumulator through ALU to prevent update from |
-- real Accumulator |
when MSTATE2 => |
alu_read_alu_o <= true; |
alu_write_shadow_o <= true; |
|
-- write result of OR operation back to port |
when MSTATE3 => |
alu_op_o <= ALU_OR; |
alu_read_alu_o <= true; |
|
if opc_opcode_s(1 downto 0) = "00" then |
bus_write_bus_o <= true; |
elsif opc_opcode_s(1) = '0' then |
p1_write_p1_o <= true; |
else |
p2_write_p2_o <= true; |
end if; |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic OUTL_EXT ---------------------------------------------------- |
when MN_OUTL_EXT => |
-- read Accumulator and store in Port/BUS output register |
if clk_second_cycle_i and clk_mstate_i = MSTATE4 then |
alu_read_alu_o <= true; |
|
if opc_opcode_s(4) = '1' then |
if opc_opcode_s(1) = '0' then |
p1_write_p1_o <= true; |
else |
p2_write_p2_o <= true; |
end if; |
|
else |
bus_write_bus_o <= true; |
|
end if; |
|
end if; |
|
-- Mnemonic RET --------------------------------------------------------- |
when MN_RET => |
if not clk_second_cycle_i then |
case clk_mstate_i is |
-- decrement Stack Pointer |
when MSTATE3 => |
psw_dec_stackp_o <= true; |
|
-- read Stack Pointer and address Data Memory for low byte |
when MSTATE4 => |
psw_read_sp_o <= true; |
dm_write_dmem_addr_o <= true; |
dm_addr_type_o <= DM_STACK; |
|
-- read Data Memory and store to Program Counter low |
-- prepare address to Data memory for high byte |
when MSTATE5 => |
dm_read_dmem_o <= true; |
pm_write_pcl_o <= true; |
dm_write_dmem_addr_o <= true; |
dm_addr_type_o <= DM_STACK_HIGH; |
|
when others => |
null; |
|
end case; |
|
else |
case clk_mstate_i is |
-- read Data Memory and store to Program Counter high and PSW |
when MSTATE1 => |
dm_read_dmem_o <= true; |
pm_write_pch_o <= true; |
if opc_opcode_s(4) = '1' then |
psw_write_psw_o <= true; |
retr_executed_s <= true; |
end if; |
|
when MSTATE2 => |
add_write_pmem_addr_s <= true; |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Mnemonic RL ---------------------------------------------------------- |
when MN_RL => |
if clk_mstate_i = MSTATE3 then |
alu_op_o <= ALU_RL; |
alu_read_alu_o <= true; |
alu_write_accu_o <= true; |
|
if opc_opcode_s(4) = '1' then |
psw_special_data_o <= alu_carry_i; |
psw_write_carry_o <= true; |
alu_use_carry_o <= true; |
end if; |
end if; |
|
-- Mnemonic RR ---------------------------------------------------------- |
when MN_RR => |
if clk_mstate_i = MSTATE3 then |
alu_op_o <= ALU_RR; |
alu_read_alu_o <= true; |
alu_write_accu_o <= true; |
|
if opc_opcode_s(4) = '0' then |
psw_special_data_o <= alu_carry_i; |
psw_write_carry_o <= true; |
alu_use_carry_o <= true; |
end if; |
end if; |
|
-- Mnemonic SEL_MB ------------------------------------------------------ |
when MN_SEL_MB => |
if clk_mstate_i = MSTATE3 then |
if opc_opcode_s(4) = '1' then |
set_mb_s <= true; |
else |
clear_mb_s <= true; |
end if; |
end if; |
|
-- Mnemonic SEL_RB ------------------------------------------------------ |
when MN_SEL_RB => |
if clk_mstate_i = MSTATE3 then |
psw_special_data_o <= opc_opcode_s(4); |
psw_write_bs_o <= true; |
end if; |
|
-- Mnemonic STOP_TCNT --------------------------------------------------- |
when MN_STOP_TCNT => |
if clk_mstate_i = MSTATE3 then |
tim_stop_tcnt_o <= true; |
end if; |
|
-- Mnemonic STRT -------------------------------------------------------- |
when MN_STRT => |
if clk_mstate_i = MSTATE3 then |
if opc_opcode_s(4) = '1' then |
tim_start_t_o <= true; |
else |
tim_start_cnt_o <= true; |
end if; |
end if; |
|
-- Mnemonic SWAP -------------------------------------------------------- |
when MN_SWAP => |
alu_op_o <= ALU_SWAP; |
|
if clk_mstate_i = MSTATE3 then |
alu_read_alu_o <= true; |
alu_write_accu_o <= true; |
end if; |
|
-- Mnemonic XCH --------------------------------------------------------- |
when MN_XCH => |
case clk_mstate_i is |
-- read RAM once for indirect address mode |
when MSTATE3 => |
address_indirect_3_f; |
|
-- store data from RAM in Accumulator and Temp Reg |
-- Accumulator is already shadowed! |
when MSTATE4 => |
dm_read_dmem_o <= true; |
alu_write_accu_o <= true; |
alu_write_temp_reg_o <= true; |
if opc_opcode_s(4) = '1' then |
-- XCHD |
-- only write lower nibble of Accumulator |
alu_accu_low_o <= true; |
end if; |
|
-- store data from shadow (previous) Accumulator to dmem |
when MSTATE5 => |
dm_write_dmem_s <= true; |
alu_read_alu_o <= true; |
if opc_opcode_s(4) = '1' then |
-- XCHD |
-- concatenate shadow Accumulator and Temp Reg |
alu_op_o <= ALU_CONCAT; |
end if; |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic XRL --------------------------------------------------------- |
when MN_XRL => |
case clk_mstate_i is |
-- read RAM once for indirect address mode |
when MSTATE3 => |
address_indirect_3_f; |
|
-- store data from RAM to Temp Reg |
when MSTATE4 => |
and_or_xor_add_4_f; |
|
-- perform XOR and store in Accumulator |
when MSTATE5 => |
and_or_xor_add_5_f(alu_op => ALU_XOR); |
|
when others => |
null; |
|
end case; |
|
-- Mnemonic XRL_A_DATA -------------------------------------------------- |
when MN_XRL_A_DATA => |
assert_psen_s <= true; |
|
if clk_second_cycle_i then |
case clk_mstate_i is |
-- write Temp Reg when contents of Program Memory is on bus |
when MSTATE1 => |
alu_write_temp_reg_o <= true; |
|
-- perform XOR and store in Accumulator |
when MSTATE3 => |
and_or_xor_add_5_f(alu_op => ALU_XOR); |
|
when others => |
null; |
|
end case; |
|
end if; |
|
-- Unimplemented mnemonic ----------------------------------------------- |
when others => |
-- this will behave like a NOP |
|
-- pragma translate_off |
assert false |
report "Mnemonic not yet implemented." |
severity warning; |
-- pragma translate_on |
|
end case; |
|
end process decode; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process regs |
-- |
-- Purpose: |
-- Implements the various registes. |
-- |
regs: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
branch_taken_q <= false; |
f1_q <= '0'; |
mb_q <= '0'; |
t0_dir_q <= '0'; |
-- pragma translate_off |
istrobe_res_q <= '1'; |
istrobe_q <= '0'; |
injected_int_q <= '0'; |
-- pragma translate_on |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
-- branch taken flag |
if branch_taken_s then |
branch_taken_q <= true; |
elsif clk_mstate_i = MSTATE5 then |
-- release flag when new instruction starts |
branch_taken_q <= false; |
end if; |
|
-- Flag 1 |
if clear_f1_s then |
f1_q <= '0'; |
elsif cpl_f1_s then |
f1_q <= not f1_q; |
end if; |
|
-- Memory Bank select |
if clear_mb_s then |
mb_q <= '0'; |
elsif set_mb_s then |
mb_q <= '1'; |
end if; |
|
-- T0 direction selection |
if ent0_clk_s then |
t0_dir_q <= '1'; |
end if; |
|
-- pragma translate_off |
-- Marker for injected instruction ------------------------------------ |
if opc_inj_int_s then |
injected_int_q <= '1'; |
elsif clk_mstate_i = MSTATE5 and last_cycle_s then |
injected_int_q <= '0'; |
end if; |
|
-- Remove istrobe after reset suppression ----------------------------- |
if clk_mstate_i = MSTATE5 and last_cycle_s then |
istrobe_res_q <= '0'; |
end if; |
-- pragma translate_on |
|
end if; |
|
-- pragma translate_off |
-- Instruction Strobe --------------------------------------------------- |
if clk_mstate_i = MSTATE5 and last_cycle_s and |
injected_int_q = '0' then |
if istrobe_res_q = '0' then |
istrobe_q <= '1'; |
end if; |
else |
istrobe_q <= '0'; |
end if; |
-- pragma translate_on |
|
end if; |
|
end process regs; |
-- |
----------------------------------------------------------------------------- |
|
-- pragma translate_off |
-- assign to global signal for testbench |
tb_istrobe_s <= istrobe_q; |
-- pragma translate_on |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
clk_multi_cycle_o <= opc_multi_cycle_s; |
cnd_f1_o <= f1_q; |
cnd_tf_o <= tf_s; |
data_o <= data_s |
when read_dec_s else |
(others => bus_idle_level_c); |
dm_write_dmem_o <= dm_write_dmem_s and en_clk_i; |
pm_inc_pc_o <= pm_inc_pc_s or add_inc_pc_s; |
pm_write_pmem_addr_o <= pm_write_pmem_addr_s or add_write_pmem_addr_s; |
t0_dir_o <= t0_dir_q; |
bus_read_bus_o <= bus_read_bus_s or add_read_bus_s; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.9 2004/04/24 11:22:55 arniml |
-- removed superfluous signal from sensitivity list |
-- |
-- Revision 1.8 2004/04/18 18:57:43 arniml |
-- + enhance instruction strobe generation |
-- + rework address output under EA=1 conditions |
-- |
-- Revision 1.7 2004/04/15 22:06:05 arniml |
-- + add marker for injected calls |
-- + suppress intstruction strobes for injected calls |
-- |
-- Revision 1.6 2004/04/14 20:53:33 arniml |
-- make istrobe visible through testbench package |
-- |
-- Revision 1.5 2004/04/07 22:09:03 arniml |
-- remove unused signals |
-- |
-- Revision 1.4 2004/04/04 14:18:53 arniml |
-- add measures to implement XCHD |
-- |
-- Revision 1.3 2004/03/28 21:15:48 arniml |
-- implemented mnemonic DA |
-- |
-- Revision 1.2 2004/03/28 13:06:32 arniml |
-- implement mnemonics: |
-- + MOVD_A_PP |
-- + OUTD_PP_A -> ANLD PP, A; MOVD PP, A; ORLD PP, A |
-- |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/cond_branch.vhd
0,0 → 1,212
------------------------------------------------------------------------------- |
-- |
-- The Conditional Branch Logic unit. |
-- Decisions whether to take a jump or not are made here. |
-- |
-- $Id: cond_branch.vhd,v 1.2 2004-04-24 23:44:25 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
|
use work.cond_branch_pack.all; |
|
entity cond_branch is |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- Decoder Interface ------------------------------------------------------ |
compute_take_i : in boolean; |
branch_cond_i : in branch_conditions_t; |
take_branch_o : out boolean; |
accu_i : in word_t; |
t0_i : in std_logic; |
t1_i : in std_logic; |
int_n_i : in std_logic; |
f0_i : in std_logic; |
f1_i : in std_logic; |
tf_i : in std_logic; |
carry_i : in std_logic; |
comp_value_i : in comp_value_t |
); |
|
end cond_branch; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
use work.t48_pack.res_active_c; |
use work.t48_pack.clk_active_c; |
|
architecture rtl of cond_branch is |
|
-- marker for branch taken |
signal take_branch_s, |
take_branch_q : boolean; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process decide_take |
-- |
-- Purpose: |
-- Decides whether a branch has to be taken or not. |
-- |
decide_take: process (accu_i, |
branch_cond_i, |
t0_i, t1_i, |
int_n_i, |
f0_i, f1_i, |
tf_i, |
carry_i, |
comp_value_i) |
variable or_v : std_logic; |
begin |
-- default assignment |
take_branch_s <= false; |
or_v := '0'; |
|
case branch_cond_i is |
-- Branch On: Accumulator Bit ------------------------------------------- |
when COND_ON_BIT => |
if accu_i(TO_INTEGER(UNSIGNED(comp_value_i))) = '1' then |
take_branch_s <= true; |
end if; |
|
-- Branch On: Accumulator Zero ------------------------------------------ |
when COND_Z => |
for i in accu_i'range loop |
or_v := or_v or accu_i(i); |
end loop; |
take_branch_s <= or_v = not comp_value_i(0); |
|
-- Branch On: Carry ----------------------------------------------------- |
when COND_C => |
take_branch_s <= carry_i = comp_value_i(0); |
|
-- Branch On: Flag 0 ---------------------------------------------------- |
when COND_F0 => |
take_branch_s <= f0_i = '1'; |
|
-- Branch On: Flag 1 ---------------------------------------------------- |
when COND_F1 => |
take_branch_s <= f1_i = '1'; |
|
-- Branch On: Interrupt ------------------------------------------------- |
when COND_INT => |
take_branch_s <= int_n_i = '0'; |
|
-- Branch On: Test 0 ---------------------------------------------------- |
when COND_T0 => |
take_branch_s <= t0_i = comp_value_i(0); |
|
-- Branch On: Test 1 ---------------------------------------------------- |
when COND_T1 => |
take_branch_s <= t1_i = comp_value_i(0); |
|
-- Branch On: Timer Flag ------------------------------------------------ |
when COND_TF => |
take_branch_s <= tf_i = '1'; |
|
when others => |
-- pragma translate_off |
assert false |
report "Unknown branch condition specified!" |
severity error; |
-- pragma translate_on |
|
end case; |
|
end process decide_take; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process reg |
-- |
-- Purpose: |
-- Implement the marker register. |
-- |
reg: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
take_branch_q <= false; |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
if compute_take_i then |
take_branch_q <= take_branch_s; |
end if; |
|
end if; |
|
end if; |
|
end process reg; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
take_branch_o <= take_branch_q; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
-- |
------------------------------------------------------------------------------- |
/vhdl/system/lpm_rom.vhd
0,0 → 1,437
-------------------------------------------------------------------------- |
-- This VHDL file was developed by Altera Corporation. It may be |
-- freely copied and/or distributed at no cost. Any persons using this |
-- file for any purpose do so at their own risk, and are responsible for |
-- the results of such use. Altera Corporation does not guarantee that |
-- this file is complete, correct, or fit for any particular purpose. |
-- NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. This notice must |
-- accompany any copy of this file. |
-- |
-------------------------------------------------------------------------- |
-- LPM Synthesizable Models (Support string type generic) |
-------------------------------------------------------------------------- |
-- Version 2.0 (lpm 220) Date 01/04/00 |
-- |
-- 1. Fixed LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO and LPM_ROM to correctly |
-- read in values from LPM_FILE (*.hex) when the DATA width is greater |
-- than 16 bits. |
-- 2. Explicit sign conversions are added to standard logic vector |
-- comparisons in LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO, LPM_ROM, and |
-- LPM_COMPARE. |
-- 3. LPM_FIFO_DC is rewritten to have correct outputs. |
-- 4. LPM_FIFO outputs zeros when nothing has been read from it, and |
-- outputs LPM_NUMWORDS mod exp(2, LPM_WIDTHU) when it is full. |
-- 5. Fixed LPM_DIVIDE to divide correctly. |
-------------------------------------------------------------------------- |
-- Version 1.9 (lpm 220) Date 11/30/99 |
-- |
-- 1. Fixed UNUSED file not found problem and initialization problem |
-- with LPM_RAM_DP, LPM_RAM_DQ, and LPM_RAM_IO. |
-- 2. Fixed LPM_MULT when SUM port is not used. |
-- 3. Fixed LPM_FIFO_DC to enable read when rdclock and wrclock rise |
-- at the same time. |
-- 4. Fixed LPM_COUNTER comparison problem when signed library is loaded |
-- and counter is incrementing. |
-- 5. Got rid of "Illegal Character" error message at time = 0 ns when |
-- simulating LPM_COUNTER. |
-------------------------------------------------------------------------- |
-- Version 1.8 (lpm 220) Date 10/25/99 |
-- |
-- 1. Some LPM_PVALUE implementations were missing, and now implemented. |
-- 2. Fixed LPM_COUNTER to count correctly without conversion overflow, |
-- that is, when LPM_MODULUS = 2 ** LPM_WIDTH. |
-- 3. Fixed LPM_RAM_DP sync process sensitivity list to detect wraddress |
-- changes. |
-------------------------------------------------------------------------- |
-- Version 1.7 (lpm 220) Date 07/13/99 |
-- |
-- Changed LPM_RAM_IO so that it can be used to simulate both MP2 and |
-- Quartus behaviour and LPM220-compliant behaviour. |
-------------------------------------------------------------------------- |
-- Version 1.6 (lpm 220) Date 06/15/99 |
-- |
-- 1. Fixed LPM_ADD_SUB sign extension problem and subtraction bug. |
-- 2. Fixed LPM_COUNTER to use LPM_MODULUS value. |
-- 3. Added CIN and COUT port, and discarded EQ port in LPM_COUNTER to |
-- comply with the specfication. |
-- 4. Included LPM_RAM_DP, LPM_RAM_DQ, LPM_RAM_IO, LPM_ROM, LPM_FIFO, and |
-- LPM_FIFO_DC; they are all initialized to 0's. |
-------------------------------------------------------------------------- |
-- Version 1.5 (lpm 220) Date 05/10/99 |
-- |
-- Changed LPM_MODULUS from string type to integer. |
-------------------------------------------------------------------------- |
-- Version 1.4 (lpm 220) Date 02/05/99 |
-- |
-- 1. Added LPM_DIVIDE module. |
-- 2. Added CLKEN port to LPM_MUX, LPM_DECODE, LPM_ADD_SUB, LPM_MULT |
-- and LPM_COMPARE |
-- 3. Replaced the constants holding string with the actual string. |
-------------------------------------------------------------------------- |
-- Version 1.3 Date 07/30/96 |
-- |
-- Modification History |
-- |
-- 1. Changed the DEFAULT value to "UNUSED" for LPM_SVALUE, LPM_AVALUE, |
-- LPM_MODULUS, and LPM_NUMWORDS, LPM_HINT,LPM_STRENGTH, LPM_DIRECTION, |
-- and LPM_PVALUE |
-- |
-- 2. Added the two dimentional port components (AND, OR, XOR, and MUX). |
-------------------------------------------------------------------------- |
-- Excluded Functions: |
-- |
-- LPM_FSM and LPM_TTABLE |
-- |
-------------------------------------------------------------------------- |
-- Assumptions: |
-- |
-- 1. All ports and signal types are std_logic or std_logic_vector |
-- from IEEE 1164 package. |
-- 2. Synopsys std_logic_arith, std_logic_unsigned, and std_logic_signed |
-- package are assumed to be accessible from IEEE library. |
-- 3. lpm_component_package must be accessible from library work. |
-- 4. The default value of LPM_SVALUE, LPM_AVALUE, LPM_MODULUS, LPM_HINT, |
-- LPM_NUMWORDS, LPM_STRENGTH, LPM_DIRECTION, and LPM_PVALUE is |
-- string "UNUSED". |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
--use work.LPM_COMPONENTS.all; |
use std.textio.all; |
|
entity LPM_ROM is |
generic (LPM_WIDTH : positive; |
LPM_WIDTHAD : positive; |
LPM_NUMWORDS : natural := 0; |
LPM_ADDRESS_CONTROL : string := "REGISTERED"; |
LPM_OUTDATA : string := "REGISTERED"; |
LPM_FILE : string; |
LPM_TYPE : string := "LPM_ROM"; |
LPM_HINT : string := "UNUSED"); |
port (ADDRESS : in STD_LOGIC_VECTOR(LPM_WIDTHAD-1 downto 0); |
INCLOCK : in STD_LOGIC := '0'; |
OUTCLOCK : in STD_LOGIC := '0'; |
MEMENAB : in STD_LOGIC := '1'; |
Q : out STD_LOGIC_VECTOR(LPM_WIDTH-1 downto 0)); |
|
function int_to_str( value : integer ) return string is |
variable ivalue,index : integer; |
variable digit : integer; |
variable line_no: string(8 downto 1) := " "; |
begin |
ivalue := value; |
index := 1; |
while (ivalue > 0 ) loop |
digit := ivalue MOD 10; |
ivalue := ivalue/10; |
case digit is |
when 0 => |
line_no(index) := '0'; |
when 1 => |
line_no(index) := '1'; |
when 2 => |
line_no(index) := '2'; |
when 3 => |
line_no(index) := '3'; |
when 4 => |
line_no(index) := '4'; |
when 5 => |
line_no(index) := '5'; |
when 6 => |
line_no(index) := '6'; |
when 7 => |
line_no(index) := '7'; |
when 8 => |
line_no(index) := '8'; |
when 9 => |
line_no(index) := '9'; |
when others => |
ASSERT FALSE |
REPORT "Illegal number!" |
SEVERITY ERROR; |
end case; |
index := index + 1; |
end loop; |
return line_no; |
end; |
|
function hex_str_to_int( str : string ) return integer is |
variable len : integer := str'length; |
variable ivalue : integer := 0; |
variable digit : integer; |
begin |
for i in len downto 1 loop |
case str(i) is |
when '0' => |
digit := 0; |
when '1' => |
digit := 1; |
when '2' => |
digit := 2; |
when '3' => |
digit := 3; |
when '4' => |
digit := 4; |
when '5' => |
digit := 5; |
when '6' => |
digit := 6; |
when '7' => |
digit := 7; |
when '8' => |
digit := 8; |
when '9' => |
digit := 9; |
when 'A' => |
digit := 10; |
when 'a' => |
digit := 10; |
when 'B' => |
digit := 11; |
when 'b' => |
digit := 11; |
when 'C' => |
digit := 12; |
when 'c' => |
digit := 12; |
when 'D' => |
digit := 13; |
when 'd' => |
digit := 13; |
when 'E' => |
digit := 14; |
when 'e' => |
digit := 14; |
when 'F' => |
digit := 15; |
when 'f' => |
digit := 15; |
when others => |
ASSERT FALSE |
REPORT "Illegal character "& str(i) & "in Intel Hex File! " |
SEVERITY ERROR; |
end case; |
ivalue := ivalue * 16 + digit; |
end loop; |
return ivalue; |
end; |
|
procedure Shrink_line(L : inout LINE; pos : in integer) is |
subtype nstring is string(1 to pos); |
variable stmp : nstring; |
begin |
if pos >= 1 then |
read(l, stmp); |
end if; |
end; |
|
end LPM_ROM; |
|
architecture LPM_SYN of lpm_rom is |
|
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0); |
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0); |
|
signal q2, q_tmp, q_reg : std_logic_vector(lpm_width-1 downto 0); |
signal address_tmp, address_reg : std_logic_vector(lpm_widthad-1 downto 0); |
|
begin |
|
enable_mem: process(memenab, q2) |
begin |
if (memenab = '1') then |
q <= q2; |
else |
q <= (OTHERS => 'Z'); |
end if; |
end process; |
|
sync: process(address, address_reg, q_tmp, q_reg) |
begin |
if (lpm_address_control = "REGISTERED") then |
address_tmp <= address_reg; |
else |
address_tmp <= address; |
end if; |
if (lpm_outdata = "REGISTERED") then |
q2 <= q_reg; |
else |
q2 <= q_tmp; |
end if; |
end process; |
|
input_reg: process (inclock) |
begin |
if inclock'event and inclock = '1' then |
address_reg <= address; |
end if; |
end process; |
|
output_reg: process (outclock) |
begin |
if outclock'event and outclock = '1' then |
q_reg <= q_tmp; |
end if; |
end process; |
|
memory: process(memenab, address_tmp) |
variable mem_data : lpm_memory; |
variable mem_data_tmp : integer := 0; |
variable mem_init: boolean := false; |
variable i, j, k, lineno : integer := 0; |
variable buf: line ; |
variable booval: boolean ; |
FILE mem_data_file: TEXT IS IN LPM_FILE; |
variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1); |
variable startadd: string(4 downto 1); |
variable ibase: integer := 0; |
variable ibyte: integer := 0; |
variable istartadd: integer := 0; |
variable check_sum_vec, check_sum_vec_tmp: unsigned(7 downto 0); |
begin |
-- INITIALIZE -- |
if NOT(mem_init) then |
-- INITIALIZE TO 0 -- |
for i in mem_data'LOW to mem_data'HIGH loop |
mem_data(i) := (OTHERS => '0'); |
end loop; |
|
if (LPM_FILE = "UNUSED") then |
ASSERT FALSE |
REPORT "Initialization file not found!" |
SEVERITY ERROR; |
else |
WHILE NOT ENDFILE(mem_data_file) loop |
booval := true; |
READLINE(mem_data_file, buf); |
lineno := lineno + 1; |
check_sum_vec := (OTHERS => '0'); |
if (buf(buf'LOW) = ':') then |
i := 1; |
shrink_line(buf, i); |
READ(L=>buf, VALUE=>byte, good=>booval); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!" |
SEVERITY ERROR; |
end if; |
ibyte := hex_str_to_int(byte); |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(ibyte, 8); |
READ(L=>buf, VALUE=>startadd, good=>booval); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
istartadd := hex_str_to_int(startadd); |
addr(2) := startadd(4); |
addr(1) := startadd(3); |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(addr), check_sum_vec'length); |
addr(2) := startadd(2); |
addr(1) := startadd(1); |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(addr), check_sum_vec'length); |
READ(L=>buf, VALUE=>rec_type, good=>booval); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(rec_type), check_sum_vec'length); |
else |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
case rec_type is |
when "00"=> -- Data record |
i := 0; |
k := lpm_width / 8; |
if ((lpm_width MOD 8) /= 0) then |
k := k + 1; |
end if; |
-- k = no. of bytes per CAM entry. |
while (i < ibyte) loop |
mem_data_tmp := 0; |
for j in 1 to k loop |
READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time. |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(datain), check_sum_vec'length); |
mem_data_tmp := mem_data_tmp * 256 + hex_str_to_int(datain); |
end loop; |
i := i + k; |
mem_data(ibase + istartadd) := STD_LOGIC_VECTOR(to_unsigned(mem_data_tmp, lpm_width)); |
istartadd := istartadd + 1; |
end loop; |
when "01"=> |
exit; |
when "02"=> |
ibase := 0; |
if (ibyte /= 2) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! " |
SEVERITY ERROR; |
end if; |
for i in 0 to (ibyte-1) loop |
READ(L=>buf, VALUE=>base,good=>booval); |
ibase := ibase * 256 + hex_str_to_int(base); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(base), check_sum_vec'length); |
end loop; |
ibase := ibase * 16; |
when OTHERS => |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! " |
SEVERITY ERROR; |
end case; |
READ(L=>buf, VALUE=>checksum,good=>booval); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! " |
SEVERITY ERROR; |
end if; |
|
check_sum_vec := unsigned(not (check_sum_vec)) + 1 ; |
check_sum_vec_tmp := to_unsigned(hex_str_to_int(checksum),8); |
|
if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!" |
SEVERITY ERROR; |
end if; |
end loop; |
end if; |
mem_init := TRUE; |
end if; |
|
-- MEMORY FUNCTION -- |
--if memenab = '1' then |
q_tmp <= mem_data(to_integer(UNSIGNED(address_tmp))); |
--else |
-- q_tmp <= (OTHERS => 'Z'); |
--end if; |
end process; |
|
end LPM_SYN; |
|
|
--------------------------------------------------------------------------- |
|
|
-- pragma translate_off |
configuration lpm_rom_c0 of lpm_rom is |
|
for lpm_syn |
end for; |
|
end lpm_rom_c0; |
-- pragma translate_on |
/vhdl/system/lpm_ram_dq.vhd
0,0 → 1,439
-------------------------------------------------------------------------- |
-- This VHDL file was developed by Altera Corporation. It may be |
-- freely copied and/or distributed at no cost. Any persons using this |
-- file for any purpose do so at their own risk, and are responsible for |
-- the results of such use. Altera Corporation does not guarantee that |
-- this file is complete, correct, or fit for any particular purpose. |
-- NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. This notice must |
-- accompany any copy of this file. |
-- |
-------------------------------------------------------------------------- |
-- LPM Synthesizable Models (Support string type generic) |
-------------------------------------------------------------------------- |
-- Version 2.0 (lpm 220) Date 01/04/00 |
-- |
-- 1. Fixed LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO and LPM_ROM to correctly |
-- read in values from LPM_FILE (*.hex) when the DATA width is greater |
-- than 16 bits. |
-- 2. Explicit sign conversions are added to standard logic vector |
-- comparisons in LPM_RAM_DQ, LPM_RAM_DP, LPM_RAM_IO, LPM_ROM, and |
-- LPM_COMPARE. |
-- 3. LPM_FIFO_DC is rewritten to have correct outputs. |
-- 4. LPM_FIFO outputs zeros when nothing has been read from it, and |
-- outputs LPM_NUMWORDS mod exp(2, LPM_WIDTHU) when it is full. |
-- 5. Fixed LPM_DIVIDE to divide correctly. |
-------------------------------------------------------------------------- |
-- Version 1.9 (lpm 220) Date 11/30/99 |
-- |
-- 1. Fixed UNUSED file not found problem and initialization problem |
-- with LPM_RAM_DP, LPM_RAM_DQ, and LPM_RAM_IO. |
-- 2. Fixed LPM_MULT when SUM port is not used. |
-- 3. Fixed LPM_FIFO_DC to enable read when rdclock and wrclock rise |
-- at the same time. |
-- 4. Fixed LPM_COUNTER comparison problem when signed library is loaded |
-- and counter is incrementing. |
-- 5. Got rid of "Illegal Character" error message at time = 0 ns when |
-- simulating LPM_COUNTER. |
-------------------------------------------------------------------------- |
-- Version 1.8 (lpm 220) Date 10/25/99 |
-- |
-- 1. Some LPM_PVALUE implementations were missing, and now implemented. |
-- 2. Fixed LPM_COUNTER to count correctly without conversion overflow, |
-- that is, when LPM_MODULUS = 2 ** LPM_WIDTH. |
-- 3. Fixed LPM_RAM_DP sync process sensitivity list to detect wraddress |
-- changes. |
-------------------------------------------------------------------------- |
-- Version 1.7 (lpm 220) Date 07/13/99 |
-- |
-- Changed LPM_RAM_IO so that it can be used to simulate both MP2 and |
-- Quartus behaviour and LPM220-compliant behaviour. |
-------------------------------------------------------------------------- |
-- Version 1.6 (lpm 220) Date 06/15/99 |
-- |
-- 1. Fixed LPM_ADD_SUB sign extension problem and subtraction bug. |
-- 2. Fixed LPM_COUNTER to use LPM_MODULUS value. |
-- 3. Added CIN and COUT port, and discarded EQ port in LPM_COUNTER to |
-- comply with the specfication. |
-- 4. Included LPM_RAM_DP, LPM_RAM_DQ, LPM_RAM_IO, LPM_ROM, LPM_FIFO, and |
-- LPM_FIFO_DC; they are all initialized to 0's. |
-------------------------------------------------------------------------- |
-- Version 1.5 (lpm 220) Date 05/10/99 |
-- |
-- Changed LPM_MODULUS from string type to integer. |
-------------------------------------------------------------------------- |
-- Version 1.4 (lpm 220) Date 02/05/99 |
-- |
-- 1. Added LPM_DIVIDE module. |
-- 2. Added CLKEN port to LPM_MUX, LPM_DECODE, LPM_ADD_SUB, LPM_MULT |
-- and LPM_COMPARE |
-- 3. Replaced the constants holding string with the actual string. |
-------------------------------------------------------------------------- |
-- Version 1.3 Date 07/30/96 |
-- |
-- Modification History |
-- |
-- 1. Changed the DEFAULT value to "UNUSED" for LPM_SVALUE, LPM_AVALUE, |
-- LPM_MODULUS, and LPM_NUMWORDS, LPM_HINT,LPM_STRENGTH, LPM_DIRECTION, |
-- and LPM_PVALUE |
-- |
-- 2. Added the two dimentional port components (AND, OR, XOR, and MUX). |
-------------------------------------------------------------------------- |
-- Excluded Functions: |
-- |
-- LPM_FSM and LPM_TTABLE |
-- |
-------------------------------------------------------------------------- |
-- Assumptions: |
-- |
-- 1. All ports and signal types are std_logic or std_logic_vector |
-- from IEEE 1164 package. |
-- 2. Synopsys std_logic_arith, std_logic_unsigned, and std_logic_signed |
-- package are assumed to be accessible from IEEE library. |
-- 3. lpm_component_package must be accessible from library work. |
-- 4. The default value of LPM_SVALUE, LPM_AVALUE, LPM_MODULUS, LPM_HINT, |
-- LPM_NUMWORDS, LPM_STRENGTH, LPM_DIRECTION, and LPM_PVALUE is |
-- string "UNUSED". |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
--use IEEE.std_logic_unsigned.all; |
use std.textio.all; |
|
entity LPM_RAM_DQ is |
generic (LPM_WIDTH : positive; |
LPM_WIDTHAD : positive; |
LPM_NUMWORDS : natural := 0; |
LPM_INDATA : string := "REGISTERED"; |
LPM_ADDRESS_CONTROL: string := "REGISTERED"; |
LPM_OUTDATA : string := "REGISTERED"; |
LPM_FILE : string := "UNUSED"; |
LPM_TYPE : string := "LPM_RAM_DQ"; |
LPM_HINT : string := "UNUSED"); |
port (DATA : in std_logic_vector(LPM_WIDTH-1 downto 0); |
ADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0); |
INCLOCK : in std_logic := '0'; |
OUTCLOCK : in std_logic := '0'; |
WE : in std_logic; |
Q : out std_logic_vector(LPM_WIDTH-1 downto 0)); |
|
function int_to_str( value : integer ) return string is |
variable ivalue,index : integer; |
variable digit : integer; |
variable line_no: string(8 downto 1) := " "; |
begin |
ivalue := value; |
index := 1; |
while (ivalue > 0) loop |
digit := ivalue MOD 10; |
ivalue := ivalue/10; |
case digit is |
when 0 => |
line_no(index) := '0'; |
when 1 => |
line_no(index) := '1'; |
when 2 => |
line_no(index) := '2'; |
when 3 => |
line_no(index) := '3'; |
when 4 => |
line_no(index) := '4'; |
when 5 => |
line_no(index) := '5'; |
when 6 => |
line_no(index) := '6'; |
when 7 => |
line_no(index) := '7'; |
when 8 => |
line_no(index) := '8'; |
when 9 => |
line_no(index) := '9'; |
when others => |
ASSERT FALSE |
REPORT "Illegal number!" |
SEVERITY ERROR; |
end case; |
index := index + 1; |
end loop; |
return line_no; |
end; |
|
function hex_str_to_int( str : string ) return integer is |
variable len : integer := str'length; |
variable ivalue : integer := 0; |
variable digit : integer; |
begin |
for i in len downto 1 loop |
case str(i) is |
when '0' => |
digit := 0; |
when '1' => |
digit := 1; |
when '2' => |
digit := 2; |
when '3' => |
digit := 3; |
when '4' => |
digit := 4; |
when '5' => |
digit := 5; |
when '6' => |
digit := 6; |
when '7' => |
digit := 7; |
when '8' => |
digit := 8; |
when '9' => |
digit := 9; |
when 'A' => |
digit := 10; |
when 'a' => |
digit := 10; |
when 'B' => |
digit := 11; |
when 'b' => |
digit := 11; |
when 'C' => |
digit := 12; |
when 'c' => |
digit := 12; |
when 'D' => |
digit := 13; |
when 'd' => |
digit := 13; |
when 'E' => |
digit := 14; |
when 'e' => |
digit := 14; |
when 'F' => |
digit := 15; |
when 'f' => |
digit := 15; |
when others => |
ASSERT FALSE |
REPORT "Illegal character "& str(i) & "in Intel Hex File! " |
SEVERITY ERROR; |
end case; |
ivalue := ivalue * 16 + digit; |
end loop; |
return ivalue; |
end; |
|
procedure Shrink_line(L : inout LINE; pos : in integer) is |
subtype nstring is string(1 to pos); |
variable stmp : nstring; |
begin |
if pos >= 1 then |
read(l, stmp); |
end if; |
end; |
|
end LPM_RAM_DQ; |
|
architecture LPM_SYN of lpm_ram_dq is |
|
--type lpm_memory is array(lpm_numwords-1 downto 0) of std_logic_vector(lpm_width-1 downto 0); |
type lpm_memory is array((2**lpm_widthad)-1 downto 0) of std_logic_vector(lpm_width-1 downto 0); |
|
signal data_tmp, data_reg : std_logic_vector(lpm_width-1 downto 0); |
signal q_tmp, q_reg : std_logic_vector(lpm_width-1 downto 0) := (others => '0'); |
signal address_tmp, address_reg : std_logic_vector(lpm_widthad-1 downto 0); |
signal we_tmp, we_reg : std_logic; |
|
begin |
|
sync: process(data, data_reg, address, address_reg, |
we, we_reg, q_tmp, q_reg) |
begin |
if (lpm_address_control = "REGISTERED") then |
address_tmp <= address_reg; |
we_tmp <= we_reg; |
else |
address_tmp <= address; |
we_tmp <= we; |
end if; |
if (lpm_indata = "REGISTERED") then |
data_tmp <= data_reg; |
else |
data_tmp <= data; |
end if; |
if (lpm_outdata = "REGISTERED") then |
q <= q_reg; |
else |
q <= q_tmp; |
end if; |
end process; |
|
input_reg: process (inclock) |
begin |
if inclock'event and inclock = '1' then |
data_reg <= data; |
address_reg <= address; |
we_reg <= we; |
end if; |
end process; |
|
output_reg: process (outclock) |
begin |
if outclock'event and outclock = '1' then |
q_reg <= q_tmp; |
end if; |
end process; |
|
memory: process(data_tmp, we_tmp, address_tmp) |
variable mem_data : lpm_memory; |
variable mem_data_tmp : integer := 0; |
variable mem_init: boolean := false; |
variable i,j,k,lineno: integer := 0; |
variable buf: line ; |
variable booval: boolean ; |
FILE unused_file: TEXT IS OUT "UNUSED"; |
FILE mem_data_file: TEXT IS IN LPM_FILE; |
variable base, byte, rec_type, datain, addr, checksum: string(2 downto 1); |
variable startadd: string(4 downto 1); |
variable ibase: integer := 0; |
variable ibyte: integer := 0; |
variable istartadd: integer := 0; |
variable check_sum_vec, check_sum_vec_tmp: unsigned(7 downto 0); |
begin |
-- INITIALIZE -- |
if NOT(mem_init) then |
-- INITIALIZE TO 0 -- |
for i in mem_data'LOW to mem_data'HIGH loop |
mem_data(i) := (OTHERS => '0'); |
end loop; |
|
if (LPM_FILE = "UNUSED") then |
ASSERT FALSE |
REPORT "Initialization file not found!" |
SEVERITY WARNING; |
else |
WHILE NOT ENDFILE(mem_data_file) loop |
booval := true; |
READLINE(mem_data_file, buf); |
lineno := lineno + 1; |
check_sum_vec := (OTHERS => '0'); |
if (buf(buf'LOW) = ':') then |
i := 1; |
shrink_line(buf, i); |
READ(L=>buf, VALUE=>byte, good=>booval); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format!" |
SEVERITY ERROR; |
end if; |
ibyte := hex_str_to_int(byte); |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(ibyte, check_sum_vec'length); |
READ(L=>buf, VALUE=>startadd, good=>booval); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
istartadd := hex_str_to_int(startadd); |
addr(2) := startadd(4); |
addr(1) := startadd(3); |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(addr), check_sum_vec'length); |
addr(2) := startadd(2); |
addr(1) := startadd(1); |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(addr), check_sum_vec'length); |
READ(L=>buf, VALUE=>rec_type, good=>booval); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(rec_type), check_sum_vec'length); |
else |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
case rec_type is |
when "00"=> -- Data record |
i := 0; |
k := lpm_width / 8; |
if ((lpm_width MOD 8) /= 0) then |
k := k + 1; |
end if; |
-- k = no. of bytes per CAM entry. |
while (i < ibyte) loop |
mem_data_tmp := 0; |
for j in 1 to k loop |
READ(L=>buf, VALUE=>datain,good=>booval); -- read in data a byte (2 hex chars) at a time. |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(datain), check_sum_vec'length); |
mem_data_tmp := mem_data_tmp * 256 + hex_str_to_int(datain); |
end loop; |
i := i + k; |
mem_data(ibase + istartadd) := STD_LOGIC_VECTOR(to_unsigned(mem_data_tmp, lpm_width)); |
istartadd := istartadd + 1; |
end loop; |
when "01"=> |
exit; |
when "02"=> |
ibase := 0; |
if (ibyte /= 2) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format for record type 02! " |
SEVERITY ERROR; |
end if; |
for i in 0 to (ibyte-1) loop |
READ(L=>buf, VALUE=>base,good=>booval); |
ibase := ibase * 256 + hex_str_to_int(base); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal Intel Hex Format! " |
SEVERITY ERROR; |
end if; |
check_sum_vec := unsigned(check_sum_vec) + to_unsigned(hex_str_to_int(base), check_sum_vec'length); |
end loop; |
ibase := ibase * 16; |
when OTHERS => |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Illegal record type in Intel Hex File! " |
SEVERITY ERROR; |
end case; |
READ(L=>buf, VALUE=>checksum,good=>booval); |
if not (booval) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Checksum is missing! " |
SEVERITY ERROR; |
end if; |
|
check_sum_vec := unsigned(not (check_sum_vec)) + 1 ; |
check_sum_vec_tmp := to_unsigned(hex_str_to_int(checksum), check_sum_vec_tmp'length); |
|
if (unsigned(check_sum_vec) /= unsigned(check_sum_vec_tmp)) then |
ASSERT FALSE |
REPORT "[Line "& int_to_str(lineno) & "]:Incorrect checksum!" |
SEVERITY ERROR; |
end if; |
end loop; |
end if; |
mem_init := TRUE; |
end if; |
|
-- MEMORY FUNCTION -- |
if we_tmp = '1' then |
mem_data (to_integer(unsigned(address_tmp))) := data_tmp; |
end if; |
q_tmp <= mem_data(to_integer(unsigned(address_tmp))); |
end process; |
|
end LPM_SYN; |
|
|
-- pragma translate_off |
configuration lpm_ram_dq_c0 of lpm_ram_dq is |
|
for lpm_syn |
end for; |
|
end lpm_ram_dq_c0; |
-- pragma translate_on |
/vhdl/system/t8039-c.vhd
0,0 → 1,27
------------------------------------------------------------------------------- |
-- |
-- T8039 Microcontroller System |
-- |
-- $Id: t8039-c.vhd,v 1.1 2004-04-18 18:51:10 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration t8039_struct_c0 of t8039 is |
|
for struct |
|
for ram_128_b : syn_ram |
use configuration work.syn_ram_lpm_c0; |
end for; |
|
for t48_core_b : t48_core |
use configuration work.t48_core_struct_c0; |
end for; |
|
end for; |
|
end t8039_struct_c0; |
/vhdl/system/t8039.vhd
0,0 → 1,223
------------------------------------------------------------------------------- |
-- |
-- T8039 Microcontroller System |
-- |
-- $Id: t8039.vhd,v 1.1 2004-04-18 18:51:10 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity t8039 is |
|
port ( |
xtal_i : in std_logic; |
reset_n_i : in std_logic; |
t0_b : inout std_logic; |
int_n_i : in std_logic; |
ea_i : in std_logic; |
rd_n_o : out std_logic; |
psen_n_o : out std_logic; |
wr_n_o : out std_logic; |
ale_o : out std_logic; |
db_b : inout std_logic_vector( 7 downto 0); |
t1_i : in std_logic; |
p2_b : inout std_logic_vector( 7 downto 0); |
p1_b : inout std_logic_vector( 7 downto 0); |
prog_n_o : out std_logic |
); |
|
end t8039; |
|
|
use work.t48_core_comp_pack.t48_core; |
use work.t48_core_comp_pack.syn_rom; |
use work.t48_core_comp_pack.syn_ram; |
|
architecture struct of t8039 is |
|
signal t0_s : std_logic; |
signal t0_dir_s : std_logic; |
signal db_s : std_logic_vector( 7 downto 0); |
signal db_dir_s : std_logic; |
signal p2_s : std_logic_vector( 7 downto 0); |
signal p2_low_imp_s : std_logic; |
signal p1_s : std_logic_vector( 7 downto 0); |
signal p1_low_imp_s : std_logic; |
signal xtal3_s : std_logic; |
signal dmem_addr_s : std_logic_vector( 7 downto 0); |
signal dmem_we_s : std_logic; |
signal dmem_data_from_s : std_logic_vector( 7 downto 0); |
signal dmem_data_to_s : std_logic_vector( 7 downto 0); |
signal pmem_data_s : std_logic_vector( 7 downto 0); |
|
begin |
|
-- no Program memory available |
pmem_data_s <= (others => '0'); |
|
t48_core_b : t48_core |
generic map ( |
xtal_div_3_g => 1, |
register_mnemonic_g => 1, |
include_port1_g => 1, |
include_port2_g => 1, |
include_bus_g => 1, |
include_timer_g => 1, |
sample_t1_state_g => 4 |
) |
port map ( |
xtal_i => xtal_i, |
reset_i => reset_n_i, |
t0_i => t0_b, |
t0_o => t0_s, |
t0_dir_o => t0_dir_s, |
int_n_i => int_n_i, |
ea_i => ea_i, |
rd_n_o => rd_n_o, |
psen_n_o => psen_n_o, |
wr_n_o => wr_n_o, |
ale_o => ale_o, |
db_i => db_b, |
db_o => db_s, |
db_dir_o => db_dir_s, |
t1_i => t1_i, |
p2_i => p2_b, |
p2_o => p2_s, |
p2_low_imp_o => p2_low_imp_s, |
p1_i => p1_b, |
p1_o => p1_s, |
p1_low_imp_o => p1_low_imp_s, |
prog_n_o => prog_n_o, |
clk_i => xtal_i, |
en_clk_i => xtal3_s, |
xtal3_o => xtal3_s, |
dmem_addr_o => dmem_addr_s, |
dmem_we_o => dmem_we_s, |
dmem_data_i => dmem_data_from_s, |
dmem_data_o => dmem_data_to_s, |
pmem_addr_o => open, |
pmem_data_i => pmem_data_s |
); |
|
----------------------------------------------------------------------------- |
-- Process bidirs |
-- |
-- Purpose: |
-- Assign bidirectional signals. |
-- |
bidirs: process (t0_b, t0_s, t0_dir_s, |
db_b, db_s, db_dir_s, |
p1_b, p1_s, p1_low_imp_s, |
p2_b, p2_s, p2_low_imp_s) |
|
function open_collector_f(sig : std_logic) return std_logic is |
variable sig_v : std_logic; |
begin |
sig_v := 'Z'; |
|
if sig = '0' then |
sig_v := '0'; |
end if; |
|
return sig_v; |
end; |
|
begin |
-- Test 0 ----------------------------------------------------------------- |
if t0_dir_s = '1' then |
t0_b <= t0_s; |
else |
t0_b <= 'Z'; |
end if; |
|
-- Data Bus --------------------------------------------------------------- |
if db_dir_s = '1' then |
db_b <= db_s; |
else |
db_b <= (others => 'Z'); |
end if; |
|
-- Port 1 ----------------------------------------------------------------- |
for i in p1_b'range loop |
p1_b(i) <= open_collector_f(p1_s(i)); |
end loop; |
-- if p1_low_imp_s = '1' then |
-- p1_b <= p1_s; |
-- else |
-- p1_b <= (others => 'Z'); |
-- end if; |
|
-- Port 2 ----------------------------------------------------------------- |
for i in p2_b'range loop |
p2_b(i) <= open_collector_f(p2_s(i)); |
end loop; |
-- if p2_low_imp_s = '1' then |
-- p2_b <= p2_b_s; |
-- else |
-- p2_b <= (others => 'Z'); |
-- end if; |
|
end process bidirs; |
-- |
----------------------------------------------------------------------------- |
|
ram_128_b : syn_ram |
generic map ( |
address_width_g => 7 |
) |
port map ( |
clk_i => xtal_i, |
res_i => reset_n_i, |
ram_addr_i => dmem_addr_s(6 downto 0), |
ram_data_i => dmem_data_to_s, |
ram_we_i => dmem_we_s, |
ram_data_o => dmem_data_from_s |
); |
|
end struct; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
------------------------------------------------------------------------------- |
/vhdl/system/syn_ram-lpm-a.vhd
0,0 → 1,105
------------------------------------------------------------------------------- |
-- |
-- A synchronous parametrizable RAM instantiating a standard RAM from |
-- the Altera LPM. |
-- |
-- $Id: syn_ram-lpm-a.vhd,v 1.2 2004-04-07 22:09:08 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
architecture lpm of syn_ram is |
|
component lpm_ram_dq |
generic ( |
LPM_WIDTH : positive; |
LPM_TYPE : string := "LPM_RAM_DQ"; |
LPM_WIDTHAD : positive; |
LPM_NUMWORDS : natural := 0; |
LPM_FILE : string := "UNUSED"; |
LPM_INDATA : string := "REGISTERED"; |
LPM_ADDRESS_CONTROL : string := "REGISTERED"; |
LPM_OUTDATA : string := "UNREGISTERED"; |
LPM_HINT : string := "UNUSED" |
); |
port ( |
data : in std_logic_vector(LPM_WIDTH-1 downto 0); |
address : in std_logic_vector(LPM_WIDTHAD-1 downto 0); |
we : in std_logic; |
inclock : in std_logic; |
q : out std_logic_vector(LPM_WIDTH-1 downto 0) |
); |
end component; |
|
begin |
|
ram_b : lpm_ram_dq |
generic map ( |
LPM_WIDTH => 8, |
LPM_TYPE => "LPM_RAM_DQ", |
LPM_WIDTHAD => address_width_g, |
LPM_NUMWORDS => 2 ** address_width_g, |
LPM_FILE => "UNUSED", |
LPM_INDATA => "REGISTERED", |
LPM_ADDRESS_CONTROL => "REGISTERED", |
LPM_OUTDATA => "UNREGISTERED", |
LPM_HINT => "UNUSED" |
) |
port map ( |
data => ram_data_i, |
address => ram_addr_i, |
we => ram_we_i, |
inclock => clk_i, |
q => ram_data_o |
); |
|
end lpm; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/24 21:32:27 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/system/t8048.vhd
0,0 → 1,234
------------------------------------------------------------------------------- |
-- |
-- T8048 Microcontroller System |
-- |
-- $Id: t8048.vhd,v 1.2 2004-03-29 19:40:14 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity t8048 is |
|
port ( |
xtal_i : in std_logic; |
reset_n_i : in std_logic; |
t0_b : inout std_logic; |
int_n_i : in std_logic; |
ea_i : in std_logic; |
rd_n_o : out std_logic; |
psen_n_o : out std_logic; |
wr_n_o : out std_logic; |
ale_o : out std_logic; |
db_b : inout std_logic_vector( 7 downto 0); |
t1_i : in std_logic; |
p2_b : inout std_logic_vector( 7 downto 0); |
p1_b : inout std_logic_vector( 7 downto 0); |
prog_n_o : out std_logic |
); |
|
end t8048; |
|
|
use work.t48_core_comp_pack.t48_core; |
use work.t48_core_comp_pack.syn_rom; |
use work.t48_core_comp_pack.syn_ram; |
|
architecture struct of t8048 is |
|
signal t0_s : std_logic; |
signal t0_dir_s : std_logic; |
signal db_s : std_logic_vector( 7 downto 0); |
signal db_dir_s : std_logic; |
signal p2_s : std_logic_vector( 7 downto 0); |
signal p2_low_imp_s : std_logic; |
signal p1_s : std_logic_vector( 7 downto 0); |
signal p1_low_imp_s : std_logic; |
signal xtal3_s : std_logic; |
signal dmem_addr_s : std_logic_vector( 7 downto 0); |
signal dmem_we_s : std_logic; |
signal dmem_data_from_s : std_logic_vector( 7 downto 0); |
signal dmem_data_to_s : std_logic_vector( 7 downto 0); |
signal pmem_addr_s : std_logic_vector(11 downto 0); |
signal pmem_data_s : std_logic_vector( 7 downto 0); |
|
begin |
|
t48_core_b : t48_core |
generic map ( |
xtal_div_3_g => 1, |
register_mnemonic_g => 1, |
include_port1_g => 1, |
include_port2_g => 1, |
include_bus_g => 1, |
include_timer_g => 1, |
sample_t1_state_g => 4 |
) |
port map ( |
xtal_i => xtal_i, |
reset_i => reset_n_i, |
t0_i => t0_b, |
t0_o => t0_s, |
t0_dir_o => t0_dir_s, |
int_n_i => int_n_i, |
ea_i => ea_i, |
rd_n_o => rd_n_o, |
psen_n_o => psen_n_o, |
wr_n_o => wr_n_o, |
ale_o => ale_o, |
db_i => db_b, |
db_o => db_s, |
db_dir_o => db_dir_s, |
t1_i => t1_i, |
p2_i => p2_b, |
p2_o => p2_s, |
p2_low_imp_o => p2_low_imp_s, |
p1_i => p1_b, |
p1_o => p1_s, |
p1_low_imp_o => p1_low_imp_s, |
prog_n_o => prog_n_o, |
clk_i => xtal_i, |
en_clk_i => xtal3_s, |
xtal3_o => xtal3_s, |
dmem_addr_o => dmem_addr_s, |
dmem_we_o => dmem_we_s, |
dmem_data_i => dmem_data_from_s, |
dmem_data_o => dmem_data_to_s, |
pmem_addr_o => pmem_addr_s, |
pmem_data_i => pmem_data_s |
); |
|
----------------------------------------------------------------------------- |
-- Process bidirs |
-- |
-- Purpose: |
-- Assign bidirectional signals. |
-- |
bidirs: process (t0_b, t0_s, t0_dir_s, |
db_b, db_s, db_dir_s, |
p1_b, p1_s, p1_low_imp_s, |
p2_b, p2_s, p2_low_imp_s) |
|
function open_collector_f(sig : std_logic) return std_logic is |
variable sig_v : std_logic; |
begin |
sig_v := 'Z'; |
|
if sig = '0' then |
sig_v := '0'; |
end if; |
|
return sig_v; |
end; |
|
begin |
-- Test 0 ----------------------------------------------------------------- |
if t0_dir_s = '1' then |
t0_b <= t0_s; |
else |
t0_b <= 'Z'; |
end if; |
|
-- Data Bus --------------------------------------------------------------- |
if db_dir_s = '1' then |
db_b <= db_s; |
else |
db_b <= (others => 'Z'); |
end if; |
|
-- Port 1 ----------------------------------------------------------------- |
for i in p1_b'range loop |
p1_b(i) <= open_collector_f(p1_s(i)); |
end loop; |
-- if p1_low_imp_s = '1' then |
-- p1_b <= p1_s; |
-- else |
-- p1_b <= (others => 'Z'); |
-- end if; |
|
-- Port 2 ----------------------------------------------------------------- |
for i in p2_b'range loop |
p2_b(i) <= open_collector_f(p2_s(i)); |
end loop; |
-- if p2_low_imp_s = '1' then |
-- p2_b <= p2_b_s; |
-- else |
-- p2_b <= (others => 'Z'); |
-- end if; |
|
end process bidirs; |
-- |
----------------------------------------------------------------------------- |
|
rom_1k_b : syn_rom |
generic map ( |
address_width_g => 10 |
) |
port map ( |
clk_i => xtal_i, |
rom_addr_i => pmem_addr_s(9 downto 0), |
rom_data_o => pmem_data_s |
); |
|
ram_64_b : syn_ram |
generic map ( |
address_width_g => 6 |
) |
port map ( |
clk_i => xtal_i, |
res_i => reset_n_i, |
ram_addr_i => dmem_addr_s(5 downto 0), |
ram_data_i => dmem_data_to_s, |
ram_we_i => dmem_we_s, |
ram_data_o => dmem_data_from_s |
); |
|
end struct; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/24 21:32:27 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/system/t8048-c.vhd
0,0 → 1,31
------------------------------------------------------------------------------- |
-- |
-- T8048 Microcontroller System |
-- |
-- $Id: t8048-c.vhd,v 1.1 2004-03-24 21:32:27 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration t8048_struct_c0 of t8048 is |
|
for struct |
|
for rom_1k_b : syn_rom |
use configuration work.syn_rom_lpm_c0; |
end for; |
|
for ram_64_b : syn_ram |
use configuration work.syn_ram_lpm_c0; |
end for; |
|
for t48_core_b : t48_core |
use configuration work.t48_core_struct_c0; |
end for; |
|
end for; |
|
end t8048_struct_c0; |
/vhdl/system/syn_rom-e.vhd
0,0 → 1,60
------------------------------------------------------------------------------- |
-- |
-- A synchronous parametrizable ROM. |
-- |
-- $Id: syn_rom-e.vhd,v 1.1 2004-03-24 21:32:27 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity syn_rom is |
|
generic ( |
address_width_g : positive := 10 |
); |
port ( |
clk_i : in std_logic; |
rom_addr_i : in std_logic_vector(address_width_g-1 downto 0); |
rom_data_o : out std_logic_vector(7 downto 0) |
); |
|
end syn_rom; |
/vhdl/system/syn_ram-e.vhd
0,0 → 1,70
------------------------------------------------------------------------------- |
-- |
-- A synchronous parametrizable RAM. |
-- |
-- $Id: syn_ram-e.vhd,v 1.1 2004-03-24 21:32:27 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
entity syn_ram is |
|
generic ( |
address_width_g : positive := 8 |
); |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
ram_addr_i : in std_logic_vector(address_width_g-1 downto 0); |
ram_data_i : in std_logic_vector(7 downto 0); |
ram_we_i : in std_logic; |
ram_data_o : out std_logic_vector(7 downto 0) |
); |
|
end syn_ram; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
------------------------------------------------------------------------------- |
/vhdl/system/syn_rom-lpm-a.vhd
0,0 → 1,102
------------------------------------------------------------------------------- |
-- |
-- A synchronous parametrizable ROM instantiating a standard ROM from |
-- the Altera LPM. |
-- |
-- $Id: syn_rom-lpm-a.vhd,v 1.1 2004-03-24 21:32:27 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
architecture lpm of syn_rom is |
|
component lpm_rom |
generic ( |
LPM_WIDTH : positive; |
LPM_TYPE : string := "LPM_ROM"; |
LPM_WIDTHAD : positive; |
LPM_NUMWORDS : natural := 0; |
LPM_FILE : string; |
LPM_ADDRESS_CONTROL : string := "REGISTERED"; |
LPM_OUTDATA : string := "REGISTERED"; |
LPM_HINT : string := "UNUSED" |
); |
port ( |
address : in std_logic_vector(LPM_WIDTHAD-1 downto 0); |
inclock : in std_logic; |
memenab : in std_logic; |
q : out std_logic_vector(LPM_WIDTH-1 downto 0) |
); |
end component; |
|
signal one_s : std_logic; |
|
begin |
|
one_s <= '1'; |
|
rom_b : lpm_rom |
generic map ( |
LPM_WIDTH => 8, |
LPM_TYPE => "LPM_ROM", |
LPM_WIDTHAD => address_width_g, |
LPM_NUMWORDS => 2 ** address_width_g, |
LPM_FILE => "t48_rom.hex", |
LPM_ADDRESS_CONTROL => "REGISTERED", |
LPM_OUTDATA => "UNREGISTERED", |
LPM_HINT => "UNUSED" |
) |
port map ( |
address => rom_addr_i, |
inclock => clk_i, |
memenab => one_s, |
q => rom_data_o |
); |
|
end lpm; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
------------------------------------------------------------------------------- |
/vhdl/system/syn_rom-lpm-c.vhd
0,0 → 1,31
------------------------------------------------------------------------------- |
-- |
-- A synchronous parametrizable ROM instantiating a standard ROM from |
-- the Altera LPM. |
-- |
-- $Id: syn_rom-lpm-c.vhd,v 1.1 2004-03-24 21:32:27 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration syn_rom_lpm_c0 of syn_rom is |
|
for lpm |
|
for rom_b : lpm_rom |
use configuration work.lpm_rom_c0; |
end for; |
|
end for; |
|
end syn_rom_lpm_c0; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
------------------------------------------------------------------------------- |
/vhdl/system/syn_ram-lpm-c.vhd
0,0 → 1,31
------------------------------------------------------------------------------- |
-- |
-- A synchronous parametrizable RAM instantiating a standard RAM from |
-- the Altera LPM. |
-- |
-- $Id: syn_ram-lpm-c.vhd,v 1.1 2004-03-24 21:32:27 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration syn_ram_lpm_c0 of syn_ram is |
|
for lpm |
|
for ram_b : lpm_ram_dq |
use configuration work.lpm_ram_dq_c0; |
end for; |
|
end for; |
|
end syn_ram_lpm_c0; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
------------------------------------------------------------------------------- |
/vhdl/dmem_ctrl.vhd
0,0 → 1,214
------------------------------------------------------------------------------- |
-- |
-- The Data Memory control unit. |
-- All accesses to the Data Memory are managed here. |
-- |
-- $Id: dmem_ctrl.vhd,v 1.3 2004-04-24 23:44:25 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.dmem_addr_t; |
use work.t48_pack.word_t; |
use work.dmem_ctrl_pack.dmem_addr_ident_t; |
|
entity dmem_ctrl is |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- Control Interface ------------------------------------------------------ |
data_i : in word_t; |
write_dmem_addr_i : in boolean; |
write_dmem_i : in boolean; |
read_dmem_i : in boolean; |
addr_type_i : in dmem_addr_ident_t; |
bank_select_i : in std_logic; |
data_o : out word_t; |
-- Data Memory Interface -------------------------------------------------- |
dmem_data_i : in word_t; |
dmem_addr_o : out dmem_addr_t; |
dmem_we_o : out std_logic; |
dmem_data_o : out word_t |
); |
|
end dmem_ctrl; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
use work.t48_pack.clk_active_c; |
use work.t48_pack.res_active_c; |
use work.t48_pack.bus_idle_level_c; |
use work.t48_pack.to_stdLogic; |
|
use work.dmem_ctrl_pack.all; |
|
architecture rtl of dmem_ctrl is |
|
signal dmem_addr_s, |
dmem_addr_q : dmem_addr_t; |
begin |
|
----------------------------------------------------------------------------- |
-- Process addr_decode |
-- |
-- Purpose: |
-- Decode/multiplex the address information for the Data Memory. |
-- |
addr_decode: process (data_i, |
addr_type_i, |
bank_select_i, |
dmem_addr_q) |
variable stack_addr_v : unsigned(5 downto 0); |
begin |
-- default assignment |
dmem_addr_s <= dmem_addr_q; |
stack_addr_v := (others => '0'); |
|
case addr_type_i is |
when DM_PLAIN => |
dmem_addr_s <= data_i; |
|
when DM_REG => |
dmem_addr_s <= (others => '0'); |
dmem_addr_s(2 downto 0) <= data_i(2 downto 0); |
-- implement bank switching |
if bank_select_i = '1' then |
-- dmem address 24 - 31: access proper set |
dmem_addr_s(4 downto 3) <= "11"; |
end if; |
|
when DM_STACK => |
-- build address from stack pointer |
stack_addr_v(3 downto 1) := unsigned(data_i(2 downto 0)); |
-- dmem address 8 - 23 |
stack_addr_v := stack_addr_v + 8; |
|
dmem_addr_s <= (others => '0'); |
dmem_addr_s(5 downto 0) <= std_logic_vector(stack_addr_v); |
|
when DM_STACK_HIGH => |
dmem_addr_s(0) <= '1'; |
|
when others => |
-- do nothing |
|
-- pragma translate_off |
assert false |
report "Unknown address type identification for Data Memory controller!" |
severity error; |
-- pragma translate_on |
|
end case; |
|
end process addr_decode; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process dmem_addr_reg |
-- |
-- Purpose: |
-- Implements the Data Memory Address Register. |
-- This register is necessary to hold the address during a write operation |
-- as we cannot hold the address in the input register of the |
-- synchronous RAM (no clock suppression/gating). |
-- |
dmem_addr_reg: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
dmem_addr_q <= (others => '0'); |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
if write_dmem_addr_i then |
dmem_addr_q <= dmem_addr_s; |
end if; |
|
end if; |
|
end if; |
|
end process dmem_addr_reg; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output mapping. |
----------------------------------------------------------------------------- |
dmem_addr_o <= dmem_addr_s |
when write_dmem_addr_i and en_clk_i else |
dmem_addr_q; |
|
-- data from bus is fed through |
dmem_data_o <= data_i; |
|
-- data to bus is enabled upon read request |
data_o <= dmem_data_i |
when read_dmem_i else |
(others => bus_idle_level_c); |
|
-- write enable to Data Memory is fed through |
dmem_we_o <= to_stdLogic(write_dmem_i); |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.2 2004/04/18 18:58:29 arniml |
-- clean up sensitivity list |
-- |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
-- |
------------------------------------------------------------------------------- |
/vhdl/clock_ctrl.vhd
0,0 → 1,394
------------------------------------------------------------------------------- |
-- |
-- The Clock Control unit. |
-- Clock States and Machine Cycles are generated here. |
-- |
-- $Id: clock_ctrl.vhd,v 1.4 2004-04-24 23:44:25 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.all; |
|
entity clock_ctrl is |
|
generic ( |
-- divide XTAL1 by 3 to derive Clock States |
xtal_div_3_g : integer := 1 |
); |
|
port ( |
clk_i : in std_logic; |
xtal_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
xtal3_o : out boolean; |
multi_cycle_i : in boolean; |
assert_psen_i : in boolean; |
assert_prog_i : in boolean; |
assert_rd_i : in boolean; |
assert_wr_i : in boolean; |
mstate_o : out mstate_t; |
second_cycle_o : out boolean; |
ale_o : out boolean; |
psen_o : out boolean; |
prog_o : out boolean; |
rd_o : out boolean; |
wr_o : out boolean |
); |
|
end clock_ctrl; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
architecture rtl of clock_ctrl is |
|
-- The three XTAL1 cycles. |
signal xtal_q : unsigned(1 downto 0); |
signal xtal1_s, |
xtal2_s, |
xtal3_s : boolean; |
signal x1_s, |
x2_s, |
x3_s : std_logic; |
|
|
-- The five clock states. |
signal mstate_q : mstate_t; |
|
signal ale_q : boolean; |
signal psen_q : boolean; |
signal prog_q : boolean; |
signal rd_q : boolean; |
signal wr_q : boolean; |
|
|
-- The Machine Cycle marker. |
signal second_cycle_q : boolean; |
signal multi_cycle_q : boolean; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Verify the generics |
----------------------------------------------------------------------------- |
|
-- pragma translate_off |
|
-- XTAL1 divide by 3 -------------------------------------------------------- |
assert (xtal_div_3_g = 1) or (xtal_div_3_g = 0) |
report "xtal_div_3_g must be either 1 or 0!" |
severity failure; |
|
-- pragma translate_on |
|
|
----------------------------------------------------------------------------- |
-- Divide XTAL1 by 3 to derive Clock States. |
----------------------------------------------------------------------------- |
use_xtal_div: if xtal_div_3_g = 1 generate |
xtal: process (res_i, xtal_i) |
begin |
if res_i = res_active_c then |
xtal_q <= TO_UNSIGNED(0, 2); |
|
elsif xtal_i'event and xtal_i = clk_active_c then |
if xtal_q < 2 then |
xtal_q <= xtal_q + 1; |
else |
xtal_q <= TO_UNSIGNED(0, 2); |
end if; |
|
end if; |
|
end process xtal; |
|
x1_s <= '1' |
when xtal_q = 0 else |
'0'; |
x2_s <= '1' |
when xtal_q = 1 else |
'0'; |
x3_s <= '1' |
when xtal_q = 2 else |
'0'; |
|
end generate; |
|
----------------------------------------------------------------------------- |
-- XTAL1 is used directly for Clock States. |
----------------------------------------------------------------------------- |
no_xtal_div: if xtal_div_3_g = 0 generate |
xtal_q <= TO_UNSIGNED(0, 2); |
|
x1_s <= '1'; |
x2_s <= '1'; |
x3_s <= '1'; |
|
end generate; |
|
-- And finally the boolean flags -------------------------------------------- |
xtal1_s <= to_boolean(x1_s); |
xtal2_s <= to_boolean(x2_s); |
xtal3_s <= to_boolean(x3_s); |
|
|
----------------------------------------------------------------------------- |
-- Process external_signal |
-- |
-- Purpose: |
-- Control signals ALE, PSEN, PROG and RD/WR are generated here. |
-- |
external_signals: process (res_i, xtal_i) |
begin |
if res_i = res_active_c then |
ale_q <= false; |
psen_q <= false; |
prog_q <= false; |
rd_q <= false; |
wr_q <= false; |
|
elsif xtal_i'event and xtal_i = clk_active_c then |
|
case mstate_q is |
when MSTATE5 => |
-- RD, WR are set at the end of XTAL2 of first machine cycle |
if xtal2_s and not second_cycle_q then |
if assert_rd_i then |
rd_q <= true; |
end if; |
if assert_wr_i then |
wr_q <= true; |
end if; |
end if; |
|
when MSTATE1 => |
if xtal3_s then |
psen_q <= false; |
end if; |
|
when MSTATE2 => |
if xtal2_s then |
-- RD, WR are removed at the end of XTAL3 of second machine cycle |
rd_q <= false; |
wr_q <= false; |
-- PROG is removed at the and of XTAL3 of second machine cycle |
prog_q <= false; |
end if; |
|
when MSTATE3 => |
-- ALE is set at the end of XTAL2 of every machine cycle |
if xtal2_s then |
ale_q <= true; |
end if; |
|
when MSTATE4 => |
if xtal3_s then |
-- PSEN is set at the end of XTAL3 |
if assert_psen_i then |
psen_q <= true; |
end if; |
|
end if; |
|
-- PROG is set at the and of XTAL2 |
if xtal2_s and multi_cycle_q and not second_cycle_q and |
assert_prog_i then |
prog_q <= true; |
end if; |
|
-- ALE is removed at the end of XTAL2 of every machine cycle |
if xtal2_s then |
ale_q <= false; |
end if; |
|
when others => |
-- recover when states are out of sync |
ale_q <= false; |
psen_q <= false; |
prog_q <= false; |
rd_q <= false; |
wr_q <= false; |
|
end case; |
|
end if; |
|
end process external_signals; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process states |
-- |
-- Purpose: |
-- The Clock State controller. |
-- |
states: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
-- Reset machine state to MSTATE3 |
-- This allows a proper instruction fetch for the first real instruction |
-- after reset. |
-- The MSTATE3 is part of a virtual NOP that has no MSTATE1 and MSTATE2. |
mstate_q <= MSTATE3; |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
case mstate_q is |
when MSTATE5 => |
mstate_q <= MSTATE1; |
|
when MSTATE1 => |
mstate_q <= MSTATE2; |
|
when MSTATE2 => |
mstate_q <= MSTATE3; |
|
when MSTATE3 => |
mstate_q <= MSTATE4; |
|
when MSTATE4 => |
mstate_q <= MSTATE5; |
|
when others => |
-- recover when states are out of sync |
mstate_q <= MSTATE1; |
|
-- pragma translate_off |
assert false |
report "Encoding of Clock States failed!" |
severity error; |
-- pragma translate_on |
|
end case; |
|
end if; |
|
end if; |
|
end process states; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process machine_cycle |
-- |
-- Purpose: |
-- Keep track of machine cycles. |
-- Basically, this means to differ between first and second cycle. |
-- |
machine_cycle: process (res_i, clk_i) |
variable state2_v, state5_v : boolean; |
begin |
if res_i = res_active_c then |
multi_cycle_q <= false; |
second_cycle_q <= false; |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
state2_v := mstate_q = MSTATE2; |
state5_v := mstate_q = MSTATE5; |
|
-- multi cycle information is delivered in State 2 from the decoder |
if state2_v and multi_cycle_i then |
multi_cycle_q <= true; |
end if; |
|
-- mark second machine cycle |
if multi_cycle_q and state5_v then |
second_cycle_q <= true; |
end if; |
|
-- reset at end of second machine cycle |
if state5_v and |
(multi_cycle_q and second_cycle_q) then |
multi_cycle_q <= false; |
second_cycle_q <= false; |
end if; |
|
end if; |
|
end if; |
|
end process machine_cycle; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output assignments |
----------------------------------------------------------------------------- |
xtal3_o <= xtal3_s; |
mstate_o <= mstate_q; |
second_cycle_o <= second_cycle_q; |
ale_o <= ale_q; |
psen_o <= psen_q; |
prog_o <= prog_q; |
rd_o <= rd_q; |
wr_o <= wr_q; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.3 2004/04/18 18:56:23 arniml |
-- reset machine state to MSTATE3 to allow proper instruction fetch |
-- after reset |
-- |
-- Revision 1.2 2004/03/28 12:55:06 arniml |
-- move code for PROG out of if-branch for xtal3_s |
-- |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
-- |
------------------------------------------------------------------------------- |
/vhdl/p2.vhd
0,0 → 1,206
------------------------------------------------------------------------------- |
-- |
-- The Port 2 unit. |
-- Implements the Port 2 logic. |
-- |
-- $Id: p2.vhd,v 1.4 2004-04-24 23:44:25 arniml Exp $ |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
use work.t48_pack.nibble_t; |
|
entity p2 is |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
data_o : out word_t; |
write_p2_i : in boolean; |
write_exp_i : in boolean; |
read_p2_i : in boolean; |
read_reg_i : in boolean; |
read_exp_i : in boolean; |
-- Port 2 Interface ------------------------------------------------------- |
output_pch_i : in boolean; |
output_exp_i : in boolean; |
pch_i : in nibble_t; |
p2_i : in word_t; |
p2_o : out word_t; |
p2_low_imp_o : out std_logic |
); |
|
end p2; |
|
|
use work.t48_pack.clk_active_c; |
use work.t48_pack.res_active_c; |
use work.t48_pack.bus_idle_level_c; |
|
architecture rtl of p2 is |
|
-- the port output register |
signal p2_q : word_t; |
|
-- the low impedance marker |
signal low_imp_q : std_logic; |
|
-- the expander register |
signal exp_q : nibble_t; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process p2_regs |
-- |
-- Purpose: |
-- Implements the port output and expander registers. |
-- |
p2_regs: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
p2_q <= (others => '1'); |
low_imp_q <= '0'; |
exp_q <= (others => '0'); |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
if write_p2_i then |
p2_q <= data_i; |
low_imp_q <= '1'; |
else |
low_imp_q <= '0'; |
end if; |
|
if write_exp_i then |
exp_q <= data_i(exp_q'range); |
end if; |
|
end if; |
|
end if; |
|
end process p2_regs; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process p2_port |
-- |
-- Purpose: |
-- Generates the output byte vector for Port 2. |
-- |
p2_port: process (p2_q, |
exp_q, |
output_exp_i, |
pch_i, |
output_pch_i) |
begin |
p2_o <= p2_q; |
|
if output_exp_i then |
p2_o(nibble_t'range) <= exp_q; |
end if; |
|
if output_pch_i then |
p2_o(nibble_t'range) <= pch_i; |
end if; |
|
end process p2_port; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process p2_data |
-- |
-- Purpose: |
-- Generates the T48 bus data. |
-- |
p2_data: process (read_p2_i, |
p2_i, |
read_reg_i, |
p2_q, |
read_exp_i) |
begin |
data_o <= (others => bus_idle_level_c); |
|
if read_p2_i then |
data_o <= p2_i; |
elsif read_reg_i then |
data_o <= p2_q; |
elsif read_exp_i then |
data_o <= "0000" & p2_i(nibble_t'range); |
end if; |
|
end process p2_data; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
p2_low_imp_o <= low_imp_q; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.3 2004/03/29 19:39:58 arniml |
-- rename pX_limp to pX_low_imp |
-- |
-- Revision 1.2 2004/03/28 13:11:43 arniml |
-- rework Port 2 expander handling |
-- |
-- Revision 1.1 2004/03/23 21:31:53 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/pmem_ctrl.vhd
0,0 → 1,223
------------------------------------------------------------------------------- |
-- |
-- The Program Memory control unit. |
-- All operations related to the Program Memory are managed here. |
-- |
-- $Id: pmem_ctrl.vhd,v 1.2 2004-04-24 23:44:25 arniml Exp $ |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.pmem_addr_t; |
use work.t48_pack.word_t; |
use work.pmem_ctrl_pack.pmem_addr_ident_t; |
|
entity pmem_ctrl is |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
data_o : out word_t; |
write_pcl_i : in boolean; |
read_pcl_i : in boolean; |
write_pch_i : in boolean; |
read_pch_i : in boolean; |
inc_pc_i : in boolean; |
write_pmem_addr_i : in boolean; |
addr_type_i : in pmem_addr_ident_t; |
read_pmem_i : in boolean; |
-- Porgram Memroy Interface ----------------------------------------------- |
pmem_addr_o : out pmem_addr_t; |
pmem_data_i : in word_t |
); |
|
end pmem_ctrl; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
use work.pmem_ctrl_pack.all; |
use work.t48_pack.res_active_c; |
use work.t48_pack.clk_active_c; |
use work.t48_pack.bus_idle_level_c; |
use work.t48_pack.pmem_addr_width_c; |
use work.t48_pack.dmem_addr_width_c; |
use work.t48_pack.page_t; |
|
architecture rtl of pmem_ctrl is |
|
-- the Program Counter |
signal program_counter_q : unsigned(pmem_addr_t'range); |
|
-- the Program Memory address |
signal pmem_addr_s, |
pmem_addr_q : std_logic_vector(pmem_addr_t'range); |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process program_counter |
-- |
-- Purpose: |
-- Implements the Program Counter. |
-- |
program_counter: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
program_counter_q <= (others => '0'); |
pmem_addr_q <= (others => '0'); |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
-- parallel load mode |
if write_pcl_i then |
program_counter_q(data_i'range) <= UNSIGNED(data_i); |
elsif write_pch_i then |
program_counter_q(pmem_addr_width_c-1 downto data_i'high+1) <= |
UNSIGNED(data_i(pmem_addr_width_c - dmem_addr_width_c - 1 downto 0)); |
elsif inc_pc_i then |
-- increment mode |
program_counter_q <= program_counter_q + 1; |
end if; |
|
-- set pmem address |
if write_pmem_addr_i then |
pmem_addr_q <= pmem_addr_s; |
end if; |
|
end if; |
|
end if; |
|
end process program_counter; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process pmem_addr |
-- |
-- Purpose: |
-- Multiplex the Program Memory address. |
-- |
pmem_addr: process (program_counter_q, |
addr_type_i, |
pmem_addr_q, |
data_i) |
begin |
-- default assignment |
pmem_addr_s <= STD_LOGIC_VECTOR(program_counter_q); |
|
case addr_type_i is |
when PM_PC => |
-- default is ok |
null; |
|
when PM_PAGE => |
pmem_addr_s(word_t'range) <= data_i; |
-- take page address from program counter |
-- => important for JMPP, MOVP! |
-- they must wrap to next page when at FF! |
|
when PM_PAGE3 => |
pmem_addr_s(word_t'range) <= data_i; |
-- page address is explicitely specified |
pmem_addr_s(page_t'range) <= "0011"; |
|
when others => |
null; |
|
end case; |
|
end process pmem_addr; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process data_output |
-- |
-- Purpose: |
-- Multiplex the data bus output. |
-- |
data_output: process (read_pmem_i, |
read_pcl_i, |
read_pch_i, |
pmem_data_i, |
program_counter_q) |
begin |
data_o <= (others => bus_idle_level_c); |
|
if read_pmem_i then |
data_o <= pmem_data_i; |
elsif read_pcl_i then |
data_o <= STD_LOGIC_VECTOR(program_counter_q(data_o'range)); |
elsif read_pch_i then |
data_o(3 downto 0) <= STD_LOGIC_VECTOR(program_counter_q(pmem_addr_width_c-1 downto data_o'high+1)); |
end if; |
|
end process data_output; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
pmem_addr_o <= pmem_addr_q; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/23 21:31:53 arniml |
-- initial check-in |
-- |
-- |
------------------------------------------------------------------------------- |
/vhdl/psw.vhd
0,0 → 1,232
------------------------------------------------------------------------------- |
-- |
-- The Program Status Word (PSW). |
-- Implements the PSW with its special bits. |
-- |
-- $Id: psw.vhd,v 1.6 2004-04-24 23:44:25 arniml Exp $ |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
|
entity psw is |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
data_o : out word_t; |
read_psw_i : in boolean; |
read_sp_i : in boolean; |
write_psw_i : in boolean; |
write_sp_i : in boolean; |
-- Decoder Interface ------------------------------------------------------ |
special_data_i : in std_logic; |
inc_stackp_i : in boolean; |
dec_stackp_i : in boolean; |
write_carry_i : in boolean; |
write_aux_carry_i : in boolean; |
write_f0_i : in boolean; |
write_bs_i : in boolean; |
carry_o : out std_logic; |
aux_carry_i : in std_logic; |
aux_carry_o : out std_logic; |
f0_o : out std_logic; |
bs_o : out std_logic |
); |
|
end psw; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
use work.t48_pack.clk_active_c; |
use work.t48_pack.res_active_c; |
use work.t48_pack.bus_idle_level_c; |
use work.t48_pack.nibble_t; |
|
architecture rtl of psw is |
|
-- special bit positions in PSW |
constant carry_c : natural := 3; |
constant aux_carry_c : natural := 2; |
constant f0_c : natural := 1; |
constant bs_c : natural := 0; |
|
-- the PSW register |
signal psw_q : nibble_t; |
-- the Stack Pointer |
signal sp_q : unsigned(2 downto 0); |
|
-- pragma translate_off |
signal psw_s : word_t; |
-- pragma translate_on |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process psw_reg |
-- |
-- Purpose: |
-- Implements the PSW register. |
-- |
psw_reg: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
psw_q <= (others => '0'); |
sp_q <= (others => '0'); |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
-- T48 bus access |
if write_psw_i then |
psw_q <= data_i(7 downto 4); |
end if; |
if write_sp_i then |
sp_q <= unsigned(data_i(2 downto 0)); |
end if; |
|
-- increment Stack Pointer |
if inc_stackp_i then |
sp_q <= sp_q + 1; |
end if; |
-- decrement Stack Pointer |
if dec_stackp_i then |
sp_q <= sp_q - 1; |
end if; |
|
-- access to special bits |
if write_carry_i then |
psw_q(carry_c) <= special_data_i; |
end if; |
-- |
if write_aux_carry_i then |
psw_q(aux_carry_c) <= aux_carry_i; |
end if; |
-- |
if write_f0_i then |
psw_q(f0_c) <= special_data_i; |
end if; |
-- |
if write_bs_i then |
psw_q(bs_c) <= special_data_i; |
end if; |
|
end if; |
|
end if; |
|
end process psw_reg; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process data_out |
-- |
-- Purpose: |
-- Output multiplexer for T48 Data Bus. |
-- |
data_out: process (read_psw_i, |
read_sp_i, |
psw_q, |
sp_q) |
begin |
data_o <= (others => bus_idle_level_c); |
|
if read_psw_i then |
data_o(7 downto 4) <= psw_q; |
end if; |
|
if read_sp_i then |
data_o(3 downto 0) <= '1' & std_logic_vector(sp_q); |
end if; |
|
end process data_out; |
-- |
----------------------------------------------------------------------------- |
|
|
-- pragma translate_off |
tb: process (psw_q, sp_q) |
begin |
psw_s(7 downto 4) <= psw_q; |
psw_s(3) <= '1'; |
psw_s(2 downto 0) <= std_logic_vector(sp_q); |
end process tb; |
-- pragma translate_on |
|
----------------------------------------------------------------------------- |
-- Output mapping. |
----------------------------------------------------------------------------- |
carry_o <= psw_q(carry_c); |
aux_carry_o <= psw_q(aux_carry_c); |
f0_o <= psw_q(f0_c); |
bs_o <= psw_q(bs_c); |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.5 2004/04/24 11:25:39 arniml |
-- removed dummy_s - workaround not longer needed for GHDL 0.11.1 |
-- |
-- Revision 1.4 2004/04/18 18:59:01 arniml |
-- add temporary workaround for GHDL 0.11 |
-- |
-- Revision 1.3 2004/04/04 14:15:45 arniml |
-- add dump_compare support |
-- |
-- Revision 1.2 2004/03/28 21:28:13 arniml |
-- take auxiliary carry from direct ALU connection |
-- |
-- Revision 1.1 2004/03/23 21:31:53 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/alu.vhd
0,0 → 1,443
------------------------------------------------------------------------------- |
-- |
-- The Arithmetic Logic Unit (ALU). |
-- It contains the ALU core plus the Accumulator and the Temp Reg. |
-- |
-- $Id: alu.vhd,v 1.8 2004-04-24 23:43:56 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
use work.alu_pack.alu_op_t; |
|
entity alu is |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
data_o : out word_t; |
write_accu_i : in boolean; |
write_shadow_i : in boolean; |
write_temp_reg_i : in boolean; |
read_alu_i : in boolean; |
-- Decoder Interface ------------------------------------------------------ |
carry_i : in std_logic; |
carry_o : out std_logic; |
aux_carry_o : out std_logic; |
alu_op_i : in alu_op_t; |
use_carry_i : in boolean; |
da_high_i : in boolean; |
da_overflow_o : out boolean; |
accu_low_i : in boolean; |
p06_temp_reg_i : in boolean; |
p60_temp_reg_i : in boolean |
); |
|
end alu; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
use work.t48_pack.clk_active_c; |
use work.t48_pack.res_active_c; |
use work.t48_pack.bus_idle_level_c; |
use work.t48_pack.nibble_t; |
use work.alu_pack.all; |
|
-- pragma translate_off |
use work.t48_tb_pack.tb_accu_s; |
-- pragma translate_on |
|
architecture rtl of alu is |
|
-- the Accumulator and Temp Reg |
signal accumulator_q, |
accu_shadow_q, |
temp_req_q : word_t; |
-- inputs to the ALU core |
signal in_a_s, |
in_b_s : word_t; |
-- output of the ALU core |
signal data_s : word_t; |
|
signal add_result_s : alu_operand_t; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process working_regs |
-- |
-- Purpose: |
-- Implements the working registers: |
-- + Accumulator |
-- + Temp Reg |
-- |
working_regs: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
accumulator_q <= (others => '0'); |
accu_shadow_q <= (others => '0'); |
temp_req_q <= (others => '0'); |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
if write_accu_i then |
if accu_low_i then |
accumulator_q(nibble_t'range) <= data_i(nibble_t'range); |
else |
accumulator_q <= data_i; |
end if; |
end if; |
|
if write_shadow_i then |
-- write shadow directly from t48 data bus |
accu_shadow_q <= data_i; |
else |
-- default: update shadow Accumulator from real Accumulator |
accu_shadow_q <= accumulator_q; |
end if; |
|
if p06_temp_reg_i then |
-- low nibble of DA sequence |
temp_req_q <= "00000110"; |
elsif p60_temp_reg_i then |
-- high nibble of DA sequence |
temp_req_q <= "01100000"; |
elsif write_temp_reg_i then |
-- normal load from T48 bus |
temp_req_q <= data_i; |
end if; |
|
end if; |
|
end if; |
|
end process working_regs; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Build the inputs to the ALU core. |
-- Input A: |
-- Unary operators use only Input A. |
-- Is always fed from the shadow Accumulator. |
-- Assumption: It never happens that the Accumulator is written and then |
-- read for an ALU operation in the next cycle. |
-- Its contents can thus be staged through the shadow Accu. |
-- Input B: |
-- Is always fed from the Temp Reg. |
----------------------------------------------------------------------------- |
in_a_s <= accu_shadow_q; |
in_b_s <= temp_req_q; |
|
|
----------------------------------------------------------------------------- |
-- Process alu_core |
-- |
-- Purpose: |
-- Implements the ALU core. |
-- All operations defined in alu_op_t are handled here. |
-- |
alu_core: process (in_a_s, |
in_b_s, |
alu_op_i, |
carry_i, |
use_carry_i, |
add_result_s) |
|
begin |
-- default assigments |
data_s <= (others => '0'); |
carry_o <= '0'; |
|
case alu_op_i is |
-- Operation: AND ------------------------------------------------------- |
when ALU_AND => |
data_s <= in_a_s and in_b_s; |
|
-- Operation: OR -------------------------------------------------------- |
when ALU_OR => |
data_s <= in_a_s or in_b_s; |
|
-- Operation: XOR ------------------------------------------------------- |
when ALU_XOR => |
data_s <= in_a_s xor in_b_s; |
|
-- Operation: Add ------------------------------------------------------- |
when ALU_ADD => |
data_s <= add_result_s(data_s'range); |
carry_o <= add_result_s(add_result_s'high); |
|
-- Operation: CPL ------------------------------------------------------- |
when ALU_CPL => |
data_s <= not in_a_s; |
|
-- Operation: CLR ------------------------------------------------------- |
when ALU_CLR => |
data_s <= (others => '0'); |
|
-- Operation: RL -------------------------------------------------------- |
when ALU_RL => |
data_s(7 downto 1) <= in_a_s(6 downto 0); |
carry_o <= in_a_s(7); |
|
if use_carry_i then |
data_s(0) <= carry_i; |
else |
data_s(0) <= in_a_s(7); |
end if; |
|
-- Operation: RR -------------------------------------------------------- |
when ALU_RR => |
data_s(6 downto 0) <= in_a_s(7 downto 1); |
carry_o <= in_a_s(0); |
|
if use_carry_i then |
data_s(7) <= carry_i; |
else |
data_s(7) <= in_a_s(0); |
end if; |
|
-- Operation: Swap ------------------------------------------------------ |
when ALU_SWAP => |
data_s(3 downto 0) <= in_a_s(7 downto 4); |
data_s(7 downto 4) <= in_a_s(3 downto 0); |
|
-- Operation: DEC ------------------------------------------------------- |
when ALU_DEC => |
data_s <= add_result_s(data_s'range); |
|
-- Operation: INC ------------------------------------------------------- |
when ALU_INC => |
data_s <= add_result_s(data_s'range); |
|
-- Operation CONCAT ----------------------------------------------------- |
when ALU_CONCAT => |
data_s <= in_b_s(7 downto 4) & in_a_s(3 downto 0); |
|
-- Operation: NOP ------------------------------------------------------- |
when ALU_NOP => |
data_s <= in_a_s; |
|
when others => |
-- pragma translate_off |
assert false |
report "Unknown ALU operation selected!" |
severity error; |
-- pragma translate_on |
|
end case; |
|
end process alu_core; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process adder |
-- |
-- Purpose: |
-- Implements the adder used by several instructions. |
-- This way of modelling the adder forces resource sharing of: |
-- * ADD |
-- * INC |
-- * DEC |
-- |
adder: process (in_a_s, |
in_b_s, |
alu_op_i, |
carry_i, |
use_carry_i) |
|
variable add_a_v, add_b_v : alu_operand_t; |
variable c_v : alu_operand_t; |
variable result_v : UNSIGNED(alu_operand_t'range); |
variable aux_c_v : std_logic_vector(1 downto 0); |
|
begin |
-- Carry Selection -------------------------------------------------------- |
c_v := (others => '0'); |
if use_carry_i and carry_i = '1' then |
c_v(0) := '1'; |
end if; |
|
-- Operand Selection ------------------------------------------------------ |
-- defaults for ADD |
add_a_v := '0' & in_a_s; |
add_b_v := '0' & in_b_s; |
|
case alu_op_i is |
when ALU_INC => |
add_b_v := (others => '0'); |
add_b_v(0) := '1'; |
when ALU_DEC => |
add_b_v := (others => '1'); |
when others => |
null; |
end case; |
|
-- The Adder -------------------------------------------------------------- |
result_v := UNSIGNED(add_a_v) + |
UNSIGNED(add_b_v) + |
UNSIGNED(c_v); |
|
add_result_s <= std_logic_vector(result_v); |
|
-- Auxiliary Carry -------------------------------------------------------- |
aux_c_v := in_a_s(4) & in_b_s(4); |
|
aux_carry_o <= '0'; |
case aux_c_v is |
when "00" | "11" => |
if result_v(4) = '1' then |
aux_carry_o <= '1'; |
end if; |
|
when "01" | "10" => |
if result_v(4) = '0' then |
aux_carry_o <= '1'; |
end if; |
|
when others => |
null; |
|
end case; |
|
end process adder; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process da_overflow |
-- |
-- Purpose: |
-- Detect overflow situation during DA sequence. |
-- |
da_overflow: process (accu_shadow_q, |
da_high_i) |
|
variable da_nibble_v : nibble_t; |
|
function da_overflow_f(data : in nibble_t) return boolean is |
variable overflow_v : boolean; |
begin |
case data is |
when "1010" | |
"1011" | |
"1100" | |
"1101" | |
"1110" | |
"1111" => |
overflow_v := true; |
when others => |
overflow_v := false; |
end case; |
|
return(overflow_v); |
end; |
|
begin |
if da_high_i then |
da_nibble_v := accu_shadow_q(7 downto 4); |
else |
da_nibble_v := accu_shadow_q(3 downto 0); |
end if; |
|
da_overflow_o <= da_overflow_f(da_nibble_v); |
|
end process da_overflow; |
-- |
----------------------------------------------------------------------------- |
|
|
-- pragma translate_off |
----------------------------------------------------------------------------- |
-- Testbench support. |
----------------------------------------------------------------------------- |
tb_accu_s <= accumulator_q; |
-- pragma translate_on |
|
----------------------------------------------------------------------------- |
-- Output Multiplexer. |
----------------------------------------------------------------------------- |
data_o <= data_s |
when read_alu_i else |
(others => bus_idle_level_c); |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.7 2004/04/07 22:09:03 arniml |
-- remove unused signals |
-- |
-- Revision 1.6 2004/04/07 20:56:23 arniml |
-- default assignment for aux_carry_o |
-- |
-- Revision 1.5 2004/04/06 20:21:53 arniml |
-- fix sensitivity list |
-- |
-- Revision 1.4 2004/04/06 18:10:41 arniml |
-- rework adder and force resource sharing between ADD, INC and DEC |
-- |
-- Revision 1.3 2004/04/04 14:18:52 arniml |
-- add measures to implement XCHD |
-- |
-- Revision 1.2 2004/03/28 21:08:51 arniml |
-- support for DA instruction |
-- |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/timer.vhd
0,0 → 1,261
------------------------------------------------------------------------------- |
-- |
-- The Timer/Counter unit. |
-- |
-- $Id: timer.vhd,v 1.2 2004-04-15 22:05:13 arniml Exp $ |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
use work.t48_pack.mstate_t; |
|
entity timer is |
|
generic ( |
-- state in which T1 is sampled (3 or 4) |
sample_t1_state_g : integer := 4 |
); |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
t1_i : in std_logic; |
clk_mstate_i : in mstate_t; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
data_o : out word_t; |
read_timer_i : in boolean; |
write_timer_i : in boolean; |
-- Decoder Interface ------------------------------------------------------ |
start_t_i : in boolean; |
start_cnt_i : in boolean; |
stop_tcnt_i : in boolean; |
overflow_o : out std_logic |
); |
|
end timer; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
use work.t48_pack.all; |
|
architecture rtl of timer is |
|
-- the 8 bit counter core |
signal counter_q : unsigned(word_t'range); |
signal overflow_q : boolean; |
|
-- increment signal for the counter core |
type inc_type_t is (NONE, TIMER, COUNTER); |
signal increment_s : boolean; |
signal inc_sel_q : inc_type_t; |
|
-- T1 edge detector |
signal t1_q : std_logic; |
signal t1_inc_s : boolean; |
|
-- timer prescaler |
signal prescaler_q : unsigned(4 downto 0); |
signal pre_inc_s : boolean; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Verify the generics |
----------------------------------------------------------------------------- |
|
-- pragma translate_off |
assert (sample_t1_state_g = 3) or (sample_t1_state_g = 4) |
report "sample_t1_state_g must be either 3 or 4!" |
severity failure; |
-- pragma translate_on |
|
|
----------------------------------------------------------------------------- |
-- Process t1_edge |
-- |
-- Purpose: |
-- Implements the edge detector for T1. |
-- |
t1_edge: process (t1_i, |
t1_q, |
clk_mstate_i) |
begin |
t1_inc_s <= false; |
|
-- sample in state according to generic |
-- Old devices: sample at the beginning of state 3 |
-- New devices: sample in state 4 |
if (sample_t1_state_g = 3 and clk_mstate_i = MSTATE3) or |
(sample_t1_state_g = 4 and clk_mstate_i = MSTATE3) then |
-- detect falling edge |
if t1_q = '1' and t1_i = '0' then |
t1_inc_s <= true; |
end if; |
end if; |
|
end process t1_edge; |
-- |
----------------------------------------------------------------------------- |
|
|
pre_inc_s <= clk_mstate_i = MSTATE4 and prescaler_q = 31; |
|
|
----------------------------------------------------------------------------- |
-- Process inc_sel |
-- |
-- Purpose: |
-- Select increment source (timer, counter or none). |
-- |
inc_sel: process (inc_sel_q, |
pre_inc_s, |
t1_inc_s) |
begin |
-- default assignment |
increment_s <= false; |
|
case inc_sel_q is |
when NONE => |
increment_s <= false; |
when TIMER => |
increment_s <= pre_inc_s; |
when COUNTER => |
increment_s <= t1_inc_s; |
when others => |
null; |
end case; |
|
end process inc_sel; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process regs |
-- |
-- Purpose: |
-- Implements the counter, the prescaler and other registers. |
-- |
regs: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
counter_q <= (others => '0'); |
overflow_q <= false; |
t1_q <= '0'; |
prescaler_q <= (others => '0'); |
inc_sel_q <= NONE; |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
-- Counter Core and overflow ------------------------------------------ |
overflow_q <= false; |
|
if write_timer_i then |
counter_q <= unsigned(data_i); |
|
elsif increment_s then |
counter_q <= counter_q + 1; |
|
if counter_q = 255 then |
overflow_q <= true; |
end if; |
|
end if; |
|
-- T1 edge detector --------------------------------------------------- |
if (sample_t1_state_g = 3 and clk_mstate_i = MSTATE3) or |
(sample_t1_state_g = 4 and clk_mstate_i = MSTATE4) then |
t1_q <= t1_i; |
end if; |
|
-- Prescaler ---------------------------------------------------------- |
if start_t_i then |
prescaler_q <= (others => '0'); |
|
elsif clk_mstate_i = MSTATE3 then |
prescaler_q <= prescaler_q + 1; |
|
end if; |
|
-- Increment Selector ------------------------------------------------- |
if start_t_i then |
inc_sel_q <= TIMER; |
elsif start_cnt_i then |
inc_sel_q <= COUNTER; |
elsif stop_tcnt_i then |
inc_sel_q <= NONE; |
end if; |
|
end if; |
|
end if; |
|
end process regs; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
data_o <= std_logic_vector(counter_q) |
when read_timer_i else |
(others => bus_idle_level_c); |
overflow_o <= to_stdLogic(overflow_q); |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/23 21:31:53 arniml |
-- initial check-in |
-- |
-- |
------------------------------------------------------------------------------- |
/vhdl/t48_tb_pack-p.vhd
0,0 → 1,22
------------------------------------------------------------------------------- |
-- |
-- $Id: t48_tb_pack-p.vhd,v 1.2 2004-04-14 20:53:54 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
package t48_tb_pack is |
|
-- Instruction strobe visibility |
signal tb_istrobe_s : std_logic; |
|
-- Accumulator visibilty |
signal tb_accu_s : std_logic_vector(7 downto 0); |
|
end t48_tb_pack; |
/vhdl/t48_comp_pack-p.vhd
0,0 → 1,391
------------------------------------------------------------------------------- |
-- |
-- $Id: t48_comp_pack-p.vhd,v 1.6 2004-04-07 22:09:03 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.alu_pack.alu_op_t; |
use work.cond_branch_pack.branch_conditions_t; |
use work.cond_branch_pack.comp_value_t; |
use work.decoder_pack.mnemonic_t; |
use work.dmem_ctrl_pack.dmem_addr_ident_t; |
use work.pmem_ctrl_pack.pmem_addr_ident_t; |
use work.t48_pack.dmem_addr_t; |
use work.t48_pack.pmem_addr_t; |
use work.t48_pack.mstate_t; |
use work.t48_pack.word_t; |
use work.t48_pack.nibble_t; |
|
package t48_comp_pack is |
|
component alu |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
data_i : in word_t; |
data_o : out word_t; |
write_accu_i : in boolean; |
write_shadow_i : in boolean; |
write_temp_reg_i : in boolean; |
read_alu_i : in boolean; |
carry_i : in std_logic; |
carry_o : out std_logic; |
aux_carry_o : out std_logic; |
alu_op_i : in alu_op_t; |
use_carry_i : in boolean; |
da_high_i : in boolean; |
da_overflow_o : out boolean; |
accu_low_i : in boolean; |
p06_temp_reg_i : in boolean; |
p60_temp_reg_i : in boolean |
); |
end component; |
|
component bus_mux |
port ( |
alu_data_i : in word_t; |
bus_data_i : in word_t; |
dec_data_i : in word_t; |
dm_data_i : in word_t; |
pm_data_i : in word_t; |
p1_data_i : in word_t; |
p2_data_i : in word_t; |
psw_data_i : in word_t; |
tim_data_i : in word_t; |
data_o : out word_t |
); |
end component; |
|
component clock_ctrl |
generic ( |
xtal_div_3_g : integer := 1 |
); |
port ( |
clk_i : in std_logic; |
xtal_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
xtal3_o : out boolean; |
multi_cycle_i : in boolean; |
assert_psen_i : in boolean; |
assert_prog_i : in boolean; |
assert_rd_i : in boolean; |
assert_wr_i : in boolean; |
mstate_o : out mstate_t; |
second_cycle_o : out boolean; |
ale_o : out boolean; |
psen_o : out boolean; |
prog_o : out boolean; |
rd_o : out boolean; |
wr_o : out boolean |
); |
end component; |
|
component cond_branch |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
compute_take_i : in boolean; |
branch_cond_i : in branch_conditions_t; |
take_branch_o : out boolean; |
accu_i : in word_t; |
t0_i : in std_logic; |
t1_i : in std_logic; |
int_n_i : in std_logic; |
f0_i : in std_logic; |
f1_i : in std_logic; |
tf_i : in std_logic; |
carry_i : in std_logic; |
comp_value_i : in comp_value_t |
); |
end component; |
|
component db_bus |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
ea_i : in std_logic; |
data_i : in word_t; |
data_o : out word_t; |
write_bus_i : in boolean; |
read_bus_i : in boolean; |
output_pcl_i : in boolean; |
bidir_bus_i : in boolean; |
pcl_i : in word_t; |
db_i : in word_t; |
db_o : out word_t; |
db_dir_o : out std_logic |
); |
end component; |
|
component decoder |
generic ( |
register_mnemonic_g : integer := 1 |
); |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
ea_i : in std_logic; |
ale_i : in boolean; |
int_n_i : in std_logic; |
t0_dir_o : out std_logic; |
data_i : in word_t; |
data_o : out word_t; |
alu_write_accu_o : out boolean; |
alu_write_shadow_o : out boolean; |
alu_write_temp_reg_o : out boolean; |
alu_read_alu_o : out boolean; |
bus_write_bus_o : out boolean; |
bus_read_bus_o : out boolean; |
dm_write_dmem_addr_o : out boolean; |
dm_write_dmem_o : out boolean; |
dm_read_dmem_o : out boolean; |
p1_write_p1_o : out boolean; |
p1_read_p1_o : out boolean; |
p2_write_p2_o : out boolean; |
p2_write_exp_o : out boolean; |
p2_read_p2_o : out boolean; |
pm_write_pcl_o : out boolean; |
pm_read_pcl_o : out boolean; |
pm_write_pch_o : out boolean; |
pm_read_pch_o : out boolean; |
pm_read_pmem_o : out boolean; |
psw_read_psw_o : out boolean; |
psw_read_sp_o : out boolean; |
psw_write_psw_o : out boolean; |
psw_write_sp_o : out boolean; |
alu_carry_i : in std_logic; |
alu_op_o : out alu_op_t; |
alu_da_high_o : out boolean; |
alu_accu_low_o : out boolean; |
alu_da_overflow_i : in boolean; |
alu_p06_temp_reg_o : out boolean; |
alu_p60_temp_reg_o : out boolean; |
alu_use_carry_o : out boolean; |
bus_output_pcl_o : out boolean; |
bus_bidir_bus_o : out boolean; |
clk_multi_cycle_o : out boolean; |
clk_assert_psen_o : out boolean; |
clk_assert_prog_o : out boolean; |
clk_assert_rd_o : out boolean; |
clk_assert_wr_o : out boolean; |
clk_mstate_i : in mstate_t; |
clk_second_cycle_i : in boolean; |
cnd_compute_take_o : out boolean; |
cnd_branch_cond_o : out branch_conditions_t; |
cnd_take_branch_i : in boolean; |
cnd_comp_value_o : out comp_value_t; |
cnd_f1_o : out std_logic; |
cnd_tf_o : out std_logic; |
dm_addr_type_o : out dmem_addr_ident_t; |
tim_read_timer_o : out boolean; |
tim_write_timer_o : out boolean; |
tim_start_t_o : out boolean; |
tim_start_cnt_o : out boolean; |
tim_stop_tcnt_o : out boolean; |
p1_read_reg_o : out boolean; |
p2_read_reg_o : out boolean; |
p2_read_exp_o : out boolean; |
p2_output_pch_o : out boolean; |
p2_output_exp_o : out boolean; |
pm_inc_pc_o : out boolean; |
pm_write_pmem_addr_o : out boolean; |
pm_addr_type_o : out pmem_addr_ident_t; |
psw_special_data_o : out std_logic; |
psw_carry_i : in std_logic; |
psw_aux_carry_i : in std_logic; |
psw_f0_i : in std_logic; |
psw_inc_stackp_o : out boolean; |
psw_dec_stackp_o : out boolean; |
psw_write_carry_o : out boolean; |
psw_write_aux_carry_o : out boolean; |
psw_write_f0_o : out boolean; |
psw_write_bs_o : out boolean; |
tim_overflow_i : in boolean |
); |
end component; |
|
component dmem_ctrl |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
data_i : in word_t; |
write_dmem_addr_i : in boolean; |
write_dmem_i : in boolean; |
read_dmem_i : in boolean; |
addr_type_i : in dmem_addr_ident_t; |
bank_select_i : in std_logic; |
data_o : out word_t; |
dmem_data_i : in word_t; |
dmem_addr_o : out dmem_addr_t; |
dmem_we_o : out std_logic; |
dmem_data_o : out word_t |
); |
end component; |
|
component int |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
clk_mstate_i : in mstate_t; |
jtf_executed_i : in boolean; |
tim_overflow_i : in boolean; |
tf_o : out std_logic; |
en_tcnti_i : in boolean; |
dis_tcnti_i : in boolean; |
int_n_i : in std_logic; |
ale_i : in boolean; |
last_cycle_i : in boolean; |
en_i_i : in boolean; |
dis_i_i : in boolean; |
ext_int_o : out boolean; |
tim_int_o : out boolean; |
retr_executed_i : in boolean; |
int_executed_i : in boolean; |
int_pending_o : out boolean |
); |
end component; |
|
component opc_table |
port ( |
opcode_i : in word_t; |
multi_cycle_o : out std_logic; |
mnemonic_o : out mnemonic_t |
); |
end component; |
|
component opc_decoder |
generic ( |
register_mnemonic_g : integer := 1 |
); |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
data_i : in word_t; |
read_bus_i : in boolean; |
inj_int_i : in boolean; |
opcode_o : out word_t; |
mnemonic_o : out mnemonic_t; |
multi_cycle_o : out boolean |
); |
end component; |
|
component timer |
generic ( |
sample_t1_state_g : integer := 4 |
); |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
t1_i : in std_logic; |
clk_mstate_i : in mstate_t; |
data_i : in word_t; |
data_o : out word_t; |
read_timer_i : in boolean; |
write_timer_i : in boolean; |
start_t_i : in boolean; |
start_cnt_i : in boolean; |
stop_tcnt_i : in boolean; |
overflow_o : out std_logic |
); |
end component; |
|
component p1 |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
data_i : in word_t; |
data_o : out word_t; |
write_p1_i : in boolean; |
read_p1_i : in boolean; |
read_reg_i : in boolean; |
p1_i : in word_t; |
p1_o : out word_t; |
p1_low_imp_o : out std_logic |
); |
end component; |
|
component p2 |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
data_i : in word_t; |
data_o : out word_t; |
write_p2_i : in boolean; |
write_exp_i : in boolean; |
read_p2_i : in boolean; |
read_reg_i : in boolean; |
read_exp_i : in boolean; |
output_pch_i : in boolean; |
output_exp_i : in boolean; |
pch_i : in nibble_t; |
p2_i : in word_t; |
p2_o : out word_t; |
p2_low_imp_o : out std_logic |
); |
end component; |
|
component pmem_ctrl |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
data_i : in word_t; |
data_o : out word_t; |
write_pcl_i : in boolean; |
read_pcl_i : in boolean; |
write_pch_i : in boolean; |
read_pch_i : in boolean; |
inc_pc_i : in boolean; |
write_pmem_addr_i : in boolean; |
addr_type_i : in pmem_addr_ident_t; |
read_pmem_i : in boolean; |
pmem_addr_o : out pmem_addr_t; |
pmem_data_i : in word_t |
); |
end component; |
|
component psw |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
data_i : in word_t; |
data_o : out word_t; |
read_psw_i : in boolean; |
read_sp_i : in boolean; |
write_psw_i : in boolean; |
write_sp_i : in boolean; |
special_data_i : in std_logic; |
inc_stackp_i : in boolean; |
dec_stackp_i : in boolean; |
write_carry_i : in boolean; |
write_aux_carry_i : in boolean; |
write_f0_i : in boolean; |
write_bs_i : in boolean; |
carry_o : out std_logic; |
aux_carry_i : in std_logic; |
aux_carry_o : out std_logic; |
f0_o : out std_logic; |
bs_o : out std_logic |
); |
end component; |
|
end t48_comp_pack; |
/vhdl/alu_pack-p.vhd
0,0 → 1,46
------------------------------------------------------------------------------- |
-- |
-- $Id: alu_pack-p.vhd,v 1.2 2004-04-04 14:18:53 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_width_c; |
|
package alu_pack is |
|
----------------------------------------------------------------------------- |
-- The ALU operations |
----------------------------------------------------------------------------- |
type alu_op_t is (ALU_AND, ALU_OR, ALU_XOR, |
ALU_CPL, ALU_CLR, |
ALU_RL, ALU_RR, |
ALU_SWAP, |
ALU_DEC, ALU_INC, |
ALU_ADD, |
ALU_CONCAT, |
ALU_NOP); |
|
----------------------------------------------------------------------------- |
-- The dedicated ALU arithmetic types. |
----------------------------------------------------------------------------- |
subtype alu_operand_t is std_logic_vector(word_width_c downto 0); |
|
end alu_pack; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
-- |
------------------------------------------------------------------------------- |
/vhdl/db_bus.vhd
0,0 → 1,148
------------------------------------------------------------------------------- |
-- |
-- The BUS unit. |
-- Implements the BUS port logic. |
-- |
-- $Id: db_bus.vhd,v 1.2 2004-04-04 14:15:45 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
|
entity db_bus is |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
ea_i : in std_logic; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
data_o : out word_t; |
write_bus_i : in boolean; |
read_bus_i : in boolean; |
-- BUS Interface ---------------------------------------------------------- |
output_pcl_i : in boolean; |
bidir_bus_i : in boolean; |
pcl_i : in word_t; |
db_i : in word_t; |
db_o : out word_t; |
db_dir_o : out std_logic |
); |
|
end db_bus; |
|
|
use work.t48_pack.clk_active_c; |
use work.t48_pack.res_active_c; |
use work.t48_pack.bus_idle_level_c; |
use work.t48_pack.to_stdLogic; |
|
architecture rtl of db_bus is |
|
-- the BUS output register |
signal bus_q : word_t; |
|
-- BUS direction marker |
signal db_dir_q : std_logic; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process bus_regs |
-- |
-- Purpose: |
-- Implements the BUS output register. |
-- |
bus_regs: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
bus_q <= (others => '0'); |
db_dir_q <= '0'; |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
if write_bus_i then |
bus_q <= data_i; |
|
db_dir_q <= '1'; |
|
elsif ea_i = '1' or bidir_bus_i then |
db_dir_q <= '0'; |
|
end if; |
|
end if; |
|
end if; |
|
end process bus_regs; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
db_o <= pcl_i |
when output_pcl_i else |
bus_q; |
db_dir_o <= db_dir_q or to_stdLogic(output_pcl_i); |
data_o <= (others => bus_idle_level_c) |
when not read_bus_i else |
db_i; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
-- |
------------------------------------------------------------------------------- |
/vhdl/p1.vhd
0,0 → 1,138
------------------------------------------------------------------------------- |
-- |
-- The Port 1 unit. |
-- Implements the Port 1 logic. |
-- |
-- $Id: p1.vhd,v 1.2 2004-03-29 19:39:58 arniml Exp $ |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
|
entity p1 is |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
data_o : out word_t; |
write_p1_i : in boolean; |
read_p1_i : in boolean; |
read_reg_i : in boolean; |
-- Port 1 Interface ------------------------------------------------------- |
p1_i : in word_t; |
p1_o : out word_t; |
p1_low_imp_o : out std_logic |
); |
|
end p1; |
|
|
use work.t48_pack.clk_active_c; |
use work.t48_pack.res_active_c; |
use work.t48_pack.bus_idle_level_c; |
|
architecture rtl of p1 is |
|
-- the port output register |
signal p1_q : word_t; |
|
-- the low impedance marker |
signal low_imp_q : std_logic; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process p1_reg |
-- |
-- Purpose: |
-- Implements the port output register. |
-- |
p1_reg: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
p1_q <= (others => '1'); |
low_imp_q <= '0'; |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
if write_p1_i then |
p1_q <= data_i; |
low_imp_q <= '1'; |
else |
low_imp_q <= '0'; |
end if; |
|
end if; |
|
end if; |
|
end process p1_reg; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
p1_o <= p1_q; |
p1_low_imp_o <= low_imp_q; |
data_o <= (others => bus_idle_level_c) |
when not read_p1_i else |
p1_q |
when read_reg_i else |
p1_i; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/t48_core_comp_pack-p.vhd
0,0 → 1,87
------------------------------------------------------------------------------- |
-- |
-- $Id: t48_core_comp_pack-p.vhd,v 1.2 2004-03-29 19:39:58 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
package t48_core_comp_pack is |
|
component t48_core |
generic ( |
xtal_div_3_g : integer := 1; |
register_mnemonic_g : integer := 1; |
include_port1_g : integer := 1; |
include_port2_g : integer := 1; |
include_bus_g : integer := 1; |
include_timer_g : integer := 1; |
sample_t1_state_g : integer := 4 |
); |
|
port ( |
xtal_i : in std_logic; |
reset_i : in std_logic; |
t0_i : in std_logic; |
t0_o : out std_logic; |
t0_dir_o : out std_logic; |
int_n_i : in std_logic; |
ea_i : in std_logic; |
rd_n_o : out std_logic; |
psen_n_o : out std_logic; |
wr_n_o : out std_logic; |
ale_o : out std_logic; |
db_i : in std_logic_vector( 7 downto 0); |
db_o : out std_logic_vector( 7 downto 0); |
db_dir_o : out std_logic; |
t1_i : in std_logic; |
p2_i : in std_logic_vector( 7 downto 0); |
p2_o : out std_logic_vector( 7 downto 0); |
p2_low_imp_o : out std_logic; |
p1_i : in std_logic_vector( 7 downto 0); |
p1_o : out std_logic_vector( 7 downto 0); |
p1_low_imp_o : out std_logic; |
prog_n_o : out std_logic; |
clk_i : in std_logic; |
en_clk_i : in std_logic; |
xtal3_o : out std_logic; |
dmem_addr_o : out std_logic_vector( 7 downto 0); |
dmem_we_o : out std_logic; |
dmem_data_i : in std_logic_vector( 7 downto 0); |
dmem_data_o : out std_logic_vector( 7 downto 0); |
pmem_addr_o : out std_logic_vector(11 downto 0); |
pmem_data_i : in std_logic_vector( 7 downto 0) |
); |
end component; |
|
component syn_rom |
generic ( |
address_width_g : positive := 10 |
); |
port ( |
clk_i : in std_logic; |
rom_addr_i : in std_logic_vector(address_width_g-1 downto 0); |
rom_data_o : out std_logic_vector(7 downto 0) |
); |
end component; |
|
component syn_ram |
generic ( |
address_width_g : positive := 8 |
); |
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
ram_addr_i : in std_logic_vector(address_width_g-1 downto 0); |
ram_data_i : in std_logic_vector(7 downto 0); |
ram_we_i : in std_logic; |
ram_data_o : out std_logic_vector(7 downto 0) |
); |
end component; |
|
end t48_core_comp_pack; |
/vhdl/decoder_pack-p.vhd
0,0 → 1,84
------------------------------------------------------------------------------- |
-- |
-- $Id: decoder_pack-p.vhd,v 1.2 2004-03-28 13:09:53 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
package decoder_pack is |
|
----------------------------------------------------------------------------- |
-- The Mnemonics. |
----------------------------------------------------------------------------- |
type mnemonic_t is (MN_ADD, |
MN_ADD_A_DATA, |
MN_ANL, |
MN_ANL_A_DATA, |
MN_ANL_EXT, |
MN_CALL, |
MN_CLR_A, |
MN_CLR_C, |
MN_CLR_F, |
MN_CPL_A, |
MN_CPL_C, |
MN_CPL_F, |
MN_DA, |
MN_DEC, |
MN_DIS_EN_I, |
MN_DIS_EN_TCNTI, |
MN_DJNZ, |
MN_ENT0_CLK, |
MN_IN, |
MN_INC, |
MN_INS, |
MN_JBB, |
MN_JC, |
MN_JF, |
MN_JMP, |
MN_JMPP, |
MN_JNI, |
MN_JT, |
MN_JTF, |
MN_JZ, |
MN_MOV_A_DATA, |
MN_MOV_A_PSW, |
MN_MOV_A_RR, |
MN_MOV_PSW_A, |
MN_MOV_RR, |
MN_MOV_RR_DATA, |
MN_MOV_T, |
MN_MOVD_A_PP, |
MN_MOVP, |
MN_MOVX, |
MN_NOP, |
MN_ORL, |
MN_ORL_A_DATA, |
MN_ORL_EXT, |
MN_OUTD_PP_A, |
MN_OUTL_EXT, |
MN_RET, |
MN_RL, |
MN_RR, |
MN_SEL_MB, |
MN_SEL_RB, |
MN_STOP_TCNT, |
MN_STRT, |
MN_SWAP, |
MN_XCH, |
MN_XRL, |
MN_XRL_A_DATA); |
|
end decoder_pack; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/opc_table.vhd
0,0 → 1,414
------------------------------------------------------------------------------- |
-- |
-- The Opcode Decoder Table. |
-- Decodes the given opcode to instruction mnemonics. |
-- Also derives the multicycle information. |
-- |
-- $Id: opc_table.vhd,v 1.2 2004-03-28 13:10:48 arniml Exp $ |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
use work.decoder_pack.mnemonic_t; |
|
entity opc_table is |
|
port ( |
opcode_i : in word_t; |
multi_cycle_o : out std_logic; |
mnemonic_o : out mnemonic_t |
); |
|
end opc_table; |
|
|
use work.decoder_pack.all; |
|
architecture rtl of opc_table is |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process opc_decode |
-- |
-- Purpose: |
-- Decode the opcode to the set of mnemonics. |
-- |
opc_decode: process (opcode_i) |
begin |
-- default assignment |
mnemonic_o <= MN_NOP; |
multi_cycle_o <= '0'; |
|
case opcode_i is |
-- Mnemonic ADD --------------------------------------------------------- |
when "01101000" | "01101001" | "01101010" | "01101011" | -- ADD A, Rr |
"01101100" | "01101101" | "01101110" | "01101111" | -- |
"01100000" | "01100001" | -- ADD A, @ Rr |
"01111000" | "01111001" | "01111010" | "01111011" | -- ADDC A, Rr |
"01111100" | "01111101" | "01111110" | "01111111" | -- |
"01110000" | "01110001" => -- ADDC A, @ Rr |
mnemonic_o <= MN_ADD; |
|
-- Mnemonic ADD_A_DATA -------------------------------------------------- |
when "00000011" | -- ADD A, data |
"00010011" => -- ADDC A, data |
mnemonic_o <= MN_ADD_A_DATA; |
multi_cycle_o <= '1'; |
|
-- Mnemonic ANL --------------------------------------------------------- |
when "01011000" | "01011001" | "01011010" | "01011011" | -- ANL A, Rr |
"01011100" | "01011101" | "01011110" | "01011111" | -- |
"01010000" | "01010001" => -- ANL A, @ Rr |
mnemonic_o <= MN_ANL; |
|
-- Mnemonic ANL_A_DATA -------------------------------------------------- |
when "01010011" => -- ANL A, data |
mnemonic_o <= MN_ANL_A_DATA; |
multi_cycle_o <= '1'; |
|
-- Mnemonic ANL_EXT ----------------------------------------------------- |
when "10011000" | -- ANL BUS, data |
"10011001" | "10011010" => -- ANL PP, data |
mnemonic_o <= MN_ANL_EXT; |
multi_cycle_o <= '1'; |
|
-- Mnemonic CALL -------------------------------------------------------- |
when "00010100" | "00110100" | "01010100" | "01110100" | -- CALL addr |
"10010100" | "10110100" | "11010100" | "11110100" => -- |
mnemonic_o <= MN_CALL; |
multi_cycle_o <= '1'; |
|
-- Mnemonic CLR_A ------------------------------------------------------- |
when "00100111" => -- CLR A |
mnemonic_o <= MN_CLR_A; |
|
-- Mnemonic CLR_C ------------------------------------------------------- |
when "10010111" => -- CLR C |
mnemonic_o <= MN_CLR_C; |
|
-- Mnemonic CLR_F ------------------------------------------------------- |
when "10000101" | -- CLR F0 |
"10100101" => |
mnemonic_o <= MN_CLR_F; |
|
-- Mnemonic CPL_A ------------------------------------------------------- |
when "00110111" => -- CPL A |
mnemonic_o <= MN_CPL_A; |
|
-- Mnemonic CPL_C ------------------------------------------------------- |
when "10100111" => -- CPL C |
mnemonic_o <= MN_CPL_C; |
|
-- Mnemonic CPL_F ------------------------------------------------------- |
when "10010101" | -- CPL F0 |
"10110101" => -- CPL F1 |
mnemonic_o <= MN_CPL_F; |
|
-- Mnemonic DA ---------------------------------------------------------- |
when "01010111" => -- DA D |
mnemonic_o <= MN_DA; |
|
-- Mnemonic DEC --------------------------------------------------------- |
when "11001000" | "11001001" | "11001010" | "11001011" | -- DEC Rr |
"11001100" | "11001101" | "11001110" | "11001111" | -- |
"00000111" => -- DEC A |
mnemonic_o <= MN_DEC; |
|
-- Mnemonic DIS_EN_I ---------------------------------------------------- |
when "00010101" | -- DIS I |
"00000101" => -- EN I |
mnemonic_o <= MN_DIS_EN_I; |
|
-- Mnemonic DIS_EN_TCNTI ------------------------------------------------ |
when "00110101" | -- DIS TCNTI |
"00100101" => -- EN TCNTI |
mnemonic_o <= MN_DIS_EN_TCNTI; |
|
-- Mnemonic DJNZ -------------------------------------------------------- |
when "11101000" | "11101001" | "11101010" | "11101011" | -- DJNZ Rr, addr |
"11101100" | "11101101" | "11101110" | "11101111" => -- |
mnemonic_o <= MN_DJNZ; |
multi_cycle_o <= '1'; |
|
-- Mnemonic ENT0_CLK ---------------------------------------------------- |
when "01110101" => -- ENT0 CLK |
mnemonic_o <= MN_ENT0_CLK; |
|
-- Mnemonic IN ---------------------------------------------------------- |
when "00001001" | "00001010" => -- IN A, Pp |
mnemonic_o <= MN_IN; |
multi_cycle_o <= '1'; |
|
-- Mnemonic INC --------------------------------------------------------- |
when "00010111" | -- INC A |
"00011000" | "00011001" | "00011010" | "00011011" | -- INC Rr |
"00011100" | "00011101" | "00011110" | "00011111" | -- |
"00010000" | "00010001" => -- INC @ Rr |
mnemonic_o <= MN_INC; |
|
-- Mnemonic INS --------------------------------------------------------- |
when "00001000" => -- INS A, BUS |
mnemonic_o <= MN_INS; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JBB --------------------------------------------------------- |
when "00010010" | "00110010" | "01010010" | "01110010" | -- JBb addr |
"10010010" | "10110010" | "11010010" | "11110010" => -- |
mnemonic_o <= MN_JBB; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JC ---------------------------------------------------------- |
when "11110110" | -- JC addr |
"11100110" => -- JNC addr |
mnemonic_o <= MN_JC; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JF ---------------------------------------------------------- |
when "10110110" | -- JF0 addr |
"01110110" => -- JF1 addr |
mnemonic_o <= MN_JF; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JMP --------------------------------------------------------- |
when "00000100" | "00100100" | "01000100" | "01100100" | -- JMP addr |
"10000100" | "10100100" | "11000100" | "11100100" => -- |
mnemonic_o <= MN_JMP; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JMPP -------------------------------------------------------- |
when "10110011" => -- JMPP @ A |
mnemonic_o <= MN_JMPP; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JNI --------------------------------------------------------- |
when "10000110" => -- JNI addr |
mnemonic_o <= MN_JNI; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JT ---------------------------------------------------------- |
when "00100110" | -- JNT0 addr |
"01000110" | -- JNT1 addr |
"00110110" | -- JT0 addr |
"01010110" => -- JT1 addr |
mnemonic_o <= MN_JT; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JTF --------------------------------------------------------- |
when "00010110" => -- JTF addr |
mnemonic_o <= MN_JTF; |
multi_cycle_o <= '1'; |
|
-- Mnemonic JZ ---------------------------------------------------------- |
when "10010110" | -- JNZ addr |
"11000110" => -- JZ addr |
mnemonic_o <= MN_JZ; |
multi_cycle_o <= '1'; |
|
-- Mnemonic MOV_A_DATA -------------------------------------------------- |
when "00100011" => -- MOV A, data |
mnemonic_o <= MN_MOV_A_DATA; |
multi_cycle_o <= '1'; |
|
-- Mnemonic MOV_A_PSW --------------------------------------------------- |
when "11000111" => -- MOV A, PSW |
mnemonic_o <= MN_MOV_A_PSW; |
|
-- Mnemonic MOV_A_RR ---------------------------------------------------- |
when "11111000" | "11111001" | "11111010" | "11111011" | -- MOV A, Rr |
"11111100" | "11111101" | "11111110" | "11111111" | -- |
"11110000" | "11110001" => -- MOV A, @ Rr |
mnemonic_o <= MN_MOV_A_RR; |
|
-- Mnemonic MOV_PSW_A --------------------------------------------------- |
when "11010111" => -- MOV PSW, A |
mnemonic_o <= MN_MOV_PSW_A; |
|
-- Mnemonic MOV_RR ------------------------------------------------------ |
when "10101000" | "10101001" | "10101010" | "10101011" | -- MOV Rr, A |
"10101100" | "10101101" | "10101110" | "10101111" | -- |
"10100000" | "10100001" => -- MOV @ Rr, A |
mnemonic_o <= MN_MOV_RR; |
|
-- Mnemonic MOV_RR_DATA ------------------------------------------------- |
when "10111000" | "10111001" | "10111010" | "10111011" | -- MOV Rr, data |
"10111100" | "10111101" | "10111110" | "10111111" | -- |
"10110000" | "10110001" => -- MOV @ Rr, data |
mnemonic_o <= MN_MOV_RR_DATA; |
multi_cycle_o <= '1'; |
|
-- Mnemonic MOV_T ------------------------------------------------------- |
when "01100010" | -- MOV T, A |
"01000010" => -- MOV A, T |
mnemonic_o <= MN_MOV_T; |
|
-- Mnemonic MOVD_A_PP --------------------------------------------------- |
when "00001100" | "00001101" | "00001110" | "00001111" => -- MOVD A, Pp |
mnemonic_o <= MN_MOVD_A_PP; |
multi_cycle_o <= '1'; |
|
-- Mnemonic MOVP -------------------------------------------------------- |
when "10100011" | -- MOVP A, @ A |
"11100011" => -- MOVP3 A, @ A |
mnemonic_o <= MN_MOVP; |
multi_cycle_o <= '1'; |
|
-- Mnemonic MOVX -------------------------------------------------------- |
when "10000000" | "10000001" | -- MOVX A, @ Rr |
"10010000" | "10010001" => -- MOVX @ Rr, A |
mnemonic_o <= MN_MOVX; |
multi_cycle_o <= '1'; |
|
-- Mnemonic NOP --------------------------------------------------------- |
when "00000000" => -- NOP |
mnemonic_o <= MN_NOP; |
|
-- Mnemonic ORL --------------------------------------------------------- |
when "01001000" | "01001001" | "01001010" | "01001011" | -- ORL A, Rr |
"01001100" | "01001101" | "01001110" | "01001111" | -- |
"01000000" | "01000001" => -- ORL A, @ Rr |
mnemonic_o <= MN_ORL; |
|
-- Mnemonic ORL_A_DATA -------------------------------------------------- |
when "01000011" => -- ORL A, data |
mnemonic_o <= MN_ORL_A_DATA; |
multi_cycle_o <= '1'; |
|
-- Mnemonic ORL_EXT ----------------------------------------------------- |
when "10001000" | -- ORL BUS, data |
"10001001" | "10001010" => -- ORL Pp, data |
mnemonic_o <= MN_ORL_EXT; |
multi_cycle_o <= '1'; |
|
-- Mnemonic OUTD_PP_A --------------------------------------------------- |
when "00111100" | "00111101" | "00111110" | "00111111" | -- MOVD Pp, A |
"10011100" | "10011101" | "10011110" | "10011111" | -- ANLD PP, A |
"10001100" | "10001101" | "10001110" | "10001111" => -- ORLD Pp, A |
mnemonic_o <= MN_OUTD_PP_A; |
multi_cycle_o <= '1'; |
|
-- Mnemonic OUTL_EXT ---------------------------------------------------- |
when "00111001" | "00111010" | -- OUTL Pp, A |
"00000010" => -- OUTL BUS, A |
mnemonic_o <= MN_OUTL_EXT; |
multi_cycle_o <= '1'; |
|
-- Mnemonic RET --------------------------------------------------------- |
when "10000011" | -- RET |
"10010011" => -- RETR |
mnemonic_o <= MN_RET; |
multi_cycle_o <= '1'; |
|
-- Mnemonic RL ---------------------------------------------------------- |
when "11100111" | -- RL A |
"11110111" => -- RLC A |
mnemonic_o <= MN_RL; |
|
-- Mnemonic RR ---------------------------------------------------------- |
when "01110111" | -- RR A |
"01100111" => -- RRC A |
mnemonic_o <= MN_RR; |
|
-- Mnemonic SEL_MB ------------------------------------------------------ |
when "11100101" | -- SEL MB0 |
"11110101" => -- SEL MB1 |
mnemonic_o <= MN_SEL_MB; |
|
-- Mnemonic SEL_RB ------------------------------------------------------ |
when "11000101" | -- SEL RB0 |
"11010101" => -- SEL RB1 |
mnemonic_o <= MN_SEL_RB; |
|
-- Mnemonic STOP_TCNT --------------------------------------------------- |
when "01100101" => -- STOP TCNT |
mnemonic_o <= MN_STOP_TCNT; |
|
-- Mnemonic START ------------------------------------------------------- |
when "01000101" | -- STRT CNT |
"01010101" => -- STRT T |
mnemonic_o <= MN_STRT; |
|
-- Mnemonic SWAP -------------------------------------------------------- |
when "01000111" => -- SWAP A |
mnemonic_o <= MN_SWAP; |
|
-- Mnemonic XCH --------------------------------------------------------- |
when "00101000" | "00101001" | "00101010" | "00101011" | -- XCH A, Rr |
"00101100" | "00101101" | "00101110" | "00101111" | -- |
"00100000" | "00100001" | -- XCH A, @ Rr |
"00110000" | "00110001" => -- XCHD A, @ Rr |
mnemonic_o <= MN_XCH; |
|
-- Mnemonic XRL --------------------------------------------------------- |
when "11011000" | "11011001" | "11011010" | "11011011" | -- XRL A, Rr |
"11011100" | "11011101" | "11011110" | "11011111" | -- |
"11010000" | "11010001" => -- XRL A, @ Rr |
mnemonic_o <= MN_XRL; |
|
-- Mnemonic XRL_A_DATA -------------------------------------------------- |
when "11010011" => -- XRL A, data |
mnemonic_o <= MN_XRL_A_DATA; |
multi_cycle_o <= '1'; |
|
when others => |
-- pragma translate_off |
assert now = 0 ns |
report "Unknown opcode." |
severity warning; |
-- pragma translate_on |
|
end case; |
|
end process opc_decode; |
-- |
----------------------------------------------------------------------------- |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- Revision 1.1 2004/03/23 21:31:52 arniml |
-- initial check-in |
-- |
------------------------------------------------------------------------------- |
/vhdl/clock_ctrl-c.vhd
0,0 → 1,14
------------------------------------------------------------------------------- |
-- |
-- $Id: clock_ctrl-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- The clock control unit. |
-- |
------------------------------------------------------------------------------- |
|
configuration clock_ctrl_rtl_c0 of clock_ctrl is |
|
for rtl |
end for; |
|
end clock_ctrl_rtl_c0; |
/vhdl/p1-c.vhd
0,0 → 1,17
------------------------------------------------------------------------------- |
-- |
-- The Port 1 unit. |
-- Implements the Port 1 logic. |
-- |
-- $Id: p1-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration p1_rtl_c0 of p1 is |
|
for rtl |
end for; |
|
end p1_rtl_c0; |
/vhdl/timer-c.vhd
0,0 → 1,16
------------------------------------------------------------------------------- |
-- |
-- The Timer/Counter unit. |
-- |
-- $Id: timer-c.vhd,v 1.1 2004-03-23 21:31:53 arniml Exp $ |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration timer_rtl_c0 of timer is |
|
for rtl |
end for; |
|
end timer_rtl_c0; |
/vhdl/p2-c.vhd
0,0 → 1,17
------------------------------------------------------------------------------- |
-- |
-- The Port 2 unit. |
-- Implements the Port 2 logic. |
-- |
-- $Id: p2-c.vhd,v 1.1 2004-03-23 21:31:53 arniml Exp $ |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration p2_rtl_c0 of p2 is |
|
for rtl |
end for; |
|
end p2_rtl_c0; |
/vhdl/dmem_ctrl_pack-p.vhd
0,0 → 1,29
------------------------------------------------------------------------------- |
-- |
-- $Id: dmem_ctrl_pack-p.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
package dmem_ctrl_pack is |
|
----------------------------------------------------------------------------- |
-- Address Type Identifier |
----------------------------------------------------------------------------- |
type dmem_addr_ident_t is (DM_PLAIN, |
DM_REG, |
DM_STACK, |
DM_STACK_HIGH); |
|
end dmem_ctrl_pack; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- |
------------------------------------------------------------------------------- |
/vhdl/pmem_ctrl-c.vhd
0,0 → 1,17
------------------------------------------------------------------------------- |
-- |
-- The Program Memory control unit. |
-- All operations related to the Program Memory are managed here. |
-- |
-- $Id: pmem_ctrl-c.vhd,v 1.1 2004-03-23 21:31:53 arniml Exp $ |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration pmem_ctrl_rtl_c0 of pmem_ctrl is |
|
for rtl |
end for; |
|
end pmem_ctrl_rtl_c0; |
/vhdl/bus_mux-c.vhd
0,0 → 1,19
------------------------------------------------------------------------------- |
-- |
-- The T48 Bus Connector. |
-- Multiplexes all drivers of the T48 bus. |
-- |
-- $Id: bus_mux-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration bus_mux_rtl_c0 of bus_mux is |
|
for rtl |
end for; |
|
end bus_mux_rtl_c0; |
/vhdl/opc_table-c.vhd
0,0 → 1,18
------------------------------------------------------------------------------- |
-- |
-- The Opcode Decoder Table. |
-- Decodes the given opcode to instruction mnemonics. |
-- Also derives the multicycle information. |
-- |
-- $Id: opc_table-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration opc_table_rtl_c0 of opc_table is |
|
for rtl |
end for; |
|
end opc_table_rtl_c0; |
/vhdl/pmem_ctrl_pack-p.vhd
0,0 → 1,28
------------------------------------------------------------------------------- |
-- |
-- $Id: pmem_ctrl_pack-p.vhd,v 1.1 2004-03-23 21:31:53 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
package pmem_ctrl_pack is |
|
----------------------------------------------------------------------------- |
-- Address Type Identifier |
----------------------------------------------------------------------------- |
type pmem_addr_ident_t is (PM_PC, |
PM_PAGE, |
PM_PAGE3); |
|
end pmem_ctrl_pack; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- |
------------------------------------------------------------------------------- |
/vhdl/db_bus-c.vhd
0,0 → 1,19
------------------------------------------------------------------------------- |
-- |
-- The BUS unit. |
-- Implements the BUS port logic. |
-- |
-- $Id: db_bus-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration db_bus_rtl_c0 of db_bus is |
|
for rtl |
end for; |
|
end db_bus_rtl_c0; |
/vhdl/bus_mux.vhd
0,0 → 1,108
------------------------------------------------------------------------------- |
-- |
-- The T48 Bus Connector. |
-- Multiplexes all drivers of the T48 bus. |
-- |
-- $Id: bus_mux.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
|
entity bus_mux is |
|
port ( |
alu_data_i : in word_t; |
bus_data_i : in word_t; |
dec_data_i : in word_t; |
dm_data_i : in word_t; |
pm_data_i : in word_t; |
p1_data_i : in word_t; |
p2_data_i : in word_t; |
psw_data_i : in word_t; |
tim_data_i : in word_t; |
data_o : out word_t |
); |
|
end bus_mux; |
|
|
use work.t48_pack.bus_idle_level_c; |
|
architecture rtl of bus_mux is |
|
begin |
|
or_tree: if bus_idle_level_c = '0' generate |
data_o <= alu_data_i or |
bus_data_i or |
dec_data_i or |
dm_data_i or |
pm_data_i or |
p1_data_i or |
p2_data_i or |
psw_data_i or |
tim_data_i; |
end generate; |
|
and_tree: if bus_idle_level_c = '1' generate |
data_o <= alu_data_i and |
bus_data_i and |
dec_data_i and |
dm_data_i and |
pm_data_i and |
p1_data_i and |
p2_data_i and |
psw_data_i and |
tim_data_i; |
end generate; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- |
------------------------------------------------------------------------------- |
/vhdl/decoder-c.vhd
0,0 → 1,28
------------------------------------------------------------------------------- |
-- |
-- The Decoder unit. |
-- It decodes the instruction opcodes and executes them. |
-- |
-- $Id: decoder-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration decoder_rtl_c0 of decoder is |
|
for rtl |
|
for opc_decoder_b: opc_decoder |
use configuration work.opc_decoder_rtl_c0; |
end for; |
|
for int_b: int |
use configuration work.int_rtl_c0; |
end for; |
|
end for; |
|
end decoder_rtl_c0; |
/vhdl/opc_decoder-c.vhd
0,0 → 1,23
------------------------------------------------------------------------------- |
-- |
-- The Opcode Decoder. |
-- Derives instruction mnemonics and multicycle information |
-- using the OPC table unit. |
-- |
-- $Id: opc_decoder-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration opc_decoder_rtl_c0 of opc_decoder is |
|
for rtl |
|
for opc_table_b: opc_table |
use configuration work.opc_table_rtl_c0; |
end for; |
|
end for; |
|
end opc_decoder_rtl_c0; |
/vhdl/psw-c.vhd
0,0 → 1,17
------------------------------------------------------------------------------- |
-- |
-- The Program Status Word (PSW). |
-- Implements the PSW with its special bits. |
-- |
-- $Id: psw-c.vhd,v 1.1 2004-03-23 21:31:53 arniml Exp $ |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration psw_rtl_c0 of psw is |
|
for rtl |
end for; |
|
end psw_rtl_c0; |
/vhdl/alu-c.vhd
0,0 → 1,19
------------------------------------------------------------------------------- |
-- |
-- The Arithmetic Logic Unit (ALU). |
-- It contains the ALU core plus the Accumulator and the Temp Reg. |
-- |
-- $Id: alu-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration alu_rtl_c0 of alu is |
|
for rtl |
end for; |
|
end alu_rtl_c0; |
/vhdl/opc_decoder.vhd
0,0 → 1,172
------------------------------------------------------------------------------- |
-- |
-- The Opcode Decoder. |
-- Derives instruction mnemonics and multicycle information |
-- using the OPC table unit. |
-- |
-- $Id: opc_decoder.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.word_t; |
use work.decoder_pack.mnemonic_t; |
|
entity opc_decoder is |
|
generic ( |
-- store mnemonic in flip-flops (registered-out) |
register_mnemonic_g : integer := 1 |
); |
|
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- T48 Bus Interface ------------------------------------------------------ |
data_i : in word_t; |
read_bus_i : in boolean; |
-- Decoder Interface ------------------------------------------------------ |
inj_int_i : in boolean; |
opcode_o : out word_t; |
mnemonic_o : out mnemonic_t; |
multi_cycle_o : out boolean |
); |
|
end opc_decoder; |
|
|
use work.t48_pack.clk_active_c; |
use work.t48_pack.res_active_c; |
use work.t48_pack.to_boolean; |
--use work.decoder_pack.MN_NOP; |
use work.decoder_pack.all; |
|
use work.t48_comp_pack.opc_table; |
|
architecture rtl of opc_decoder is |
|
-- the opcode register |
signal opcode_q : word_t; |
|
-- the mnemonic |
signal mnemonic_s, |
mnemonic_q : mnemonic_t; |
|
signal multi_cycle_s : std_logic; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Verify the generics |
----------------------------------------------------------------------------- |
|
-- pragma translate_off |
|
-- Register Mnemonic -------------------------------------------------------- |
assert (register_mnemonic_g = 1) or (register_mnemonic_g = 0) |
report "register_mnemonic_g must be either 1 or 0!" |
severity failure; |
|
-- pragma translate_on |
|
|
----------------------------------------------------------------------------- |
-- Opcode Decoder Table |
----------------------------------------------------------------------------- |
opc_table_b : opc_table |
port map ( |
opcode_i => opcode_q, |
multi_cycle_o => multi_cycle_s, |
mnemonic_o => mnemonic_s |
); |
|
|
----------------------------------------------------------------------------- |
-- Process regs |
-- |
-- Purpose: |
-- Implements the opcode and mnemonic registers. |
-- |
regs: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
opcode_q <= (others => '0'); -- NOP |
mnemonic_q <= MN_NOP; |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
if read_bus_i then |
opcode_q <= data_i; |
elsif inj_int_i then |
opcode_q <= "00010100"; |
else |
mnemonic_q <= mnemonic_s; |
end if; |
|
end if; |
|
end if; |
|
end process regs; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
opcode_o <= opcode_q; |
multi_cycle_o <= to_boolean(multi_cycle_s); |
mnemonic_o <= mnemonic_q |
when register_mnemonic_g = 1 else |
mnemonic_s; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- |
------------------------------------------------------------------------------- |
/vhdl/t48_core-c.vhd
0,0 → 1,71
------------------------------------------------------------------------------- |
-- |
-- T48 Microcontroller Core |
-- |
-- $Id: t48_core-c.vhd,v 1.1 2004-03-23 21:31:53 arniml Exp $ |
-- |
------------------------------------------------------------------------------- |
|
configuration t48_core_struct_c0 of t48_core is |
|
for struct |
|
for alu_b : alu |
use configuration work.alu_rtl_c0; |
end for; |
|
for bus_mux_b : bus_mux |
use configuration work.bus_mux_rtl_c0; |
end for; |
|
for clock_ctrl_b : clock_ctrl |
use configuration work.clock_ctrl_rtl_c0; |
end for; |
|
for cond_branch_b : cond_branch |
use configuration work.cond_branch_rtl_c0; |
end for; |
|
for use_db_bus |
for db_bus_b : db_bus |
use configuration work.db_bus_rtl_c0; |
end for; |
end for; |
|
for decoder_b : decoder |
use configuration work.decoder_rtl_c0; |
end for; |
|
for dmem_ctrl_b : dmem_ctrl |
use configuration work.dmem_ctrl_rtl_c0; |
end for; |
|
for use_timer |
for timer_b : timer |
use configuration work.timer_rtl_c0; |
end for; |
end for; |
|
for use_p1 |
for p1_b : p1 |
use configuration work.p1_rtl_c0; |
end for; |
end for; |
|
for use_p2 |
for p2_b : p2 |
use configuration work.p2_rtl_c0; |
end for; |
end for; |
|
for pmem_ctrl_b : pmem_ctrl |
use configuration work.pmem_ctrl_rtl_c0; |
end for; |
|
for psw_b : psw |
use configuration work.psw_rtl_c0; |
end for; |
|
end for; |
|
end t48_core_struct_c0; |
/vhdl/int-c.vhd
0,0 → 1,17
------------------------------------------------------------------------------- |
-- |
-- The Interrupt Controller. |
-- It collects the interrupt sources and notifies the decoder. |
-- |
-- $Id: int-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration int_rtl_c0 of int is |
|
for rtl |
end for; |
|
end int_rtl_c0; |
/vhdl/t48_pack-p.vhd
0,0 → 1,82
------------------------------------------------------------------------------- |
-- |
-- $Id: t48_pack-p.vhd,v 1.1 2004-03-23 21:31:53 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
package t48_pack is |
|
----------------------------------------------------------------------------- |
-- Global constants |
----------------------------------------------------------------------------- |
|
-- clock active level |
constant clk_active_c : std_logic := '1'; |
-- reset active level |
constant res_active_c : std_logic := '0'; |
-- idle level on internal data bus |
constant bus_idle_level_c : std_logic := '1'; |
|
-- global data word width |
constant word_width_c : natural := 8; |
|
-- data memory address width |
constant dmem_addr_width_c : natural := 8; |
-- program memory address width |
constant pmem_addr_width_c : natural := 12; |
|
|
----------------------------------------------------------------------------- |
-- Global data types |
----------------------------------------------------------------------------- |
|
-- the global data word width type |
subtype word_t is std_logic_vector(word_width_c-1 downto 0); |
subtype nibble_t is std_logic_vector(word_width_c/2-1 downto 0); |
-- the global data memory address type |
subtype dmem_addr_t is std_logic_vector(dmem_addr_width_c-1 downto 0); |
-- the global program memory address type |
subtype pmem_addr_t is std_logic_vector(pmem_addr_width_c-1 downto 0); |
subtype page_t is std_logic_vector(pmem_addr_width_c-1 downto word_width_c); |
|
-- the machine states |
type mstate_t is (MSTATE1, MSTATE2, MSTATE3, MSTATE4, MSTATE5); |
|
|
----------------------------------------------------------------------------- |
-- Global functions |
----------------------------------------------------------------------------- |
|
function to_stdLogic(input: boolean) return std_logic; |
function to_boolean(input: std_logic) return boolean; |
|
end t48_pack; |
|
package body t48_pack is |
|
function to_stdLogic(input: boolean) return std_logic is |
begin |
if input then |
return '1'; |
else |
return '0'; |
end if; |
end to_stdLogic; |
|
function to_boolean(input: std_logic) return boolean is |
begin |
if input = '1' then |
return true; |
else |
return false; |
end if; |
end to_boolean; |
|
end t48_pack; |
/vhdl/cond_branch-c.vhd
0,0 → 1,19
------------------------------------------------------------------------------- |
-- |
-- The Conditional Branch Logic unit. |
-- Decisions whether to take a jump or not are made here. |
-- |
-- $Id: cond_branch-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration cond_branch_rtl_c0 of cond_branch is |
|
for rtl |
end for; |
|
end cond_branch_rtl_c0; |
/vhdl/dmem_ctrl-c.vhd
0,0 → 1,19
------------------------------------------------------------------------------- |
-- |
-- The Data Memory control unit. |
-- All accesses to the Data Memory are managed here. |
-- |
-- $Id: dmem_ctrl-c.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration dmem_ctrl_rtl_c0 of dmem_ctrl is |
|
for rtl |
end for; |
|
end dmem_ctrl_rtl_c0; |
/vhdl/int.vhd
0,0 → 1,234
------------------------------------------------------------------------------- |
-- |
-- The Interrupt Controller. |
-- It collects the interrupt sources and notifies the decoder. |
-- |
-- $Id: int.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- All rights reserved |
-- |
-- Redistribution and use in source and synthezised forms, with or without |
-- modification, are permitted provided that the following conditions are met: |
-- |
-- Redistributions of source code must retain the above copyright notice, |
-- this list of conditions and the following disclaimer. |
-- |
-- Redistributions in synthesized form must reproduce the above copyright |
-- notice, this list of conditions and the following disclaimer in the |
-- documentation and/or other materials provided with the distribution. |
-- |
-- Neither the name of the author nor the names of other contributors may |
-- be used to endorse or promote products derived from this software without |
-- specific prior written permission. |
-- |
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE |
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
-- POSSIBILITY OF SUCH DAMAGE. |
-- |
-- Please report bugs to the author, but before you do so, please |
-- make sure that this is not a derivative work and that |
-- you have the latest version of this file. |
-- |
-- The latest version of this file can be found at: |
-- http://www.opencores.org/cvsweb.shtml/t48/ |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
use work.t48_pack.mstate_t; |
|
entity int is |
|
port ( |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
clk_mstate_i : in mstate_t; |
jtf_executed_i : in boolean; |
tim_overflow_i : in boolean; |
tf_o : out std_logic; |
en_tcnti_i : in boolean; |
dis_tcnti_i : in boolean; |
int_n_i : in std_logic; |
ale_i : in boolean; |
last_cycle_i : in boolean; |
en_i_i : in boolean; |
dis_i_i : in boolean; |
ext_int_o : out boolean; |
tim_int_o : out boolean; |
retr_executed_i : in boolean; |
int_executed_i : in boolean; |
int_pending_o : out boolean |
); |
|
end int; |
|
|
use work.t48_pack.all; |
|
architecture rtl of int is |
|
constant tim_int_c : std_logic := '0'; |
constant ext_int_c : std_logic := '1'; |
|
type int_state_t is (IDLE, PENDING, INT); |
|
signal int_state_s, |
int_state_q : int_state_t; |
|
signal timer_flag_q : boolean; |
signal timer_overflow_q : boolean; |
signal timer_int_enable_q : boolean; |
signal int_q : boolean; |
signal int_enable_q : boolean; |
signal ale_q : boolean; |
signal int_type_q : std_logic; |
signal int_in_progress_q : boolean; |
|
begin |
|
----------------------------------------------------------------------------- |
-- Process nstate |
-- |
-- Purpose: |
-- Determines the next state of the Interrupt controller FSM. |
-- |
nstate: process (int_state_q, |
int_type_q, |
int_in_progress_q, |
int_executed_i, |
retr_executed_i, |
clk_mstate_i, |
last_cycle_i) |
begin |
int_state_s <= int_state_q; |
|
case int_state_q is |
when IDLE => |
if int_in_progress_q and |
last_cycle_i and clk_mstate_i = MSTATE5 then |
int_state_s <= PENDING; |
end if; |
|
when PENDING => |
if int_executed_i then |
int_state_s <= INT; |
end if; |
|
when INT => |
if retr_executed_i then |
int_state_s <= IDLE; |
end if; |
|
when others => |
int_state_s <= IDLE; |
|
end case; |
|
end process nstate; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Process regs |
-- |
-- Purpose: |
-- Implement the various registers. |
-- |
regs: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
timer_flag_q <= false; |
timer_overflow_q <= false; |
timer_int_enable_q <= false; |
int_q <= false; |
int_enable_q <= false; |
ale_q <= false; |
int_type_q <= '0'; |
int_state_q <= IDLE; |
int_in_progress_q <= false; |
|
elsif clk_i'event and clk_i = clk_active_c then |
if en_clk_i then |
|
ale_q <= ale_i; |
|
int_state_q <= int_state_s; |
|
if jtf_executed_i then |
timer_flag_q <= false; |
elsif tim_overflow_i then |
timer_flag_q <= true; |
end if; |
|
if (int_type_q = tim_int_c and int_executed_i) or |
not timer_int_enable_q then |
timer_overflow_q <= false; |
elsif tim_overflow_i then |
timer_overflow_q <= true; |
end if; |
|
if dis_tcnti_i then |
timer_int_enable_q <= false; |
elsif en_tcnti_i then |
timer_int_enable_q <= true; |
end if; |
|
if last_cycle_i and |
ale_q and not ale_i then |
int_q <= not to_boolean(int_n_i); |
end if; |
|
if dis_i_i then |
int_enable_q <= false; |
elsif en_i_i then |
int_enable_q <= true; |
end if; |
|
if retr_executed_i then |
int_in_progress_q <= false; |
elsif (int_q and int_enable_q) or |
timer_overflow_q then |
int_in_progress_q <= true; |
if not int_in_progress_q then |
int_type_q <= to_stdLogic(int_q and int_enable_q); |
end if; |
end if; |
|
end if; |
|
end if; |
|
end process regs; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
tf_o <= to_stdLogic(timer_flag_q); |
ext_int_o <= int_type_q = ext_int_c; |
tim_int_o <= int_type_q = tim_int_c; |
int_pending_o <= int_state_q = PENDING; |
|
end rtl; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- |
------------------------------------------------------------------------------- |
/vhdl/cond_branch_pack-p.vhd
0,0 → 1,36
------------------------------------------------------------------------------- |
-- |
-- $Id: cond_branch_pack-p.vhd,v 1.1 2004-03-23 21:31:52 arniml Exp $ |
-- |
-- Copyright (c) 2004, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
package cond_branch_pack is |
|
----------------------------------------------------------------------------- |
-- The branch conditions. |
----------------------------------------------------------------------------- |
type branch_conditions_t is (COND_ON_BIT, COND_Z, |
COND_C, |
COND_F0, COND_F1, |
COND_INT, |
COND_T0, COND_T1, |
COND_TF); |
|
subtype comp_value_t is std_logic_vector(2 downto 0); |
|
end cond_branch_pack; |
|
|
------------------------------------------------------------------------------- |
-- File History: |
-- |
-- $Log: not supported by cvs2svn $ |
-- |
------------------------------------------------------------------------------- |