Question

I have a project where i am supposed to develop a RISC microprocessor . this involves creating an ALU in behavioral model . however there seems to be problems/errors/warnings while simulating the design . most of the operations work properly except following :

COMPARING THE 2 INPUTS : when numbers are equal , zero flag is not getting set . ( unequal numbers are working properly ) .

Warning: There is an 'U'|'X'|'W'|'Z'|'-' in an arithmetic operand, the result will be 'X'(es).

( this appears every 1 ps , presumably due to the wait statement in the process )

I Wish to work with std_logic_vector, even though i read that they are very messy .

also, there is a problem when i try to use comparing commands ( which update the flags but dont store the difference in the output register ) . How are if commands executed in VHDL ?? are they executed at the same time ?? or line by line ??

CODE BELOW :

   LIBRARY IEEE;  
USE IEEE.STD_LOGIC_1164.ALL;  
USE IEEE.STD_LOGIC_ARITH.ALL;  
USE IEEE.STD_LOGIC_UNSIGNED.ALL; 

ENTITY ALU IS
  PORT(
      INPUT1 , INPUT2: IN STD_LOGIC_VECTOR(7 DOWNTO 0 ) ; 
      CARRYIN : IN STD_LOGIC ; 
       ZERO,CARRYOUT : OUT STD_LOGIC ; 
       OUTPUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0 ) ; 
       CONTROL : IN STD_LOGIC_VECTOR(7 DOWNTO 0 )  
        ) ; 
END ALU ; 

ARCHITECTURE OPERATION OF ALU IS
SIGNAL TMP : STD_LOGIC_VECTOR( 8 DOWNTO 0 ) ; 
BEGIN
PROCESS
BEGIN
  IF( CONTROL = "00110000" OR CONTROL(7 DOWNTO 3 )  = "00001" ) THEN TMP <= CARRYIN & ( INPUT1 AND INPUT2 ) ;
  ELSIF( CONTROL(7 DOWNTO 3 ) = "00010" ) THEN TMP <= CARRYIN & ( INPUT1 OR INPUT2 ) ;
  ELSIF( CONTROL(7 DOWNTO 3 ) = "00011" ) THEN TMP <= CARRYIN & ( INPUT1 XOR INPUT2 ) ;
  ELSIF( CONTROL(7 DOWNTO 3 ) = "00100" ) THEN TMP <= CONV_STD_LOGIC_VECTOR(  ( CONV_INTEGER(INPUT1)+1 ) , 9 ) ; 
  ELSIF( CONTROL(7 DOWNTO 3 ) = "00101" ) THEN TMP <= CONV_STD_LOGIC_VECTOR(  ( CONV_INTEGER(INPUT1)-1 ) , 9 ) ; 
  ELSIF( CONTROL = "10001100" ) THEN TMP <= '0' & (NOT INPUT1) ; 
  ELSIF( CONTROL(7 DOWNTO 3 ) = "11000" OR CONTROL(7 DOWNTO 2 ) = "110010" OR CONTROL = "110-11--" ) THEN TMP <= CONV_STD_LOGIC_VECTOR(  ( CONV_INTEGER(INPUT1)+CONV_INTEGER(INPUT2) ) , 9 ) ; 
  ELSIF( CONTROL(7 DOWNTO 3 ) = "11100" OR CONTROL(7 DOWNTO 2 ) = "111010" OR CONTROL = "111-11--" OR CONTROL(7 DOWNTO 3 ) = "00000" OR CONTROL = "00111000" ) THEN TMP <= CONV_STD_LOGIC_VECTOR(  ( CONV_INTEGER(INPUT1)-CONV_INTEGER(INPUT2) ) , 9 ) ; 
  ELSIF( CONTROL(7 DOWNTO 3 ) = "11010" OR CONTROL(7 DOWNTO 2 ) = "110110" ) THEN TMP <= CONV_STD_LOGIC_VECTOR(  ( CONV_INTEGER(INPUT1)+CONV_INTEGER(INPUT2)+CONV_INTEGER(CARRYIN) ) , 9 ) ;
  ELSIF( CONTROL(7 DOWNTO 3 ) = "11110" OR CONTROL(7 DOWNTO 2 ) = "111110" ) THEN TMP <= CONV_STD_LOGIC_VECTOR(  ( CONV_INTEGER(INPUT1)-CONV_INTEGER(INPUT2)-CONV_INTEGER(CARRYIN) ) , 9 ) ;
  END IF ;
  IF ( TMP( 7 DOWNTO 0 ) = "00000000" ) THEN ZERO <= '1' ;
  ELSE ZERO <= '0' ;    
    END IF ; 
      IF( CONTROL(7 DOWNTO 3 ) = "00000" OR CONTROL = "00111000" ) THEN
      TMP( 7 DOWNTO 0 ) <= INPUT1 ; 
      END IF ;
      OUTPUT <= TMP( 7 DOWNTO 0 ) ; 
    CARRYOUT <= TMP(8) ;
      WAIT FOR 1 PS;
END PROCESS ; 
END OPERATION ; 

testbench code

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;


ENTITY test_tb IS
END test_tb;

ARCHITECTURE behavior OF test_tb IS
   COMPONENT ALU
  PORT(
      INPUT1 , INPUT2: IN STD_LOGIC_VECTOR(7 DOWNTO 0 ) ; 
      CARRYIN : IN STD_LOGIC ; 
       ZERO,CARRYOUT : OUT STD_LOGIC ; 
       OUTPUT : OUT STD_LOGIC_VECTOR(7 DOWNTO 0 ) ; 
       CONTROL : IN STD_LOGIC_VECTOR(7 DOWNTO 0 )  
        ) ; 
END COMPONENT ; 


   signal i1,i2,ctrl,opt : std_logic_vector(7 downto 0 ) := "00000000" ;
   signal cin,cout,zero : std_logic := '0';


BEGIN


   uut: alu PORT MAP ( i1,i2,cin,zero,cout,opt,ctrl ) ;


  stim_proc: process
   begin        

        i1 <= "10000000" ; 
        i2 <= "10000000" ; 
        ctrl <= "11011010" ; 
        cin <= '0' ; 
        wait for 5 ps;
        ctrl <= "00111000" ; 
        wait for 5 ps ; 
        wait;
  end process;

END;
Was it helpful?

Solution

Unfortunately, this piece of code doesn't do what you expect:

CONTROL = "111-11--"

It actually compares CONTROL to see if it has the 4th, 6th and 7th bits set to -, rather than using them as "don't care" matches! Mind-boggling, but that's the way it's been specified to work for years :(

What you want is

 std_match(CONTROL, "111-11--")

Which will do a don't-care comparison like you expect.

OTHER TIPS

the problem lies in the statements of the form CONTROL = "111-11--" and the way how 'U'|'X'|'W'|'Z'|'-' are treated in the library functions you use.

  1. CONTROL = "111-11--" calls the '=' function from std_logic_unsigned (comparing two std_logic_vectors)...
  2. this calls the '=' function from std_logic_arith (comparing two unsigned values)...
  3. this calls CONV_UNSIGNED from std_logic_arith...
  4. and this calls MAKE_BINARY from std_logic_arith...
  5. and this function, finally, checks whether a bit is set to 'U'|'X'|'W'|'Z'|'-'. if so, it gives the warning you see

--> short message of long answer: avoid using 'U'|'X'|'W'|'Z'|'-'. use explicit comparison of '0' and '1' bits instead

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top