OpenCores
URL https://opencores.org/ocsvn/mcip_open/mcip_open/trunk

Subversion Repositories mcip_open

[/] [mcip_open/] [trunk/] [MCIPopen_XilinxISEproject/] [Program_Counter.vhd] - Rev 4

Compare with Previous | Blame | View Log

--------------------------------------------------------------------------------
-- Company:        Ferhat Abbas University - Algeria
-- Engineer:       Ibrahim MEZZAH
-- Progect Supervisor: Dr H. Chemali
-- Create Date:    19:22:33 05/19/05
-- Design Name:    Program Counter
-- Module Name:    Program_Counter - Counter
-- Project Name:   Microcontroller IP (MCIP)
-- Target Device:  xc3s500e-4fg320
-- Tool versions:  Xilinx ISE 9.1.03i
-- Description:	 The Program Counter (PC) specifies the address 
--                 of the instruction to fetch for execution and addresses 
--                 each byte in the program memory. this module includes 
--                 also the Stack memory of 32 levels.
-- Revision: 		 07/06/2008
-- Revision  6
-- Additional Comments: The PC structure is PCU<4:0>:PCH<7:0>:PCL<7:0>
--                      and is equivalent to PC<20:0>.
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
 
entity Program_Counter is
    Generic ( STKPTR_length : integer := 5;  -- Stack Pointer Length -- < 6
				  STVREN : std_logic := '1'); 	-- Stack Overflow/Underflow Reset Enable bit
    Port ( nreset         : in std_logic;
           Q2             : in std_logic;
           Q4             : in std_logic;
           Command_vector : in std_logic_vector(6 downto 0);
			  Branch_data    : in std_logic_vector(11 downto 0);
			  stack_overflow : out std_logic;
			  IAddress       : out std_logic_vector(20 downto 1));
end Program_Counter;
 
architecture Behavioral of Program_Counter is
 
component Stack_ram
    Generic ( STKPTR_length : integer := STKPTR_length );
	 Port ( Q            : in std_logic;
			  write_enable : in std_logic;
			  STKPTR       : in std_logic_vector(STKPTR_length-1 downto 0);
           Data_write   : in std_logic_vector(20 downto 1);
           Data_read    : out std_logic_vector(20 downto 1));
end component Stack_ram;
 
	signal PCL : std_logic_vector(7 downto 1);
	signal PCH : std_logic_vector(7 downto 0);
	signal PCU : std_logic_vector(4 downto 0);
	signal STKPTR : std_logic_vector(STKPTR_length-1 downto 0);
 
	signal latch1      : std_logic_vector(19 downto 0);
	signal PNTR        : std_logic_vector(STKPTR_length-1 downto 0);
	signal PNTRp1      : std_logic_vector(STKPTR_length-1 downto 0);
	signal pushed_addr : std_logic_vector(20 downto 1);
	signal write_stack_enable : std_logic;
 
	signal PC       : std_logic_vector(20 downto 1);
	signal PCcall   : std_logic_vector(20 downto 1);
	signal TOS      : std_logic_vector(20 downto 1);
	signal PCs      : std_logic_vector(19 downto 0);
	signal PC_addr  : std_logic_vector(19 downto 0);
	signal offset   : std_logic_vector(19 downto 0);
	signal Br_data  : std_logic_vector(7 downto 0);
 
	alias V : std_logic_vector(6 downto 0) is Command_vector;
 
	signal STKPTRfull : std_logic_vector(STKPTR_length-1 downto 0);
	signal STKPTRzero : std_logic_vector(STKPTR_length-1 downto 0);
 
begin
 
stack : Stack_ram
Port map ( Q            => Q4,
			  write_enable => write_stack_enable,
			  STKPTR       => PNTR,
           Data_write   => pushed_addr,
           Data_read    => TOS);
 
	PC <= PCU&PCH&PCL;
	PCcall <= Branch_data&Br_data;
	PNTRp1 <= STKPTR + "1";
 
	write_stack_enable <= '1'		when Command_vector(4 downto 3) = "11" else
								 '0';
	pushed_addr <= latch1;
	PNTR <= PNTRp1						when V(4 downto 3) = "11" else
			  STKPTR;
 
	STKPTRzero <= (others => '0');
	STKPTRfull <= (others => '1');
 
 
	offset <= "00"&x"00"&Branch_data(9 downto 0)		when V(2 downto 1) = "11" and
																		  V(5) = '0' and
																		  Branch_data(10) = '0' else
				 "11"&x"ff"&Branch_data(9 downto 0)		when V(2 downto 1) = "11" and
																		  V(5) = '0' and
																		  Branch_data(10) = '1' else
				 x"000"&Branch_data(7 downto 0)			when V(2 downto 1) = "10" and
																		  V(5) = '0' and
																		  Branch_data(7) = '0' else
				 x"fff"&Branch_data(7 downto 0)			when V(2 downto 1) = "10" and
																		  V(5) = '0' and
																		  Branch_data(7) = '1' else
				 x"00001";
	PC_addr <= PCcall(20 downto 1) + "1"			when V(5) = '1' else
				  PC(20 downto 1) + offset;
	PCs <= PC_addr											when V(0)  = '0' else
			 latch1;
 
	IAddress <= PCcall										when V(5) = '1' else
				   PC;
 
Load_latchs : process (nreset, Q4, PCU, PCH,
							  PCs, V(4), V(3), latch1, PNTRp1)
	begin	 
	 if nreset = '0' then
		 PCL     <= (others => '0');
		 PCH     <= (others => '0');
		 PCU     <= (others => '0');
		 STKPTR  <= (others => '0');
		 stack_overflow <= '0';
	 else
	 if Q4'event and Q4='1'  then
			PCL <= PCs(6 downto 0);
			PCH <= PCs(14 downto 7);
			PCU <= PCs(19 downto 15);
		 if V(4) = '1' then
			if V(3) = '1' then			  -- PUCH --> stack
			  if STKPTR = STKPTRfull then
					if STVREN = '1' then
						stack_overflow <= '1';
					end if;
			  else
			  STKPTR <= PNTRp1;
			  end if;
			else								  -- POP  <-- stack
			  if STKPTR = STKPTRzero then
					if STVREN = '1' then
						stack_overflow <= '1';
					end if;
			  else
			  STKPTR <= STKPTR - "1";
			  end if;
			end if;
		 end if;
	 end if;
	 end if;
	end process;
 
	process(nreset, Q2, V(6 downto 5), Branch_data,
			  V(3), V(4), PC, TOS)
	begin
		 if nreset = '0' then
			latch1  <= (others => '0');
			Br_data <= (others => '0');
		 else
		 if Q2'event and Q2='1' then
			if V(6 downto 5) = "10" then
				Br_data <= Branch_data(7 downto 0);
			end if;
			if V(4) = '1' then
				if V(3) = '1' then
				  latch1 <= PCU&PCH&PCL;
				else
				  latch1 <= TOS; --(20 downto 1);
				end if;
			 end if;
		  end if;
		  end if;
	end process;
 
end Behavioral;

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.