📄 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 ) );-- DeclarationsEND 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 + -