I designed a circuit composed of a register and an incrementer. Each one is supposed to feed the input of the other, resulting in the PC being incremented by 4 on each rising edge of the clock. The code is show below:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity Register1 is
port (
CLK : in STD_LOGIC;
d : in STD_LOGIC_VECTOR(31 downto 0);
q : out STD_LOGIC_VECTOR(31 downto 0)
);
end;
architecture Behavioral of Register1 is
begin
process (CLK)
begin
if rising_edge(CLK) then
q <= d;
end if;
end process;
end;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
entity Incrementer is
port (
din : in STD_LOGIC_VECTOR(31 downto 0);
dout : out STD_LOGIC_VECTOR(31 downto 0)
);
end;
architecture DataFLow of Incrementer is
begin
dout <= STD_LOGIC_VECTOR(UNSIGNED(din) + 4);
end;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity Test is
end Test;
architecture Struct of Test is
component Register1 is
port (
CLK : in STD_LOGIC;
d : in STD_LOGIC_VECTOR(31 downto 0);
q : out STD_LOGIC_VECTOR(31 downto 0)
);
end component;
component Incrementer is
port (
din : in STD_LOGIC_VECTOR(31 downto 0);
dout : out STD_LOGIC_VECTOR(31 downto 0)
);
end component;
signal CLK : STD_LOGIC := '0';
signal PCN : STD_LOGIC_VECTOR(31 downto 0) := (others => '0');
signal PC : STD_LOGIC_VECTOR(31 downto 0) := (others => '0');
constant CLK_period: TIME := 10 ns;
begin
-- The concurent clock signal
CLK <= not CLK after CLK_period/2;
PCreg: Register1 port map (
CLK,
d => PCN,
q => PC
);
Incr1: Incrementer port map (
din => PC,
dout => PCN
);
-- The stimulus process
verify: process
begin
wait for 80 ns;
end process;
end;
However the relevant signals (PC, PCN) are shown with "X" in my simulator (vivado). What am I doing wrong?
The problem is, you do not initialize the signal q of the register1 module. So at simulation start q has the value 'U' (unassigned). When you add 1 to 'U' a 'X' results. So you must initialize q. This is often done by a synchronous or asynchronous reset signal or by a signal definition with initialization statement, which resets all storing elements in your design to a value different from 'U'. So with a asynchronous reset signal your code would look like:
process (RESET, CLK)
begin
if RESET='1' then
q <= (others => '0');
elsif rising_edge(CLK) then
q <= d;
end if;
end process;