📄 pc_chg_spec.vhd
字号:
--------------------------------------------------
-- Model : 8051 Behavioral Model,
-- VHDL Entity mc8051.pc_chg.interface
--
-- Author : Michael Mayer (mrmayer@computer.org),
-- Dr. Hardy J. Pottinger,
-- Department of Electrical Engineering
-- University of Missouri - Rolla
--
-- Created at : 09/19/98 20:02:01
--
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
LIBRARY mc8051 ;
USE mc8051.synth_pack.all;
ENTITY pc_chg IS
PORT(
cmp_true : IN std_logic ;
cycle_states : IN std_logic_vector( 3 DOWNTO 0 ) ;
dptr : IN std_logic_vector( 15 DOWNTO 0 ) ;
int_clk : IN std_logic ;
int_rst : IN std_logic ;
ir : IN std_logic_vector( 7 DOWNTO 0 ) ;
last_cycle : IN std_logic ;
new_ir : IN std_logic ;
pc : IN std_logic_vector( 15 DOWNTO 0 ) ;
pmem1 : IN std_logic_vector( 7 DOWNTO 0 ) ;
pmem2 : IN std_logic_vector( 7 DOWNTO 0 ) ;
addr_gb : OUT std_logic_vector( 7 DOWNTO 0 ) ;
dec_rd_sp : OUT std_logic ;
inc_wr_sp : OUT std_logic ;
indirect_sel : OUT std_logic ;
new_pc : OUT std_logic_vector( 15 DOWNTO 0 ) ;
rd_gb : OUT std_logic ;
wr_gb : OUT std_logic ;
wr_pc : OUT std_logic ;
acknow : INOUT std_logic ;
data_gb : INOUT std_logic_vector( 7 DOWNTO 0 )
);
-- Declarations
END pc_chg ;
--
-- VHDL Architecture mc8051.pc_chg.spec
--
-- Created:
-- by - mrmayer.UNKNOWN (eceultra7.ece.umr.edu)
-- at - 12:38:13 08/29/98
--
-- Generated by Mentor Graphics' Renoir(TM) 3.0 (Build 110)
--
architecture spec of pc_chg is
SIGNAL temp_reg : std_logic_vector(15 DOWNTO 0);
SIGNAL add_result, add_op1, add_op2 : unsigned(15 DOWNTO 0);
SIGNAL use_2_for_rel, use_1_for_rel : std_logic;
SIGNAL prefix : std_logic_vector(7 DOWNTO 0);
BEGIN
-- define some combinational logic to store the pc to the
-- stack for ACALL and LCALL
store_pc : PROCESS (ir, last_cycle, cycle_states, pc) IS
BEGIN
-- ACALL or LCALL
-- note the ack from gb is ignore (assumed to work)
IF std_match(ir,"---10001") OR std_match(ir,"00010010") THEN
IF last_cycle = '0' AND cycle_states = s3p1 THEN
data_gb <= pc(7 DOWNTO 0);
inc_wr_sp <= '1';
ELSIF last_cycle = '0' AND cycle_states = s4p1 THEN
data_gb <= pc(15 DOWNTO 8);
inc_wr_sp <= '1';
ELSE
data_gb <= (OTHERS => 'Z');
inc_wr_sp <= 'Z';
END IF;
END IF;
END PROCESS store_pc;
-- these two signals define which byte (pmem1 or pmem2) is used for the
-- relative address
use_1_for_rel <= '1' WHEN (std_match(ir,"11011---") OR -- DJNZ Rn, rel
std_match(ir,"01--0000") ) OR -- JC, JNC, JNZ, JZ
std_match(ir,"10000000") ELSE -- SJMP
'0';
use_2_for_rel <= '1' WHEN (std_match(ir,"1011----") AND NOT std_match(ir,"----00--") ) OR -- CJNE
std_match(ir,"11010101") OR -- DJNZ direct, rel
(std_match(ir,"00-10000") OR -- JBC; JNB
std_match(ir,"00100000") ) ELSE -- JB
'0';
-- since the pmem bytes being read in are signed displacements, the
-- following will assure that the leading 1s or 0s are correct.
prefix <= "11111111" WHEN use_1_for_rel = '1' AND pmem1(7) = '1' ELSE
"11111111" WHEN use_2_for_rel = '1' AND pmem2(7) = '1' ELSE
"00000000";
-- this should be an adder and a mux
add_op1 <= unsigned(prefix & pmem1) WHEN use_1_for_rel = '1' ELSE
unsigned(prefix & pmem2) WHEN use_2_for_rel = '1' ELSE
unsigned(prefix & temp_reg(7 DOWNTO 0)); -- will be driven with the value of acc
add_op2 <= unsigned(dptr) WHEN std_match(ir,"01110011") ELSE
unsigned(pc);
-- the resulting pc for any relative jumping
add_result <= add_op1 + add_op2;
-- get the PC either from the stack, or
-- from the pmem signals, or from add_result
get_pc : PROCESS (int_clk) IS
BEGIN
IF falling_edge(int_clk) THEN
IF std_match(ir,"001-0010") THEN
-- ret, reti
IF last_cycle = '0' THEN
IF cycle_states = s4p1 THEN
dec_rd_sp <= '1';
END IF;
If acknow = '1' THEN
temp_reg(15 DOWNTO 8) <= data_gb;
dec_rd_sp <= '0';
END IF;
ELSIF last_cycle = '1' THEN
IF cycle_states = s1p1 THEN
dec_rd_sp <= '1';
END IF;
IF acknow = '1' THEN
temp_reg(7 DOWNTO 0) <= data_gb;
dec_rd_sp <= '0';
END IF;
IF cycle_states = s4p1 THEN
new_pc <= temp_reg;
wr_pc <= '1';
END IF;
END IF;
ELSIF std_match(ir,"----0001") THEN
-- ACALL, AJMP
IF last_cycle = '1' AND cycle_states = s4p1 THEN
new_pc <= pc(15 DOWNTO 11) & ir(7 DOWNTO 5) & pmem1;
wr_pc <= '1';
ELSE
new_pc <= (OTHERS => 'Z');
wr_pc <= 'Z';
END IF;
ELSIF std_match(ir,"00010010") OR std_match(ir,"00000010") THEN
-- LCALL, LJMP
IF last_cycle = '1' AND cycle_states = s4p1 THEN
new_pc <= pmem2 & pmem1;
wr_pc <= '1';
ELSE
new_pc <= (OTHERS => 'Z');
wr_pc <= 'Z';
END IF;
ELSIF std_match(ir,"01110011") THEN -- JMP @(A + DPTR)
IF last_cycle = '1' THEN
IF cycle_states = s1p1 THEN
addr_gb <= "11100000"; -- E0, or acc
rd_gb <= '1';
END IF;
IF acknow = '1' THEN
temp_reg <= "00000000" & data_gb;
rd_gb <= 'Z';
END IF;
IF cycle_states = s4p1 THEN
new_pc <= std_logic_vector(add_result);
wr_pc <= '1';
ELSE
new_pc <= (OTHERS => 'Z');
wr_pc <= 'Z';
END IF;
END IF;
ELSIF (cmp_true = '1' AND last_cycle = '1') AND
(use_1_for_rel = '1' OR use_2_for_rel = '1') THEN
-- The following opcodes require a test result to be
-- true in order to perform the pc change
IF last_cycle = '1' AND cycle_states = s4p1 THEN
new_pc <= std_logic_vector(add_result);
wr_pc <= '1';
ELSE
new_pc <= (OTHERS => 'Z');
wr_pc <= 'L';
END IF;
ELSE -- do nothing
-- these lines may not be needed, but just in case
data_gb <= (OTHERS => 'Z');
dec_rd_sp <= 'Z';
inc_wr_sp <= 'Z';
rd_gb <= 'Z';
wr_gb <= 'Z';
new_pc <= (OTHERS => 'Z');
wr_pc <= 'Z';
addr_gb <= (OTHERS => 'Z');
END IF;
END IF;
END PROCESS get_pc;
END ARCHITECTURE spec;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -