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;
Your process and the
MUX
instance do almost the same thing (assuming yourmux2to1_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
andPC_next
do not need to be in the sensitivity list, because you only look at them whenclk
has an event (which is already in the sensitivity list).PC_current
can taken out as well ifInstr_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 onPC
and you assignedclk
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:
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.