]> rtime.felk.cvut.cz Git - fpga/plasma.git/blob - vhdl/pc_next.vhd
Local copy of Plasma MIPS project.
[fpga/plasma.git] / vhdl / pc_next.vhd
1 ---------------------------------------------------------------------
2 -- TITLE: Program Counter Next
3 -- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4 -- DATE CREATED: 2/8/01
5 -- FILENAME: pc_next.vhd
6 -- PROJECT: Plasma CPU core
7 -- COPYRIGHT: Software placed into the public domain by the author.
8 --    Software 'as is' without warranty.  Author liable for nothing.
9 -- DESCRIPTION:
10 --    Implements the Program Counter logic.
11 ---------------------------------------------------------------------
12 library ieee;
13 use ieee.std_logic_1164.all;
14 use work.mlite_pack.all;
15
16 entity pc_next is
17    port(clk         : in std_logic;
18         reset_in    : in std_logic;
19         pc_new      : in std_logic_vector(31 downto 2);
20         take_branch : in std_logic;
21         pause_in    : in std_logic;
22         opcode25_0  : in std_logic_vector(25 downto 0);
23         pc_source   : in pc_source_type;
24         pc_future   : out std_logic_vector(31 downto 2);
25         pc_current  : out std_logic_vector(31 downto 2);
26         pc_plus4    : out std_logic_vector(31 downto 2));
27 end; --pc_next
28
29 architecture logic of pc_next is
30    signal pc_reg : std_logic_vector(31 downto 2); 
31 begin
32
33 pc_select: process(clk, reset_in, pc_new, take_branch, pause_in, 
34                  opcode25_0, pc_source, pc_reg)
35    variable pc_inc      : std_logic_vector(31 downto 2);
36    variable pc_next : std_logic_vector(31 downto 2);
37 begin
38    pc_inc := bv_increment(pc_reg);  --pc_reg+1
39
40    case pc_source is
41    when FROM_INC4 =>
42       pc_next := pc_inc;
43    when FROM_OPCODE25_0 =>
44       pc_next := pc_reg(31 downto 28) & opcode25_0;
45    when FROM_BRANCH | FROM_LBRANCH =>
46       if take_branch = '1' then
47          pc_next := pc_new;
48       else
49          pc_next := pc_inc;
50       end if;
51    when others =>
52       pc_next := pc_inc;
53    end case;
54
55    if pause_in = '1' then
56       pc_next := pc_reg;
57    end if;
58
59    if reset_in = '1' then
60       pc_reg <= ZERO(31 downto 2);
61       pc_next := pc_reg;
62    elsif rising_edge(clk) then
63       pc_reg <= pc_next;
64    end if;
65
66    pc_future <= pc_next;
67    pc_current <= pc_reg;
68    pc_plus4 <= pc_inc;
69 end process;
70
71 end; --logic