[SOLVED] VHDL multiple processes with assignments

Status
Not open for further replies.

Adam Hussey

Junior Member level 3
Joined
Sep 28, 2013
Messages
25
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
276
Hi,
Sorry I know this is my first post, but I have been working on this assignment now for months, with no previous experience in VHDL what so ever.

Long story short, I am trying to design a simple 16bit ALU in vhdl. My instructor said we need 2 different architectures: behavioral and RTL. They both need to run concurrently when simulating.

To make things easier, I'll just post the code for both.

Code:
 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use std.textio.all;          

entity simple_alu is
port(   Clk, Res : in std_logic; --clock signal
        A,B : in signed(15 downto 0); --input operands
        Op : in unsigned(2 downto 0); --Operation to be performed
        R : out signed(31 downto 0)  --output of ALU
        );
end simple_alu;

architecture Behavioral of simple_alu is

--temporary signal declaration.
Signal overflow: bit:='0';
signal Reg1,Reg2 : signed(15 downto 0) := (others => '0');
signal Reg3 : signed(31 downto 0) := (others => '0');

begin

 Reg1 <= A ;
 Reg2 <= B ;

ALU_Exec: process(Clk, Res)
begin

    if(Res='1' and clk'event and clk='1') then --Do the calculation at the positive edge of clock cycle.
        case Op is
            when "000" =>
                Reg3(15 downto 0) <= Reg1 + Reg2;  --addition
				if Reg3>16#FFFF# then
					overflow<='1';
				end if;
            when "001" =>
                Reg3(15 downto 0) <= Reg1 - Reg2; --subtraction
            when "010" =>
                Reg3(15 downto 0) <= not Reg1;  	--NOT gate
            when "011" =>
                Reg3 <= Reg1 * Reg2; 				--MPY
            when "100" =>
                if (Reg1 < Reg2) then 				--COMP
					Reg3(2 downto 0) <="001"; 	  --less than returns 1				
				elsif (Reg1 = Reg2) then
					Reg3(2 downto 0) <="000";
				else Reg3(2 downto 0) <="010";
				end if;		
            when "101" =>
                Reg3(15 downto 0) <= Reg1 and Reg2;  --AND gate
            when "110" =>
                Reg3(15 downto 0) <= Reg1 or Reg2;  --OR gate   
            when "111" =>
                Reg3(15 downto 0) <= Reg1 xor Reg2; --XOR gate  
            when others =>
                NULL;
        end case;      
    end if;

end process;   
    R <= Reg3;

end Behavioral;

architecture RTL of simple_alu is
Signal overflow: bit:='0';
signal RReg1,RReg2 : signed(15 downto 0) := (others => '0');
signal C : signed(16 downto 0) := (others => '0');
signal RReg3 : signed(31 downto 0) := (others => '0');

begin
--
RReg1 <= A;
RReg2 <= B;
--
ALU_RTL_Exec: process(Clk, Res)
begin
  

    if(Res='0' and clk'event and clk='1') then --Do the calculation at the positive edge of clock cycle.
		case Op is
		        when "000"=> for I in 0 to 15 loop		--addition
                    RReg3(I) <= RReg1(I) XOR RReg2(I) XOR C(I);
                    C(I+1) <= RReg1(I) and RReg2(I) and C(I);
                end loop;
					if RReg3>16#FFFF# then
					 overflow<='1';
					end if;
				when "001"=> RReg2<= not RReg2; C(0) <='1';	--subtraction
                   for I in 0 to 15 loop
                      RReg3(I)   <= RReg1(I) XOR RReg2(I) XOR C(I);
                      C(I+1) <= RReg1(I) and RReg2(I) and C(I);
                     end loop;
					if RReg3>16#FFFF# then
					 overflow<='1';
					end if;
				when "010"=> for I in 0 to 15 loop	--Not gate of RReg2
                    RReg3(I) <= not RReg2(I);
                  end loop;
					 
				when "011"=> for I in 0 to 15 loop			--Multiplication
					C <= "00000000000000001";
					while (RReg2 /= "0000000000000000") loop					--loop til RReg2=>0
					  if ((RReg2 and C(15 downto 0)) = "0000000000000001") then	-- bitwise and of RReg2 and 01
					    RReg3 <= RReg3+RReg1;					--add a to result if RReg2 is odd
					  end if;
					  RReg1 <= RReg1 sll 1;			
					  RReg2 <= RReg2 srl 1;
					end loop;
				end loop;	
				
				when "100"=> for I in 0 to 15 loop			--Compare
					RReg3(I) <= RReg1(I) xor RReg2(I); 
				  end loop;
				  if (RReg3(15 downto 0) /= "000000000000000") then
				    for I in 15 downto 0 loop
					  RReg3(I) <= RReg1(I) xor RReg2(I);
					  if (RReg3(I) /= '0') then
					    RReg3(1) <= RReg1(I);
						RReg3(0) <= RReg2(I);
						exit;
					  end if;
					end loop;
				  end if;  
					
				
				when "101"=> for I in 0 to 15 loop			--AND OP
				  RReg3(I)   <= RReg1(I) and RReg2(I);
				end loop;
				
				when "110" => for I in 0 to 15 loop			--OR OP
				  RReg3(I)   <= RReg1(I) or RReg2(I);
				end loop;
				
				when "111" => for I in 0 to 15 loop			-- XOR OP
				  RReg3(I)   <= RReg1(I) xor RReg2(I);
				end loop;
				
				when others =>
                NULL;	
	  end case;		  
	end if;
  R <= RReg3;	
  end process;
end architecture RTL;

The problem comes in the second process (RTL). I am unable to assign any values to the signals (RREG, RREG2) without getting X's. I have even tried explicitly assigning all 0s to them (instead of the values of A, B) unsuccessfully.

I am guessing it has something to do with clock cycles, but I thought I tried running them on different cycles.

I am completely exhausted from trying everything. I am beyond frustrated on figuring this out. I know very little about this language and that makes it very hard to do this assignment.

I would be very grateful if anyone could help me get this to simulate properly.
Huge thanks in advance.
 

To be perfectly honest, I don't quite understand the significance of "rtl" or "behavioral" designs, and I've been doing FPGA design for years. I think it's something professors like to confuse you with. I'm probably just showing my ignorance.

But back to your problem: one thing that stands out is your statement: "Res='0' and clk'event and clk='1' ". That's bad form (it's a 'gated clock'). Think about what happens when the RES part of that statement is false: what happens to everything? It's undefined.

If you are trying to create a synchronous reset, you should do something like this:

Code:
process(clk)
begin
        if clk='1' and clk'event then
                  if res='1'then
                          --reset stuff here
                 else
                         --clocked stuff here.
                 end if;
       end if;

The other thing that I'm noticing is that in your first architecture res is active low, in the second one, it's active high. Is that what you wanted?
 


Thanks, I'll look into fixing the reset once I get everything working lol.
Ah yes I actually did that to the reset to try to bypass doing a process to see if the problem still occurred, and it did.
 

Your problem is probably in that loop. You are using the value of C in the calculation of RREG3, and I don't see where C is initialized. Thus, the undefined value. You should probably run a simulation and observe what your intermediate values are.
 

Your problem is probably in that loop. You are using the value of C in the calculation of RREG3, and I don't see where C is initialized. Thus, the undefined value. You should probably run a simulation and observe what your intermediate values are.

Unfortunately I have run many simulations trying to debug this stupid thing. RReg3 actually isn't the register with the problems. RREG1 and RREG2 are.

I can give details of the simulation, just tell me what you want to know.
 

if the problems are with RReg 1 and 2, then the problem is external to the block, as they are connected to the A and B input.
 

if the problems are with RReg 1 and 2, then the problem is external to the block, as they are connected to the A and B input.

Can you elaborate on this? I have tried connecting them to direct values of "0000000000000000" and still getting errors.
 

RREG1 is getting assigned values in TWO PLACES, outside the process and inside the process. That's a big nono.

I do something similar with Reg1 in the first process and everything works, though?
 

In the first process Reg1 is only assigned outside the process. In the 2nd RReg1 is assigned inside and outside the process. You cant do this, as they could both be driving different things (hence why you get 'X')
 

In the first process Reg1 is only assigned outside the process. In the 2nd RReg1 is assigned inside and outside the process. You cant do this, as they could both be driving different things (hence why you get 'X')

I see. I'll try to figure out what I can do and see if it works.

EDIT: That did it! After several weeks of headaches, I can finally proceed to finish this.

HUGE thanks to everyone for helping!
 
Last edited:

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…