VHDL Program Counter , multiple constant driver error

1k views Asked by At

I am currently attempting to design a Program Counter(PC) using previously made components. The model of my design looks like this picture here.

The issue im running into is connected my MUX component to the PC register component. I am supposed to use the given signals but I am not sure how to connect them exactly. AS stands, upon compiling I am recieving

Error (10028): Can't resolve multiple constant drivers for net "PC_next[31]" at pc_update.vhd(52)

...

Error (10028): Can't resolve multiple constant drivers for net "PC_next[14]" at pc_update.vhd(52)

Error (10029): Constant driver at pc_update.vhd(63)

Error: Can't elaborate top-level user hierarchy

I know That is because I have two components trying to write to the same signal, which is wrong, I just dont know how I am supposed to fix it. Any help is appreciated.

Here is the code I have been given, my implementation begins at the begin statement on line 41.

library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

---------------------------------------------------

entity pc_update is
    port( clk: in std_logic; -- clock
        incH_ldL: in std_logic; -- increment PC = PC + 4 when high,
                                -- load PCInput when low
        PCInput: in std_logic_vector(31 downto 0); -- external input for PC
        InstrAddr: out std_logic_vector(31 downto 0) ); -- instruction address
end entity pc_update;

----------------------------------------------------

architecture pc_update_arch of pc_update is

    component register32 is
        port( clr: in std_logic; -- async. clear
              clk: in std_logic; -- clock
               ld: in std_logic; -- load
                D: in std_logic_vector(31 downto 0); -- data input
                Q: out std_logic_vector(31 downto 0) ); -- data output
    end component register32;

    component mux2to1_32 is
        port( sel: in std_logic; -- selection bit input
               X0: in std_logic_vector(31 downto 0); -- first input
               X1: in std_logic_vector(31 downto 0); -- second input
                Y: out std_logic_vector(31 downto 0)); -- output
    end component mux2to1_32;


    signal PC_current: std_logic_vector(31 downto 0); -- the current state of
                                                      -- PC reg
    signal PC_add_4: std_logic_vector(31 downto 0); -- output from the adder 
    signal PC_next: std_logic_vector(31 downto 0); -- output from the MUX

    begin

        PC: register32 Port Map(  --32 bit register
           clk => '1', 
            ld => '1',  
             D => PC_next, 
             Q => PC_Current 
           );

       MUX: mux2to1_32 Port Map(  -- 32 bit multiplexor
          sel => incH_ldL, 
           X0 => PCInput ,
           X1 => PC_add_4,
            Y =>  PC_next 
         );


    PC_add_4 <= (PC_current + 4);

    process (incH_ldL, clk, PC_next, PC_current)
        begin
        if rising_edge(clk) then
            if  (incH_ldL = '0') then
                PC_next <= PCInput;
            else PC_next  <= PC_add_4;
            end if;
        end if; 
        InstrAddr <= PC_current;    
    end process;

end architecture pc_update_arch; 

EDIT Since It seems needed. Here is the code for mux2to1_32 and register32 register32

library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

---------------------------------------------------

entity register32 is port( 
clr: in std_logic; -- async. clear
clk: in std_logic; -- clock
 ld: in std_logic; -- load
  D: in std_logic_vector(31 downto 0); -- data input
  Q: out std_logic_vector(31 downto 0) ); -- data output
end entity register32;

----------------------------------------------------

architecture register32_arch of register32 is

begin 
    process(clk, clr)
    begin
        if clr = '1' then
            q <= x"00000000";
        elsif rising_edge(clk) then
           if ld = '1' then
                q <= d;
           end if;
        end if;
    end process;
END register32_arch;

mux2to1_32

library ieee ;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

---------------------------------------------------

entity mux2to1_32 is
port( sel: in std_logic; -- selection bit input
X0: in std_logic_vector(31 downto 0); -- first input
X1: in std_logic_vector(31 downto 0); -- second input
Y: out std_logic_vector(31 downto 0)); -- output

end entity mux2to1_32;

----------------------------------------------------

architecture mux2to1_32_arch of mux2to1_32 is
begin

    Y <= X1 when (SEL = '1') else X0;

end architecture mux2to1_32_arch; 
1

There are 1 answers

3
QuantumRipple On BEST ANSWER

Your process and the MUX instance do almost the same thing (assuming your mux2to1_32 works as named). The process, however produces a registered output (because it only acts on the clock edge). You need to delete one or the other.

Note that for your process, incH_ldL and PC_next do not need to be in the sensitivity list, because you only look at them when clk has an event (which is already in the sensitivity list). PC_current can taken out as well if Instr_addr <= PC_current is moved out of the process to be a standalone concurrent statement - there is no reason for it to be bundled within the process.

Note also that you haven't assigned the clr port on PC and you assigned clk to '1', which is almost certainly a mistake.

In fact, the components you use are pretty much entirely unnecessary. The whole design could be accomplished with 1 internal signal, a process similar to what you had, and a single concurrent statement:

architecture pc_update_arch of pc_update is
    signal PC : std_logic_vector(31 downto 0):=(others=>'0');
begin
    process (clk)
        begin
        if rising_edge(clk) then
            if  (incH_ldL = '0') then
                PC <= PCInput;
            else
                PC <= PC + 4;
            end if;
        end if; 

    end process;
    InstrAddr <= PC;
end architecture pc_update_arch;

If you do wish to do an implementation with the components, you don't need to describe any logic at all - just the connective signals.