Search code examples
vhdl

VHDL Increment 10-bit Program Counter by 1


I am trying to make a 32-bit CPU using a modified MIPS instruction set in VHDL. I am currently trying to get my Program Counter to increment by 1 for the next instruction, unless it is a jump instruction which then the Program Counter will equal the Jump value.

entity PC is
Port ( PC_IN     : in STD_LOGIC_VECTOR (9 downto 0); --New PC in value (PC+1 or jump)
       PC_OUT    : out STD_LOGIC_VECTOR (9 downto 0); --PC out to instruction memory
       Jump_Inst : in STD_LOGIC_VECTOR(9 downto 0); --Jump address
       Jump      : in STD_LOGIC; --Jump MUX
       clk       : in STD_LOGIC);
end PC;

architecture Behavioral of PC is
begin

PC_IN <= (PC_IN + "0000000001") when (Jump = '0')
else Jump_Inst;     

process(clk)
begin
   if rising_edge(clk) then --If it is the next clock cycle (i.e time for the next instruction)
   PC_OUT <= PC_IN;

end if;
end process;     
end Behavioral;

I am getting errors at this line PC_IN <= (PC_IN + "0000000001") when (Jump = '0'). The errors consist of cannot update 'in' object pc_in and 0 definitions of operator "+" match here, so it doesn't like me using the + operator and maybe pc_in needs to be an output?

Does anyone know how to get my program counter to increment by 1 for the next instruction? Any help would be appreciated. Thanks.


Solution

  • PC_IN is defined as a std_logic_vector. You don't show the libraries in use, but by default there are no defined operators for + for std_logic_vector in std_logic_1164. Note your error message:

    0 definitions of operator "+" match here

    This is your hing that + isn't defined in this context. In order to use the + operator, you need to include a library that has that support and use the appropriate type.

    Your other error:

    cannot update 'in' object pc_in

    Tells you that you cannot set an in port. Notably, PC_IN is an input, yet you are trying to drive PC_IN. Perhaps you mean to drive PC_OUT?

    I won't mention the alternate method, but you should probably use numeric_std in this case. For example:

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    ...
    
    PC_OUT <= std_logic_vector(unsigned(PC_IN) + 1) when (Jump = '0') else Jump_Inst;