URL
https://opencores.org/ocsvn/t48/t48/trunk
Subversion Repositories t48
Compare Revisions
- This comparison shows the changes necessary to convert path
/t48
- from Rev 302 to Rev 303
- ↔ Reverse comparison
Rev 302 → Rev 303
/trunk/bench/vhdl/tb_t8041a-c.vhd
0,0 → 1,21
------------------------------------------------------------------------------- |
-- |
-- The testbench for t8041a. |
-- |
-- Copyright (c) 2004-2022, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration tb_t8041a_behav_c0 of tb_t8041a is |
|
for behav |
|
for t8041a_b : t8041a |
use configuration work.t8041a_struct_c0; |
end for; |
|
end for; |
|
end tb_t8041a_behav_c0; |
/trunk/bench/vhdl/tb_t8041a.vhd
0,0 → 1,174
------------------------------------------------------------------------------- |
-- |
-- The testbench for t8041a. |
-- |
-- Copyright (c) 2004-2022, 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 tb_t8041a is |
|
end tb_t8041a; |
|
|
use work.t48_system_comp_pack.t8041a; |
|
use work.t48_tb_pack.all; |
|
architecture behav of tb_t8041a is |
|
-- clock period, 11 MHz |
constant period_c : time := 90 ns; |
|
signal xtal_s : std_logic; |
signal res_n_s : std_logic; |
signal prog_n_s : std_logic; |
|
signal p1_b : std_logic_vector( 7 downto 0); |
signal p2_b : std_logic_vector( 7 downto 0); |
|
signal db_b : std_logic_vector( 7 downto 0); |
signal cs_n_s : std_logic; |
signal rd_n_s : std_logic; |
signal wr_n_s : std_logic; |
signal a0_s : std_logic; |
|
signal zero_s : std_logic; |
signal one_s : std_logic; |
|
begin |
|
-- TODO |
cs_n_s <= '1'; |
rd_n_s <= '1'; |
wr_n_s <= '1'; |
a0_s <= '0'; |
|
zero_s <= '0'; |
one_s <= '1'; |
|
p2_b <= (others => 'H'); |
p1_b <= (others => 'H'); |
|
t8041a_b : t8041a |
port map ( |
xtal_i => xtal_s, |
reset_n_i => res_n_s, |
cs_n_i => cs_n_s, |
rd_n_i => rd_n_s, |
a0_i => a0_s, |
wr_n_i => wr_n_s, |
t0_i => p1_b(0), |
db_b => db_b, |
t1_i => p1_b(1), |
p2_b => p2_b, |
p1_b => p1_b, |
prog_n_o => prog_n_s |
); |
|
|
----------------------------------------------------------------------------- |
-- The clock generator |
-- |
clk_gen: process |
begin |
xtal_s <= '0'; |
wait for period_c/2; |
xtal_s <= '1'; |
wait for period_c/2; |
end process clk_gen; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- The reset generator |
-- |
res_gen: process |
begin |
res_n_s <= '0'; |
wait for 5 * period_c; |
res_n_s <= '1'; |
wait; |
end process res_gen; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- End of simulation detection |
-- |
eos: process |
begin |
|
outer: loop |
wait on tb_accu_s; |
if tb_accu_s = "10101010" then |
wait on tb_accu_s; |
if tb_accu_s = "01010101" then |
wait on tb_accu_s; |
if tb_accu_s = "00000001" then |
-- wait for instruction strobe of this move |
wait until tb_istrobe_s'event and tb_istrobe_s = '1'; |
-- wait for next strobe |
wait until tb_istrobe_s'event and tb_istrobe_s = '1'; |
assert false |
report "Simulation Result: PASS." |
severity note; |
else |
assert false |
report "Simulation Result: FAIL." |
severity note; |
end if; |
|
assert false |
report "End of simulation reached." |
severity failure; |
|
end if; |
end if; |
end loop; |
|
end process eos; |
-- |
----------------------------------------------------------------------------- |
|
end behav; |
/trunk/rtl/vhdl/cond_branch.vhd
70,6 → 70,8
f1_i : in std_logic; |
tf_i : in std_logic; |
carry_i : in std_logic; |
ibf_i : in std_logic := '0'; -- UPI41 |
obf_i : in std_logic := '0'; -- UPI41 |
comp_value_i : in comp_value_t |
); |
|
103,6 → 105,7
f0_i, f1_i, |
tf_i, |
carry_i, |
ibf_i, obf_i, |
comp_value_i) |
variable or_v : std_logic; |
begin |
152,6 → 155,14
when COND_TF => |
take_branch_s <= tf_i = '1'; |
|
-- Branch On: IBF not set - UPI41 --------------------------------------- |
when COND_NIBF => |
take_branch_s <= ibf_i = '0'; |
|
-- Branch On: OBF set - UPI41 ------------------------------------------- |
when COND_OBF => |
take_branch_s <= obf_i = '1'; |
|
when others => |
-- pragma translate_off |
assert false |
/trunk/rtl/vhdl/cond_branch_pack-p.vhd
21,7 → 21,10
COND_F0, COND_F1, |
COND_INT, |
COND_T0, COND_T1, |
COND_TF); |
COND_TF, |
-- UPI41 |
COND_NIBF, |
COND_OBF); |
|
subtype comp_value_t is std_logic_vector(2 downto 0); |
|
/trunk/rtl/vhdl/decoder.vhd
58,7 → 58,9
|
generic ( |
-- store mnemonic in flip-flops (registered-out) |
register_mnemonic_g : integer := 1 |
register_mnemonic_g : integer := 1; |
is_upi_g : integer := 0; |
is_upi_type_a_g : integer := 0 |
); |
|
port ( |
81,6 → 83,12
alu_read_alu_o : out boolean; |
bus_write_bus_o : out boolean; |
bus_read_bus_o : out boolean; |
bus_set_f1_i : in boolean := false; -- UPI41 |
bus_clear_f1_i : in boolean := false; -- UPI41 |
bus_ibf_int_o : out boolean; -- UPI41 |
bus_en_dma_o : out boolean; -- UPI41A |
bus_en_flags_o : out boolean; -- UPI41A |
bus_write_sts_o : out boolean; -- UPI41A |
dm_write_dmem_addr_o : out boolean; |
dm_write_dmem_o : out boolean; |
dm_read_dmem_o : out boolean; |
254,6 → 262,15
report "register_mnemonic_g must be either 1 or 0!" |
severity failure; |
|
-- UPI41 configuration ------------------------------------------------------ |
assert (is_upi_g = 0) or (is_upi_g = 1) |
report "is_upi_g must be either 1 or 0!" |
severity failure; |
-- |
assert (is_upi_type_a_g = 0) or (is_upi_type_a_g = 1) |
report "is_upi_type_a_g must be either 1 or 0!" |
severity failure; |
|
-- pragma translate_on |
|
|
260,7 → 277,15
----------------------------------------------------------------------------- |
-- Opcode Decoder |
-- |
mnemonic_rec_s <= decode_opcode_f(opcode => opc_opcode_q); |
gen_mcs48: if is_upi_g = 0 generate |
mnemonic_rec_s <= decode_mcs48_opcode_f (opcode => opc_opcode_q); |
end generate; |
gen_upi41: if is_upi_g = 1 and is_upi_type_a_g = 0 generate |
mnemonic_rec_s <= decode_upi41_opcode_f (opcode => opc_opcode_q); |
end generate; |
gen_upi41a: if is_upi_g = 1 and is_upi_type_a_g = 1 generate |
mnemonic_rec_s <= decode_upi41a_opcode_f(opcode => opc_opcode_q); |
end generate; |
-- |
----------------------------------------------------------------------------- |
|
525,6 → 550,10
alu_read_alu_o <= false; |
bus_write_bus_o <= false; |
bus_bidir_bus_o <= false; |
bus_ibf_int_o <= false; -- UPI41 |
bus_en_dma_o <= false; -- UPI41A |
bus_en_flags_o <= false; -- UPI41A |
bus_write_sts_o <= false; -- UPI41A |
dm_write_dmem_addr_o <= false; |
dm_write_dmem_s <= false; |
dm_read_dmem_o <= false; |
815,6 → 844,8
data_s(1 downto 0) <= "11"; |
if tim_int_s then |
data_s(2) <= '1'; |
else |
bus_ibf_int_o <= true; -- UPI41 |
end if; |
read_dec_s <= true; |
end if; |
1022,6 → 1053,16
|
end if; |
|
-- Mnemonic EN_DMA_FLAGS - UPI41A --------------------------------------- |
when MN_EN_DMA_FLAGS => |
if clk_mstate_i = MSTATE4 then |
if opc_opcode_q(4) = '0' then |
bus_en_dma_o <= true; |
else |
bus_en_flags_o <= true; |
end if; |
end if; |
|
-- Mnemonic ENT0_CLK ---------------------------------------------------- |
when MN_ENT0_CLK => |
if clk_mstate_i = MSTATE3 then |
1041,6 → 1082,15
end if; |
end if; |
|
-- Mnemonic IN_DBB - UPI41 ---------------------------------------------- |
when MN_IN_DBB => |
-- read BUS and store in Accumulator |
if clk_mstate_i = MSTATE2 then |
alu_write_accu_o <= true; |
|
add_read_bus_s <= true; |
end if; |
|
-- Mnemonic INS --------------------------------------------------------- |
when MN_INS => |
clk_assert_rd_o <= true; |
1222,6 → 1272,46
|
end if; |
|
-- Mnemonic JNIBF - UPI41 ----------------------------------------------- |
when MN_JNIBF => |
assert_psen_s <= true; |
cnd_branch_cond_o <= COND_NIBF; |
|
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 |
if clk_mstate_i = MSTATE1 and cnd_take_branch_i then |
cond_jump_c2_m1_f; |
end if; |
|
end if; |
|
-- Mnemonic JOBF - UPI41 ------------------------------------------------ |
when MN_JOBF => |
assert_psen_s <= true; |
cnd_branch_cond_o <= COND_OBF; |
|
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 |
if clk_mstate_i = MSTATE1 and cnd_take_branch_i then |
cond_jump_c2_m1_f; |
end if; |
|
end if; |
|
-- Mnemonic JT ---------------------------------------------------------- |
when MN_JT => |
assert_psen_s <= true; |
1374,6 → 1464,15
dm_write_dmem_s <= true; |
end if; |
|
-- Mnemonic MOV_STS - UPI41A -------------------------------------------- |
when MN_MOV_STS => |
-- read Accumulator and store in STS register |
if clk_mstate_i = MSTATE4 then |
alu_read_alu_o <= true; |
|
bus_write_sts_o <= true; |
end if; |
|
-- Mnemonic MOV_T ------------------------------------------------------- |
when MN_MOV_T => |
if clk_mstate_i = MSTATE3 then |
1661,6 → 1760,15
|
end if; |
|
-- Mnemonic OUT_DBB - UPI41 --------------------------------------------- |
when MN_OUT_DBB => |
-- read Accumulator and store in BUS output register |
if clk_mstate_i = MSTATE4 then |
alu_read_alu_o <= true; |
|
bus_write_bus_o <= true; |
end if; |
|
-- Mnemonic OUTL_EXT ---------------------------------------------------- |
when MN_OUTL_EXT => |
if opc_opcode_q(4) = '0' then |
1921,6 → 2029,13
-- pragma translate_on |
|
elsif clk_i'event and clk_i = clk_active_c then |
-- UPI41 master access |
if bus_set_f1_i then |
f1_q <= '1'; |
elsif bus_clear_f1_i then |
f1_q <= '0'; |
end if; |
|
if en_clk_i then |
|
-- branch taken flag |
/trunk/rtl/vhdl/decoder_pack-p.vhd
18,7 → 18,8
----------------------------------------------------------------------------- |
-- The Mnemonics. |
----------------------------------------------------------------------------- |
type mnemonic_t is (MN_ADD, |
type mnemonic_t is (MN_INVALID, |
MN_ADD, |
MN_ADD_A_DATA, |
MN_ANL, |
MN_ANL_A_DATA, |
74,7 → 75,16
MN_SWAP, |
MN_XCH, |
MN_XRL, |
MN_XRL_A_DATA); |
MN_XRL_A_DATA, |
-- UPI41 opcodes |
MN_IN_DBB, |
MN_OUT_DBB, |
MN_JNIBF, |
MN_JOBF, |
-- UPI41A opcodes |
MN_EN_DMA_FLAGS, |
MN_MOV_STS |
); |
|
type mnemonic_rec_t is |
record |
82,15 → 92,24
multi_cycle : boolean; |
end record; |
|
function decode_opcode_f(opcode : in word_t) return |
function decode_mcs48_opcode_f(opcode : in word_t) return |
mnemonic_rec_t; |
|
function decode_upi41_opcode_f(opcode : in word_t) return |
mnemonic_rec_t; |
|
function decode_upi41a_opcode_f(opcode : in word_t) return |
mnemonic_rec_t; |
|
end t48_decoder_pack; |
|
|
package body t48_decoder_pack is |
|
function decode_opcode_f(opcode : in word_t) return |
----------------------------------------------------------------------------- |
-- Common opcodes of MCS-48 and UPI-41/UPI-41A |
-- |
function decode_common_opcode_f(opcode : in word_t) return |
mnemonic_rec_t is |
variable mnemonic_v : mnemonic_t; |
variable multi_cycle_v : boolean; |
97,7 → 116,6
variable result_v : mnemonic_rec_t; |
begin |
-- default assignment |
mnemonic_v := MN_NOP; |
multi_cycle_v := false; |
|
case opcode is |
127,12 → 145,6
mnemonic_v := MN_ANL_A_DATA; |
multi_cycle_v := true; |
|
-- Mnemonic ANL_EXT ----------------------------------------------------- |
when "10011000" | -- ANL BUS, data |
"10011001" | "10011010" => -- ANL PP, data |
mnemonic_v := MN_ANL_EXT; |
multi_cycle_v := true; |
|
-- Mnemonic CALL -------------------------------------------------------- |
when "00010100" | "00110100" | "01010100" | "01110100" | -- CALL addr |
"10010100" | "10110100" | "11010100" | "11110100" => -- |
191,10 → 203,6
mnemonic_v := MN_DJNZ; |
multi_cycle_v := true; |
|
-- Mnemonic ENT0_CLK ---------------------------------------------------- |
when "01110101" => -- ENT0 CLK |
mnemonic_v := MN_ENT0_CLK; |
|
-- Mnemonic IN ---------------------------------------------------------- |
when "00001001" | "00001010" => -- IN A, Pp |
mnemonic_v := MN_IN; |
207,11 → 215,6
"00010000" | "00010001" => -- INC @ Rr |
mnemonic_v := MN_INC; |
|
-- Mnemonic INS --------------------------------------------------------- |
when "00001000" => -- INS A, BUS |
mnemonic_v := MN_INS; |
multi_cycle_v := true; |
|
-- Mnemonic JBB --------------------------------------------------------- |
when "00010010" | "00110010" | "01010010" | "01110010" | -- JBb addr |
"10010010" | "10110010" | "11010010" | "11110010" => -- |
241,11 → 244,6
mnemonic_v := MN_JMPP; |
multi_cycle_v := true; |
|
-- Mnemonic JNI --------------------------------------------------------- |
when "10000110" => -- JNI addr |
mnemonic_v := MN_JNI; |
multi_cycle_v := true; |
|
-- Mnemonic JT ---------------------------------------------------------- |
when "00100110" | -- JNT0 addr |
"01000110" | -- JNT1 addr |
313,12 → 311,6
mnemonic_v := MN_MOVP; |
multi_cycle_v := true; |
|
-- Mnemonic MOVX -------------------------------------------------------- |
when "10000000" | "10000001" | -- MOVX A, @ Rr |
"10010000" | "10010001" => -- MOVX @ Rr, A |
mnemonic_v := MN_MOVX; |
multi_cycle_v := true; |
|
-- Mnemonic NOP --------------------------------------------------------- |
when "00000000" => -- NOP |
mnemonic_v := MN_NOP; |
334,12 → 326,6
mnemonic_v := MN_ORL_A_DATA; |
multi_cycle_v := true; |
|
-- Mnemonic ORL_EXT ----------------------------------------------------- |
when "10001000" | -- ORL BUS, data |
"10001001" | "10001010" => -- ORL Pp, data |
mnemonic_v := MN_ORL_EXT; |
multi_cycle_v := true; |
|
-- Mnemonic OUTD_PP_A --------------------------------------------------- |
when "00111100" | "00111101" | "00111110" | "00111111" | -- MOVD Pp, A |
"10011100" | "10011101" | "10011110" | "10011111" | -- ANLD PP, A |
347,12 → 333,6
mnemonic_v := MN_OUTD_PP_A; |
multi_cycle_v := true; |
|
-- Mnemonic OUTL_EXT ---------------------------------------------------- |
when "00111001" | "00111010" | -- OUTL Pp, A |
"00000010" => -- OUTL BUS, A |
mnemonic_v := MN_OUTL_EXT; |
multi_cycle_v := true; |
|
-- Mnemonic RET --------------------------------------------------------- |
when "10000011" | -- RET |
"10010011" => -- RETR |
369,11 → 349,6
"01100111" => -- RRC A |
mnemonic_v := MN_RR; |
|
-- Mnemonic SEL_MB ------------------------------------------------------ |
when "11100101" | -- SEL MB0 |
"11110101" => -- SEL MB1 |
mnemonic_v := MN_SEL_MB; |
|
-- Mnemonic SEL_RB ------------------------------------------------------ |
when "11000101" | -- SEL RB0 |
"11010101" => -- SEL RB1 |
411,6 → 386,7
multi_cycle_v := true; |
|
when others => |
mnemonic_v := MN_NOP; |
-- pragma translate_off |
assert now = 0 ns |
report "Unknown opcode." |
425,4 → 401,176
return result_v; |
end; |
|
|
----------------------------------------------------------------------------- |
-- Specific MCS-48 opcodes |
-- |
function decode_mcs48_opcode_f(opcode : in word_t) return |
mnemonic_rec_t is |
variable mnemonic_v : mnemonic_t; |
variable multi_cycle_v : boolean; |
variable result_v : mnemonic_rec_t; |
begin |
-- default assignment |
multi_cycle_v := false; |
|
case opcode is |
-- Mnemonic ANL_EXT ----------------------------------------------------- |
when "10011000" | -- ANL BUS, data |
"10011001" | "10011010" => -- ANL PP, data |
mnemonic_v := MN_ANL_EXT; |
multi_cycle_v := true; |
|
-- Mnemonic ENT0_CLK ---------------------------------------------------- |
when "01110101" => -- ENT0 CLK |
mnemonic_v := MN_ENT0_CLK; |
|
-- Mnemonic INS --------------------------------------------------------- |
when "00001000" => -- INS A, BUS |
mnemonic_v := MN_INS; |
multi_cycle_v := true; |
|
-- Mnemonic JNI --------------------------------------------------------- |
when "10000110" => -- JNI addr |
mnemonic_v := MN_JNI; |
multi_cycle_v := true; |
|
-- Mnemonic MOVX -------------------------------------------------------- |
when "10000000" | "10000001" | -- MOVX A, @ Rr |
"10010000" | "10010001" => -- MOVX @ Rr, A |
mnemonic_v := MN_MOVX; |
multi_cycle_v := true; |
|
-- Mnemonic ORL_EXT ----------------------------------------------------- |
when "10001000" | -- ORL BUS, data |
"10001001" | "10001010" => -- ORL Pp, data |
mnemonic_v := MN_ORL_EXT; |
multi_cycle_v := true; |
|
-- Mnemonic OUTL_EXT ---------------------------------------------------- |
when "00111001" | "00111010" | -- OUTL Pp, A |
"00000010" => -- OUTL BUS, A |
mnemonic_v := MN_OUTL_EXT; |
multi_cycle_v := true; |
|
-- Mnemonic SEL_MB ------------------------------------------------------ |
when "11100101" | -- SEL MB0 |
"11110101" => -- SEL MB1 |
mnemonic_v := MN_SEL_MB; |
|
when others => |
mnemonic_v := MN_INVALID; |
|
end case; |
|
if mnemonic_v = MN_INVALID then |
result_v := decode_common_opcode_f(opcode); |
else |
result_v.mnemonic := mnemonic_v; |
result_v.multi_cycle := multi_cycle_v; |
end if; |
|
return result_v; |
end; |
|
|
----------------------------------------------------------------------------- |
-- Specific UPI-41 opcodes |
-- |
function decode_upi41_opcode_f(opcode : in word_t) return |
mnemonic_rec_t is |
variable mnemonic_v : mnemonic_t; |
variable multi_cycle_v : boolean; |
variable result_v : mnemonic_rec_t; |
begin |
-- default assignment |
multi_cycle_v := false; |
|
case opcode is |
-- Mnemonic ANL_EXT ----------------------------------------------------- |
when "10011001" | "10011010" => -- ANL PP, data |
mnemonic_v := MN_ANL_EXT; |
multi_cycle_v := true; |
|
-- Mnemonic IN_DBB ------------------------------------------------------ |
when "00100010" => -- IN A, DBB |
mnemonic_v := MN_IN_DBB; |
|
-- Mnemonic JNIBF ------------------------------------------------------- |
when "11010110" => -- JNIBF addr |
mnemonic_v := MN_JNIBF; |
multi_cycle_v := true; |
|
-- Mnemonic JOBF -------------------------------------------------------- |
when "10000110" => -- JOBF addr |
mnemonic_v := MN_JOBF; |
multi_cycle_v := true; |
|
-- Mnemonic ORL_EXT ----------------------------------------------------- |
when "10001001" | "10001010" => -- ORL Pp, data |
mnemonic_v := MN_ORL_EXT; |
multi_cycle_v := true; |
|
-- Mnemonic OUT_DBB ----------------------------------------------------- |
when "00000010" => -- OUT DBB, A |
mnemonic_v := MN_OUT_DBB; |
|
-- Mnemonic OUTL_EXT ---------------------------------------------------- |
when "00111001" | "00111010" => -- OUTL Pp, A |
mnemonic_v := MN_OUTL_EXT; |
multi_cycle_v := true; |
|
when others => |
mnemonic_v := MN_INVALID; |
|
end case; |
|
if mnemonic_v = MN_INVALID then |
result_v := decode_common_opcode_f(opcode); |
else |
result_v.mnemonic := mnemonic_v; |
result_v.multi_cycle := multi_cycle_v; |
end if; |
|
return result_v; |
end; |
|
|
----------------------------------------------------------------------------- |
-- Specific UPI-41A opcodes |
-- |
function decode_upi41a_opcode_f(opcode : in word_t) return |
mnemonic_rec_t is |
variable mnemonic_v : mnemonic_t; |
variable multi_cycle_v : boolean; |
variable result_v : mnemonic_rec_t; |
begin |
-- default assignment |
multi_cycle_v := false; |
|
case opcode is |
-- Mnemonic EN_DMA_FLAGS ------------------------------------------------ |
when "11100101" | -- EN DMA |
"11110101" => -- EN FLAGS |
mnemonic_v := MN_EN_DMA_FLAGS; |
|
-- Mnemonic MOV_STS ----------------------------------------------------- |
when "10010000" => -- MOV STS, A |
mnemonic_v := MN_MOV_STS; |
|
when others => |
mnemonic_v := MN_INVALID; |
|
end case; |
|
if mnemonic_v = MN_INVALID then |
result_v := decode_upi41_opcode_f(opcode); |
else |
result_v.mnemonic := mnemonic_v; |
result_v.multi_cycle := multi_cycle_v; |
end if; |
|
return result_v; |
end; |
|
end t48_decoder_pack; |
/trunk/rtl/vhdl/system/t48_system_comp_pack-p.vhd
174,4 → 174,52
); |
end component; |
|
component t8041a_notri |
generic ( |
gate_port_input_g : integer := 1 |
); |
|
port ( |
xtal_i : in std_logic; |
xtal_en_i : in std_logic; |
reset_n_i : in std_logic; |
t0_i : in std_logic; |
cs_n_i : in std_logic; |
rd_n_i : in std_logic; |
a0_i : in std_logic; |
wr_n_i : in std_logic; |
sync_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); |
p2l_low_imp_o : out std_logic; |
p2h_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 |
); |
end component; |
|
component t8041a |
port ( |
xtal_i : in std_logic; |
reset_n_i : in std_logic; |
t0_i : in std_logic; |
cs_n_i : in std_logic; |
rd_n_i : in std_logic; |
a0_i : in std_logic; |
wr_n_i : in std_logic; |
sync_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 component; |
|
end t48_system_comp_pack; |
/trunk/rtl/vhdl/system/t8041a-c.vhd
0,0 → 1,21
------------------------------------------------------------------------------- |
-- |
-- T8041A Microcontroller System |
-- |
-- Copyright (c) 2004-2022, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration t8041a_struct_c0 of t8041a is |
|
for struct |
|
for t8041a_notri_b : t8041a_notri |
use configuration work.t8041a_notri_struct_c0; |
end for; |
|
end for; |
|
end t8041a_struct_c0; |
/trunk/rtl/vhdl/system/t8041a.vhd
0,0 → 1,170
------------------------------------------------------------------------------- |
-- |
-- T8041A Microcontroller System |
-- |
-- Copyright (c) 2004-2022, 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 t8041a is |
|
port ( |
xtal_i : in std_logic; |
reset_n_i : in std_logic; |
t0_i : in std_logic; |
cs_n_i : in std_logic; |
rd_n_i : in std_logic; |
a0_i : in std_logic; |
wr_n_i : in std_logic; |
sync_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 t8041a; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
use work.t48_system_comp_pack.t8041a_notri; |
|
architecture struct of t8041a is |
|
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 p2l_low_imp_s : std_logic; |
signal p2h_low_imp_s : std_logic; |
signal p1_s : std_logic_vector( 7 downto 0); |
signal p1_low_imp_s : std_logic; |
|
signal vdd_s : std_logic; |
|
begin |
|
vdd_s <= '1'; |
|
t8041a_notri_b : t8041a_notri |
generic map ( |
-- we don't need explicit gating of input ports |
-- this is done implicitely by the bidirectional pads |
gate_port_input_g => 0 |
) |
|
port map ( |
xtal_i => xtal_i, |
xtal_en_i => vdd_s, |
reset_n_i => reset_n_i, |
t0_i => t0_i, |
cs_n_i => cs_n_i, |
rd_n_i => rd_n_i, |
a0_i => a0_i, |
wr_n_i => wr_n_i, |
sync_o => sync_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, |
p2l_low_imp_o => p2l_low_imp_s, |
p2h_low_imp_o => p2h_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 |
); |
|
----------------------------------------------------------------------------- |
-- Process bidirs |
-- |
-- Purpose: |
-- Assign bidirectional signals. |
-- |
bidirs: process (db_b, db_s, db_dir_s, |
p1_b, p1_s, p1_low_imp_s, |
p2_b, p2_s, p2l_low_imp_s, p2h_low_imp_s) |
|
function port_bidir_f(port_value : in std_logic_vector; |
low_imp : in std_logic) return std_logic_vector is |
variable result_v : std_logic_vector(port_value'range); |
begin |
for idx in port_value'high downto port_value'low loop |
if low_imp = '1' then |
result_v(idx) := port_value(idx); |
elsif port_value(idx) = '0' then |
result_v(idx) := '0'; |
else |
result_v(idx) := 'Z'; |
end if; |
end loop; |
|
return result_v; |
end; |
|
begin |
-- Data Bus --------------------------------------------------------------- |
if db_dir_s = '1' then |
db_b <= db_s; |
else |
db_b <= (others => 'Z'); |
end if; |
|
-- Port 1 ----------------------------------------------------------------- |
p1_b <= port_bidir_f(port_value => p1_s, |
low_imp => p1_low_imp_s); |
|
-- Port 2 ----------------------------------------------------------------- |
p2_b(3 downto 0) <= port_bidir_f(port_value => p2_s(3 downto 0), |
low_imp => p2l_low_imp_s); |
p2_b(7 downto 4) <= port_bidir_f(port_value => p2_s(7 downto 4), |
low_imp => p2h_low_imp_s); |
|
end process bidirs; |
-- |
----------------------------------------------------------------------------- |
|
|
end struct; |
/trunk/rtl/vhdl/system/t8041a_notri-c.vhd
0,0 → 1,29
------------------------------------------------------------------------------- |
-- |
-- T8041A Microcontroller System |
-- |
-- Copyright (c) 2004-2022, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration t8041a_notri_struct_c0 of t8041a_notri is |
|
for struct |
|
for rom_1k_b : t48_rom |
use configuration work.t48_rom_lpm_c0; |
end for; |
|
for ram_64_b : generic_ram_ena |
use configuration work.generic_ram_ena_rtl_c0; |
end for; |
|
for upi41a_core_b : upi41_core |
use configuration work.upi41_core_struct_c0; |
end for; |
|
end for; |
|
end t8041a_notri_struct_c0; |
/trunk/rtl/vhdl/system/t8041a_notri.vhd
0,0 → 1,205
------------------------------------------------------------------------------- |
-- |
-- T8041A Microcontroller System |
-- 8041A toplevel without tri-states |
-- |
-- Copyright (c) 2004-2022, 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 t8041a_notri is |
|
generic ( |
gate_port_input_g : integer := 1 |
); |
|
port ( |
xtal_i : in std_logic; |
xtal_en_i : in std_logic; |
reset_n_i : in std_logic; |
t0_i : in std_logic; |
cs_n_i : in std_logic; |
rd_n_i : in std_logic; |
a0_i : in std_logic; |
wr_n_i : in std_logic; |
sync_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); |
p2l_low_imp_o : out std_logic; |
p2h_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 |
); |
|
end t8041a_notri; |
|
|
library ieee; |
use ieee.numeric_std.all; |
|
use work.t48_core_comp_pack.upi41_core; |
use work.t48_core_comp_pack.t48_rom; |
use work.t48_core_comp_pack.generic_ram_ena; |
|
architecture struct of t8041a_notri is |
|
-- Address width of internal ROM |
constant rom_addr_width_c : natural := 10; |
|
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(10 downto 0); |
signal pmem_data_s : std_logic_vector( 7 downto 0); |
|
signal p1_in_s, |
p1_out_s : std_logic_vector( 7 downto 0); |
signal p2_in_s, |
p2_out_s : std_logic_vector( 7 downto 0); |
|
signal vdd_s : std_logic; |
|
begin |
|
vdd_s <= '1'; |
|
----------------------------------------------------------------------------- |
-- Check generics for valid values. |
----------------------------------------------------------------------------- |
-- pragma translate_off |
assert gate_port_input_g = 0 or gate_port_input_g = 1 |
report "gate_port_input_g must be either 1 or 0!" |
severity failure; |
-- pragma translate_on |
|
|
upi41a_core_b : upi41_core |
generic map ( |
xtal_div_3_g => 1, |
register_mnemonic_g => 1, |
include_port1_g => 1, |
include_port2_g => 1, |
include_timer_g => 1, |
sample_t1_state_g => 4, |
is_upi_type_a_g => 1 |
) |
|
port map ( |
xtal_i => xtal_i, |
xtal_en_i => xtal_en_i, |
reset_i => reset_n_i, |
t0_i => t0_i, |
cs_n_i => cs_n_i, |
rd_n_i => rd_n_i, |
a0_i => a0_i, |
wr_n_i => wr_n_i, |
sync_o => sync_o, |
db_i => db_i, |
db_o => db_o, |
db_dir_o => db_dir_o, |
t1_i => t1_i, |
p2_i => p2_in_s, |
p2_o => p2_out_s, |
p2l_low_imp_o => p2l_low_imp_o, |
p2h_low_imp_o => p2h_low_imp_o, |
p1_i => p1_in_s, |
p1_o => p1_out_s, |
p1_low_imp_o => p1_low_imp_o, |
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 |
); |
|
|
----------------------------------------------------------------------------- |
-- Gate port 1 and 2 input bus with respetive output value |
----------------------------------------------------------------------------- |
gate_ports: if gate_port_input_g = 1 generate |
p1_in_s <= p1_i and p1_out_s; |
p2_in_s <= p2_i and p2_out_s; |
end generate; |
|
pass_ports: if gate_port_input_g = 0 generate |
p1_in_s <= p1_i; |
p2_in_s <= p2_i; |
end generate; |
|
p1_o <= p1_out_s; |
p2_o <= p2_out_s; |
|
|
rom_1k_b : t48_rom |
port map ( |
clk_i => xtal_i, |
rom_addr_i => pmem_addr_s(rom_addr_width_c-1 downto 0), |
rom_data_o => pmem_data_s |
); |
|
ram_64_b : generic_ram_ena |
generic map ( |
addr_width_g => 6, |
data_width_g => 8 |
) |
port map ( |
clk_i => xtal_i, |
a_i => dmem_addr_s(5 downto 0), |
we_i => dmem_we_s, |
ena_i => vdd_s, |
d_i => dmem_data_to_s, |
d_o => dmem_data_from_s |
); |
|
end struct; |
/trunk/rtl/vhdl/t48_comp_pack-p.vhd
107,6 → 107,8
f1_i : in std_logic; |
tf_i : in std_logic; |
carry_i : in std_logic; |
ibf_i : in std_logic := '0'; |
obf_i : in std_logic := '0'; |
comp_value_i : in comp_value_t |
); |
end component; |
130,9 → 132,44
); |
end component; |
|
component upi41_db_bus |
generic ( |
is_type_a_g : integer := 1 |
); |
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_bus_i : in boolean; |
read_bus_i : in boolean; |
write_sts_i : in boolean; |
set_f1_o : out boolean; |
clear_f1_o : out boolean; |
f0_i : in std_logic; |
f1_i : in std_logic; |
ibf_o : out std_logic; |
obf_o : out std_logic; |
int_n_o : out std_logic; |
ibf_int_i : in boolean; |
en_dma_i : in boolean; |
en_flags_i : in boolean; |
a0_i : in std_logic; |
cs_n_i : in std_logic; |
rd_n_i : in std_logic; |
wr_n_i : in std_logic; |
db_i : in word_t; |
db_o : out word_t; |
db_dir_o : out std_logic |
); |
end component; |
|
component t48_decoder |
generic ( |
register_mnemonic_g : integer := 1 |
register_mnemonic_g : integer := 1; |
is_upi_g : integer := 0; |
is_upi_type_a_g : integer := 0 |
); |
port ( |
clk_i : in std_logic; |
152,6 → 189,12
alu_read_alu_o : out boolean; |
bus_write_bus_o : out boolean; |
bus_read_bus_o : out boolean; |
bus_set_f1_i : in boolean := false; |
bus_clear_f1_i : in boolean := false; |
bus_ibf_int_o : out boolean; |
bus_en_dma_o : out boolean; |
bus_en_flags_o : out boolean; |
bus_write_sts_o : out boolean; |
dm_write_dmem_addr_o : out boolean; |
dm_write_dmem_o : out boolean; |
dm_read_dmem_o : out boolean; |
/trunk/rtl/vhdl/t48_core_comp_pack-p.vhd
61,6 → 61,51
); |
end component; |
|
component upi41_core |
generic ( |
xtal_div_3_g : integer := 1; |
register_mnemonic_g : integer := 1; |
include_port1_g : integer := 1; |
include_port2_g : integer := 1; |
include_timer_g : integer := 1; |
sample_t1_state_g : integer := 4; |
is_upi_type_a_g : integer := 1 |
); |
|
port ( |
xtal_i : in std_logic; |
xtal_en_i : in std_logic; |
reset_i : in std_logic; |
t0_i : in std_logic; |
cs_n_i : in std_logic; |
rd_n_i : in std_logic; |
a0_i : in std_logic; |
wr_n_i : in std_logic; |
sync_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); |
p2l_low_imp_o : out std_logic; |
p2h_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(10 downto 0); |
pmem_data_i : in std_logic_vector( 7 downto 0) |
); |
end component; |
|
component generic_ram_ena |
generic ( |
addr_width_g : integer := 10; |
/trunk/rtl/vhdl/upi41_core-c.vhd
0,0 → 1,67
------------------------------------------------------------------------------- |
-- |
-- UPI-41 Microcontroller Core |
-- |
------------------------------------------------------------------------------- |
|
configuration upi41_core_struct_c0 of upi41_core is |
|
for struct |
|
for alu_b : t48_alu |
use configuration work.t48_alu_rtl_c0; |
end for; |
|
for bus_mux_b : t48_bus_mux |
use configuration work.t48_bus_mux_rtl_c0; |
end for; |
|
for clock_ctrl_b : t48_clock_ctrl |
use configuration work.t48_clock_ctrl_rtl_c0; |
end for; |
|
for cond_branch_b : t48_cond_branch |
use configuration work.t48_cond_branch_rtl_c0; |
end for; |
|
for db_bus_b : upi41_db_bus |
use configuration work.upi41_db_bus_rtl_c0; |
end for; |
|
for decoder_b : t48_decoder |
use configuration work.t48_decoder_rtl_c0; |
end for; |
|
for dmem_ctrl_b : t48_dmem_ctrl |
use configuration work.t48_dmem_ctrl_rtl_c0; |
end for; |
|
for use_timer |
for timer_b : t48_timer |
use configuration work.t48_timer_rtl_c0; |
end for; |
end for; |
|
for use_p1 |
for p1_b : t48_p1 |
use configuration work.t48_p1_rtl_c0; |
end for; |
end for; |
|
for use_p2 |
for p2_b : t48_p2 |
use configuration work.t48_p2_rtl_c0; |
end for; |
end for; |
|
for pmem_ctrl_b : t48_pmem_ctrl |
use configuration work.t48_pmem_ctrl_rtl_c0; |
end for; |
|
for psw_b : t48_psw |
use configuration work.t48_psw_rtl_c0; |
end for; |
|
end for; |
|
end upi41_core_struct_c0; |
/trunk/rtl/vhdl/upi41_core.vhd
0,0 → 1,655
------------------------------------------------------------------------------- |
-- |
-- UPI-41 Microcontroller Core |
-- |
-- Copyright (c) 2004-2022, 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: |
-- |
-- * 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 upi41_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 timer module |
include_timer_g : integer := 1; |
-- state in which T1 is sampled (3 or 4) |
sample_t1_state_g : integer := 4; |
-- UPI41 type a |
is_upi_type_a_g : integer := 1 |
); |
|
port ( |
-- UPI41 Interface -------------------------------------------------------- |
xtal_i : in std_logic; |
xtal_en_i : in std_logic; |
reset_i : in std_logic; |
t0_i : in std_logic; |
cs_n_i : in std_logic; |
rd_n_i : in std_logic; |
a0_i : in std_logic; |
wr_n_i : in std_logic; |
sync_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); |
p2l_low_imp_o : out std_logic; |
p2h_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(10 downto 0); |
pmem_data_i : in std_logic_vector( 7 downto 0) |
); |
|
end upi41_core; |
|
|
use work.t48_alu_pack.alu_op_t; |
use work.t48_cond_branch_pack.branch_conditions_t; |
use work.t48_cond_branch_pack.comp_value_t; |
use work.t48_dmem_ctrl_pack.dmem_addr_ident_t; |
use work.t48_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 upi41_core is |
|
signal t48_data_s : word_t; |
|
signal xtal_en_s : boolean; |
signal en_clk_s : boolean; |
|
signal t0_s, t1_s : std_logic; |
|
-- 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_data_s : word_t; |
-- UPI41 |
signal bus_ibf_s : std_logic; |
signal bus_obf_s : std_logic; |
signal bus_int_n_s : std_logic; |
signal bus_set_f1_s : boolean; |
signal bus_clear_f1_s : boolean; |
signal bus_ibf_int_s : boolean; |
signal bus_en_dma_s : boolean; |
signal bus_en_flags_s : boolean; |
signal bus_write_sts_s : boolean; |
|
-- 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_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; |
|
signal gnd_s : std_logic; |
|
begin |
|
-- TODO |
sync_o <= '0'; |
|
gnd_s <= '0'; |
|
----------------------------------------------------------------------------- |
-- 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; |
-- pragma translate_on |
|
|
xtal_en_s <= to_boolean(xtal_en_i); |
en_clk_s <= to_boolean(en_clk_i); |
|
t0_s <= To_X01Z(t0_i); |
t1_s <= To_X01Z(t1_i); |
|
alu_b : t48_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 : t48_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 : t48_clock_ctrl |
generic map ( |
xtal_div_3_g => xtal_div_3_g |
) |
port map ( |
clk_i => clk_i, |
xtal_i => xtal_i, |
xtal_en_i => xtal_en_s, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
xtal3_o => xtal3_s, |
t0_o => open, |
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 : t48_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 => t0_s, |
t1_i => t1_s, |
int_n_i => bus_int_n_s, |
f0_i => psw_f0_s, |
f1_i => cnd_f1_s, |
tf_i => cnd_tf_s, |
carry_i => psw_carry_s, |
ibf_i => bus_ibf_s, |
obf_i => bus_obf_s, |
comp_value_i => cnd_comp_value_s |
); |
|
db_bus_b : upi41_db_bus |
generic map ( |
is_type_a_g => 1 |
) |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
data_i => t48_data_s, |
data_o => bus_data_s, |
write_bus_i => bus_write_bus_s, |
read_bus_i => bus_read_bus_s, |
write_sts_i => bus_write_sts_s, |
set_f1_o => bus_set_f1_s, |
clear_f1_o => bus_clear_f1_s, |
f0_i => psw_f0_s, |
f1_i => cnd_f1_s, |
ibf_o => bus_ibf_s, |
obf_o => bus_obf_s, |
int_n_o => bus_int_n_s, |
ibf_int_i => bus_ibf_int_s, |
en_dma_i => bus_en_dma_s, |
en_flags_i => bus_en_flags_s, |
a0_i => a0_i, |
cs_n_i => cs_n_i, |
rd_n_i => rd_n_i, |
wr_n_i => wr_n_i, |
db_i => db_i, |
db_o => db_o, |
db_dir_o => db_dir_o |
); |
|
decoder_b : t48_decoder |
generic map ( |
register_mnemonic_g => register_mnemonic_g, |
is_upi_g => 1, |
is_upi_type_a_g => is_upi_type_a_g |
) |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
xtal_i => xtal_i, |
xtal_en_i => xtal_en_s, |
ea_i => gnd_s, |
ale_i => ale_s, |
int_n_i => bus_int_n_s, |
t0_dir_o => open, |
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, |
bus_set_f1_i => bus_set_f1_s, -- UPI41 |
bus_clear_f1_i => bus_clear_f1_s, -- UPI41 |
bus_ibf_int_o => bus_ibf_int_s, -- UPI41 |
bus_en_dma_o => bus_en_dma_s, -- UPI41A |
bus_en_flags_o => bus_en_flags_s, -- UPI41A |
bus_write_sts_o => bus_write_sts_s, -- UPI41A |
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 => open, |
bus_bidir_bus_o => open, |
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, |
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 : t48_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 : t48_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 => t1_s, |
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 : t48_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 : t48_p2 |
port map ( |
clk_i => clk_i, |
res_i => reset_i, |
en_clk_i => en_clk_s, |
xtal_i => xtal_i, |
xtal_en_i => xtal_en_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, |
pch_i => pmem_addr_s(11 downto 8), |
p2_i => p2_i, |
p2_o => p2_o, |
p2l_low_imp_o => p2l_low_imp_o, |
p2h_low_imp_o => p2h_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'); |
p2l_low_imp_o <= '0'; |
p2h_low_imp_o <= '0'; |
end generate; |
|
pmem_ctrl_b : t48_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 : t48_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. |
----------------------------------------------------------------------------- |
prog_n_o <= to_stdLogic(not prog_s); |
xtal3_o <= to_stdLogic(xtal3_s); |
pmem_addr_o <= pmem_addr_s(10 downto 0); |
|
end struct; |
/trunk/rtl/vhdl/upi41_db_bus-c.vhd
0,0 → 1,17
------------------------------------------------------------------------------- |
-- |
-- The UPI-41 BUS unit. |
-- Implements the BUS port logic. |
-- |
-- Copyright (c) 2004-2022, Arnim Laeuger (arniml@opencores.org) |
-- |
-- All rights reserved |
-- |
------------------------------------------------------------------------------- |
|
configuration upi41_db_bus_rtl_c0 of upi41_db_bus is |
|
for rtl |
end for; |
|
end upi41_db_bus_rtl_c0; |
/trunk/rtl/vhdl/upi41_db_bus.vhd
0,0 → 1,216
------------------------------------------------------------------------------- |
-- |
-- The UPI-41 BUS unit. |
-- Implements the BUS port logic. |
-- |
-- Copyright (c) 2004-2022, 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 upi41_db_bus is |
|
generic ( |
is_type_a_g : integer := 1 |
); |
port ( |
-- Global Interface ------------------------------------------------------- |
clk_i : in std_logic; |
res_i : in std_logic; |
en_clk_i : in boolean; |
-- UPI41 Bus Interface ---------------------------------------------------- |
data_i : in word_t; |
data_o : out word_t; |
write_bus_i : in boolean; |
read_bus_i : in boolean; |
write_sts_i : in boolean; |
set_f1_o : out boolean; |
clear_f1_o : out boolean; |
f0_i : in std_logic; |
f1_i : in std_logic; |
ibf_o : out std_logic; |
obf_o : out std_logic; |
int_n_o : out std_logic; |
ibf_int_i : in boolean; |
en_dma_i : in boolean; |
en_flags_i : in boolean; |
-- BUS Interface ---------------------------------------------------------- |
a0_i : in std_logic; |
cs_n_i : in std_logic; |
rd_n_i : in std_logic; |
wr_n_i : in std_logic; |
db_i : in word_t; |
db_o : out word_t; |
db_dir_o : out std_logic |
); |
|
end upi41_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 upi41_db_bus is |
|
signal read_s, read_q, |
read_hold_q, |
write_s, write_q, |
read_pulse_s, write_pulse_s : boolean; |
|
signal ibf_q, obf_q : std_logic; |
|
-- the BUS output register |
signal dbbin_q, |
dbbout_q : word_t; |
-- the BUS status register |
signal sts_q : word_t; |
|
begin |
|
-- pragma translate_off |
|
-- UPI41 configuration ------------------------------------------------------ |
assert (is_type_a_g = 0) or (is_type_a_g = 1) |
report "is_type_a_g must be either 1 or 0!" |
severity failure; |
|
-- pragma translate_on |
|
|
----------------------------------------------------------------------------- |
-- Process master_access |
-- |
-- Purpose: |
-- Generate read and write pulses based on master access. |
-- |
read_s <= cs_n_i = '0' and rd_n_i = '0'; |
write_s <= cs_n_i = '0' and wr_n_i = '0'; |
-- |
master_access: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
read_q <= false; |
read_hold_q <= false; |
write_q <= false; |
|
elsif clk_i'event and clk_i = clk_active_c then |
read_q <= read_s; |
write_q <= write_s; |
|
if read_s then |
read_hold_q <= true; |
elsif cs_n_i = '1' then |
read_hold_q <= false; |
end if; |
|
end if; |
end process master_access; |
-- |
read_pulse_s <= read_q and not read_s; |
write_pulse_s <= write_q and not write_s; |
|
----------------------------------------------------------------------------- |
-- Process bus_regs |
-- |
-- Purpose: |
-- Implements the BUS output register. |
-- |
bus_regs: process (res_i, clk_i) |
begin |
if res_i = res_active_c then |
dbbin_q <= (others => '0'); |
dbbout_q <= (others => '0'); |
sts_q <= (others => '0'); |
ibf_q <= '0'; |
obf_q <= '0'; |
int_n_o <= '1'; |
|
elsif clk_i'event and clk_i = clk_active_c then |
-- master access |
if read_pulse_s then |
obf_q <= '0'; |
elsif write_pulse_s then |
dbbin_q <= db_i; |
ibf_q <= '1'; |
int_n_o <= '0'; |
end if; |
|
if en_clk_i then |
if write_bus_i then |
dbbout_q <= data_i; |
obf_q <= '1'; |
elsif read_bus_i then |
ibf_q <= '0'; |
elsif write_sts_i then |
sts_q <= data_i; |
end if; |
|
if ibf_int_i then |
int_n_o <= '1'; |
end if; |
|
end if; |
|
end if; |
|
end process bus_regs; |
-- |
----------------------------------------------------------------------------- |
|
|
----------------------------------------------------------------------------- |
-- Output Mapping. |
----------------------------------------------------------------------------- |
set_f1_o <= write_pulse_s and a0_i = '1'; |
clear_f1_o <= write_pulse_s and a0_i = '0'; |
ibf_o <= ibf_q; |
obf_o <= obf_q; |
db_o <= dbbout_q when a0_i = '0' else |
sts_q(7 downto 4) & f1_i & f0_i & ibf_q & obf_q; |
db_dir_o <= '1' when cs_n_i = '0' and read_hold_q else '0'; |
data_o <= dbbin_q |
when read_bus_i else |
(others => bus_idle_level_c); |
|
end rtl; |
/trunk/sim/rtl_sim/Makefile.ghdl
34,6 → 34,17
############################################################################## |
# The analyze targets |
# |
upi41_db_bus_rtl_c0 = $(LIB_WORK)/upi41_db_bus-c.o |
upi41_db_bus = $(LIB_WORK)/upi41_db_bus.o |
upi41_core_struct_c0 = $(LIB_WORK)/upi41_core-c.o |
upi41_core = $(LIB_WORK)/upi41_core.o |
t8041a_notri_struct_c0 = $(LIB_WORK)/t8041a_notri-c.o |
t8041a_notri = $(LIB_WORK)/t8041a_notri.o |
t8041a_struct_c0 = $(LIB_WORK)/t8041a-c.o |
t8041a = $(LIB_WORK)/t8041a.o |
tb_t8041a_behav_c0 = $(LIB_WORK)/tb_t8041a-c.o |
tb_t8041a = $(LIB_WORK)/tb_t8041a.o |
|
tb_t8243_behav_c0 = $(LIB_WORK)/tb_t8243-c.o |
tb_t8243 = $(LIB_WORK)/tb_t8243.o |
tb_t8048_t8243_behav_c0 = $(LIB_WORK)/tb_t8048_t8243-c.o |
132,6 → 143,7
tb_t8039_elab = tb_t8039_behav_c0 |
tb_t8048_t8243_elab = tb_t8048_t8243_behav_c0 |
tb_t8243_elab = tb_t8243_behav_c0 |
tb_t8041a_elab = tb_t8041a_behav_c0 |
# |
############################################################################## |
|
154,9 → 166,13
$(tb_t8243_elab) : $(tb_t8243_behav_c0) |
$(ELABORATE) tb_t8243_behav_c0 |
|
$(tb_t8041a_elab) : $(tb_t8041a_behav_c0) |
$(ELABORATE) tb_t8041a_behav_c0 |
|
.PHONY: elaborate |
elaborate: $(LIB_WORK) $(tb_elab) $(tb_t8048_elab) $(tb_t8039_elab) \ |
$(tb_t8048_t8243_elab) $(tb_t8243_elab) |
$(tb_t8048_t8243_elab) $(tb_t8243_elab) \ |
$(tb_t8041a_elab) |
# |
############################################################################## |
|
/trunk/sim/rtl_sim/Makefile.hier
431,3 → 431,78
$(t48_core_comp_pack) \ |
$(tb_t8243) |
$(ANALYZE) $< |
|
$(upi41_db_bus) : $(RTL_DIR)/upi41_db_bus.vhd \ |
$(t48_pack) |
$(ANALYZE) $< |
|
$(upi41_db_bus_rtl_c0) : $(RTL_DIR)/upi41_db_bus-c.vhd \ |
$(upi41_db_bus) |
$(ANALYZE) $< |
|
$(upi41_core) : $(RTL_DIR)/upi41_core.vhd \ |
$(decoder_pack) \ |
$(t48_comp_pack) \ |
$(pmem_ctrl_pack) \ |
$(dmem_ctrl_pack) \ |
$(cond_branch_pack) \ |
$(t48_pack) \ |
$(alu_pack) |
$(ANALYZE) $< |
|
$(upi41_core_struct_c0) : $(RTL_DIR)/upi41_core-c.vhd \ |
$(psw_rtl_c0) \ |
$(pmem_ctrl_rtl_c0) \ |
$(p2_rtl_c0) \ |
$(p1_rtl_c0) \ |
$(timer_rtl_c0) \ |
$(dmem_ctrl_rtl_c0) \ |
$(decoder_rtl_c0) \ |
$(upi41_db_bus_rtl_c0) \ |
$(cond_branch_rtl_c0) \ |
$(clock_ctrl_rtl_c0) \ |
$(bus_mux_rtl_c0) \ |
$(alu_rtl_c0) \ |
$(decoder_pack) \ |
$(t48_comp_pack) \ |
$(pmem_ctrl_pack) \ |
$(dmem_ctrl_pack) \ |
$(cond_branch_pack) \ |
$(t48_pack) \ |
$(alu_pack) \ |
$(upi41_core-struct) \ |
$(upi41_core) |
$(ANALYZE) $< |
|
$(t8041a_notri) : $(RTL_DIR)/system/t8041a_notri.vhd \ |
$(t48_core_comp_pack) |
$(ANALYZE) $< |
|
$(t8041a_notri_struct_c0) : $(RTL_DIR)/system/t8041a_notri-c.vhd \ |
$(upi41_core_struct_c0) \ |
$(generic_ram_ena_rtl_c0) \ |
$(t48_rom_lpm_c0) \ |
$(t48_core_comp_pack) \ |
$(t8041a_notri) |
$(ANALYZE) $< |
|
$(t8041a) : $(RTL_DIR)/system/t8041a.vhd \ |
$(t48_system_comp_pack) |
$(ANALYZE) $< |
|
$(t8041a_struct_c0) : $(RTL_DIR)/system/t8041a-c.vhd \ |
$(t8041a_notri_struct_c0) \ |
$(t8041a) |
$(ANALYZE) $< |
|
$(tb_t8041a) : $(BENCH_DIR)/tb_t8041a.vhd \ |
$(t48_tb_pack) \ |
$(t48_core_comp_pack) \ |
$(t48_system_comp_pack) |
$(ANALYZE) $< |
|
$(tb_t8041a_behav_c0) : $(BENCH_DIR)/tb_t8041a-c.vhd \ |
$(t8041a_struct_c0) \ |
$(t48_tb_pack) \ |
$(tb_t8041a) |
$(ANALYZE) $< |
/trunk/sw/run_regression.pl
66,7 → 66,8
# GHDL |
my %ghdl_simulators = ('gen' => './tb_behav_c0', |
't48' => './tb_t8048_behav_c0', |
't39' => './tb_t8039_behav_c0'); |
't39' => './tb_t8039_behav_c0', |
't41a'=> './tb_t8041a_behav_c0'); |
my %ghdl_io_expanders = ('gen' => './tb_t8243_behav_c0', |
't48' => './tb_t8048_t8243_behav_c0'); |
my $ghdl_simulator_opt = '--assert-level=error --stop-time=20ms'; |