I am trying to make a 4 bit multiplier. Here is my top level design:
And here are the two modules:
However when I try to simulate this I get no output. My testbench:
ARCHITECTURE behavior OF sim3 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT multiplicator
PORT(
a : IN std_logic_vector(3 downto 0);
b : IN std_logic_vector(3 downto 0);
reset : IN std_logic;
clk : IN std_logic;
start : IN std_logic;
prod : OUT std_logic_vector(7 downto 0);
ready : OUT std_logic
);
END COMPONENT;
--Inputs
signal a : std_logic_vector(3 downto 0) := (others => '0');
signal b : std_logic_vector(3 downto 0) := (others => '0');
signal reset : std_logic := '0';
signal clk : std_logic := '0';
signal start : std_logic := '0';
--Outputs
signal prod : std_logic_vector(7 downto 0);
signal ready : std_logic;
-- Clock period definitions
constant clk_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: multiplicator PORT MAP (
a => a,
b => b,
reset => reset,
clk => clk,
start => start,
prod => prod,
ready => ready
);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for clk_period;
reset<='1';
wait for clk_period;
reset<='0';
a<="0011";
b<="0010";
start <='1';
wait for clk_period*10;
end process;
END;
When I am setting the start to '1' the simulation just stops. I don't know why. I get the folowing error:
ERROR: at 20 ns(10000): Iteration limit 10000 is reached. Possible zero delay oscillation detected where simulation can not advance in time because signals can not resolve to a stable value in File "D:/faculta/PL II/multiplicator/reg8.vhd" Line 45. Please correct this code in order to advance past the current simulation time.
I don't see what could be wrong at that line:
q_s <= "00000000" WHEN reset='1' ELSE d WHEN reset='0' and load='1' ELSE q_s;
Some help please?
Don't use a register with a load enable, use clock edge register. The iteration limit is a delta cycle limit in ISIM. Introducing a '1' in b
you get a striking oscillator, a loop with delta cycle delays and inversion (the summing). Make num4, reg4 and reg8 clock edge driven with their loads as enables, this appears compatible with Lab10 which shows the use of a clock (and the VHDL source for @scary_jeff, albeit expressed in type BIT instead of std_logic). This feedback phenomenon is mentioned in William Kafig's book VHDL 101 Everything you need to know to get started, in Chapter 4.
Google Translate helps. No one ever seems to provide their handouts for their assignments.
If you look at the original implementation of assignment to q_s
in reg4
:
block1:
block (ck = '1' and not ck'stable)
begin
q_s <= guarded "0000" when reset = '1' else
d when reset = '0' and load = '1' else
q_s;
end block block1;
I'd translate this into a synthesizable process statement instead of a block statement, making in clear reg4
(and reg8
) is a clocked register:
block1:
process (ck)
begin
if rising_edge(ck) then
if reset = '1' then
q_s <= (others => '0');
elsif load = '1' then
q_s <= d;
end if;
end if;
end process;
The reason the original works is because a block statement can have a guard statement.
The change makes it clear the q_s
is a clocked register with a synchronous reset.
You also might note we no longer reference q_s
and can assign q directly.
In the control state machine the process assigning next_state
to current_state
can likewise be updated:
process (ck)
begin
if ck'event and ck = '1' then -- or rising_edge(ck)
current_state <= next_state;
end if;
end process;
Simply for readability. It's uncommon to use the form not ck'stable
for signifying a clock event, noting you also appear to have missed the implication in implementing reg8
, potentially in reg4
and automat
as well.
The synthesis eligibility of a guarded expression as an edge sensitive clock is demonstrated in IEEE Std 1076.6-2004, 6.1.3.6 Edge-sensitive storage using a guarded block.