[SOLVED] Problem with output (output changes when it is not supposed to)

Status
Not open for further replies.

sarjumaharaj

Junior Member level 1
Joined
Mar 2, 2014
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
148
hey,
I'm designing shift and add multiplier using controller datapath method. Here is the design of the circuit Shift And ADD DESIGN. I'm Making the Q from the design. Basically it's a register which stores the multiplier and shifts the value to the right when a value from product is shifted through the datapath.

I made the design in vhdl and it seems to be working but there is a slight problem. In the tb each clock cycle i made of 100 ns. So within the hunderd nanosecond the product does over 20 shifts due to which my value of multiplier (value stored in Q) becomes erroneous.

I tried adding the shift in the process so each time the value of shift is changed the process is initiated but still the output constantly changes over the period of 100ns and becomes wrong. Does any one know how to fix it.

Here is the code:
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity q_multiplier is
	port ( a0 , clk, shift , ini : in std_logic ; 
			 mul: in std_logic_vector ( 4 downto 1); 
			 q0 : out std_logic ;
			 temp_out : out std_logic_vector (4 downto 1)
		   ); 
end q_multiplier ; 

architecture Behavioral of q_multiplier is
signal temp : std_logic_vector (4 downto 1); 
signal temp_ini : std_logic ; 
signal temp_shift : std_logic ; 

begin 
process (clk ,shift ,ini) 
begin 

temp_ini <= ini ; 
temp_shift <= shift ; 

	if (clk = '1' and rising_edge(clk)) then 
		
		if ( temp_ini = '1') then 
			temp <= mul; 
		end if ;
		
		if ( temp_shift = '1' ) then
			for i in 3 downto 1 loop 
				temp(4-i) <= temp(5- i); 
			end loop ;
			temp(4) <= a0; 
		end if ; 
		
		temp_out <= temp; 
		q0 <= temp(4);
end if ; 
		
end process ;
end Behavioral;
--

TEST BENCH INPUT
Code:
    wait for 100 ns;	
		a0 <= '1';
		shift <='0';
		ini <= '1' ;
  	   mul<= "1010"; 

		wait for 100 ns;	
		a0 <= '1';
		shift <='1';
		ini <= '0' ;
  	   mul<= "1010";
		
		wait for 100 ns;	
		a0 <= '1';
		shift <='0';
Here are 2 pictures of the waverform. Second one is just zoomed in 
[ATTACH=CONFIG]103037._xfImport[/ATTACH][ATTACH=CONFIG]103038._xfImport[/ATTACH]
 

you have not given any value for clock

wait for 100 ns doesnt means clk will change after 100ns.
clk is just an input.

try this


initial
begin
clk<='0'
end

always
begin
clk=~clk
wait for 50ns
end

this is based on verilog coding check for the variation in vhdl
 

nikhilna007 that is only part of the test bench. Complete testbench has that code too . Here is the whole code.
Code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

 
ENTITY tb IS
END tb;
 
ARCHITECTURE behavior OF tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT q_multiplier
    PORT(
         a0 : IN  std_logic;
         clk : IN  std_logic;
         shift : IN  std_logic;
         ini : IN  std_logic;
         mul : IN  std_logic_vector(4 downto 1);
         q0 : OUT  std_logic;
         temp_out : OUT  std_logic_vector(4 downto 1)
        );
    END COMPONENT;
    

   --Inputs
   signal a0 : std_logic := '0';
   signal clk : std_logic := '0';
   signal shift : std_logic := '0';
   signal ini : std_logic := '0';
   signal mul : std_logic_vector(4 downto 1) := (others => '0');

 	--Outputs
   signal q0 : std_logic;
   signal temp_out : std_logic_vector(4 downto 1);

   -- Clock period definitions
   constant clk_period : time := 10 ns;
 
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: q_multiplier PORT MAP (
          a0 => a0,
          clk => clk,
          shift => shift,
          ini => ini,
          mul => mul,
          q0 => q0,
          temp_out => temp_out
        );

   -- 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		
      -- hold reset state for 100 ns.
      wait for 100 ns;	
		a0 <= '1';
		shift <='0';
		ini <= '1' ;
  	   mul<= "1010"; 

		wait for 100 ns;	
		a0 <= '1';
		shift <='1';
		ini <= '0' ;
  	   mul<= "1010";
		
		wait for 100 ns;	
		a0 <= '1';
		shift <='0';
		ini <= '0' ;
  	   mul<= "1010";
		

      wait for clk_period*10;

      -- insert stimulus here 

      wait;
   end process;

END;
 

Heres your culprit:

if (clk = '1' and rising_edge(clk)) then

This situation can never happen. Think about why.....
 

Heres your culprit:

if (clk = '1' and rising_edge(clk)) then

This situation can never happen. Think about why.....

That looks like inbreeding between
if (clk ='1' and clk'event) then

and

if (rising_edge(clk)) then

;-)
 

does rising_edge mean that the clk isn't at 1 stage but between 0 and 1 ?
 

yup. The clue is in the name. a rising edge is a change from '0' to '1'. a falling edge is change from '1' to '0'. Hence '1' and rising_edge cannot occur on the same signal at the same time.
 

Although I agree to this conclusion if we are going to hardware synthesis, the simulator seems to have a different opinion about it as you see in the post #1 waveform. temp is shifted on each 100 MHz clock edge.

I'm generally unable to detect any incorrect design behaviour at first sight.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…