114 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
| ARCHITECTURE RTL OF alu IS
 | |
| 
 | |
|   signal aluCodeInt: unsigned(aluCode'range);
 | |
|   signal aArith: signed(opA'high+1 downto 0);
 | |
|   signal bArith: signed(opA'high+1 downto 0);
 | |
|   signal cInArith: signed(1 downto 0);
 | |
|   signal cInShift: std_ulogic;
 | |
|   signal yArith: signed(aluOut'high+1 downto 0);
 | |
|   signal aluOutInt: signed(aluOut'range);
 | |
| 
 | |
| BEGIN
 | |
|   ------------------------------------------------------------------------------
 | |
|                                       -- clear aluCode don't care LSB for shifts
 | |
|   aluCodeInt(aluCode'high downto 1) <= unsigned(aluCode(aluCode'high downto 1));
 | |
| 
 | |
|   cleanupLsb: process(aluCode)
 | |
|   begin
 | |
|     if aluCode(aluCode'high) = '1' then
 | |
|       aluCodeInt(0) <= '0';
 | |
|     else
 | |
|       aluCodeInt(0) <= aluCode(0);
 | |
|     end if;
 | |
|   end process cleanupLsb;
 | |
| 
 | |
|   ------------------------------------------------------------------------------
 | |
|                                              -- values for arithmetic operations
 | |
|   aArith <= signed(resize(unsigned(opA), aArith'length));
 | |
|   bArith <= signed(resize(unsigned(opB), bArith'length));
 | |
|   cInArith <= (0 => cIn, others => '0');
 | |
| 
 | |
|   process(aluCode, cIn, opA)
 | |
|   begin
 | |
|     case aluCode(2 downto 1) is
 | |
|       when "00"   => cInShift <= cIn;
 | |
|       when "01"   => cInShift <= opA(opA'high);
 | |
|       when "10"   => cInShift <= opA(opA'low);
 | |
|       when "11"   => cInShift <= aluCode(0);
 | |
|       when others => cInShift <= '-';
 | |
|     end case;
 | |
|   end process;
 | |
| 
 | |
|   ------------------------------------------------------------------------------
 | |
|                                                                -- alu operations
 | |
|   aluOperation: process(
 | |
|     aluCodeInt,
 | |
|     opA, opB,
 | |
|     aArith, bArith, cInArith,
 | |
|     cInShift,
 | |
|     yArith, aluOutInt
 | |
|   )
 | |
|     variable xorAcc: std_ulogic;
 | |
|   begin
 | |
|     yArith <= (others => '-');
 | |
|     cOut   <= '-';
 | |
|     aluOutInt <= (others => '-');
 | |
|     case to_integer(aluCodeInt) is
 | |
|       when  0 =>                                        -- LOAD sX, kk
 | |
|         aluOutInt <= opB;
 | |
|       when  2 =>                                        -- INPUT sX, pp
 | |
|         aluOutInt <= opB;
 | |
|       when  3 =>                                        -- FETCH sX, ss
 | |
|         aluOutInt <= opB;
 | |
|       when  5 =>                                        -- AND sX, kk
 | |
|         aluOutInt <= opA and opB;
 | |
|         cOut      <= '0';
 | |
|       when  6 =>                                        -- OR sX, kk
 | |
|         aluOutInt <= opA or opB;
 | |
|         cOut      <= '0';
 | |
|       when  7 =>                                        -- XOR sX, kk
 | |
|         aluOutInt <= opA xor opB;
 | |
|         cOut      <= '0';
 | |
|       when  9 =>                                        -- TEST sX, kk
 | |
|         aluOutInt <= opA and opB;
 | |
|         xorAcc := '0';
 | |
|         for index in aluOutInt'range loop
 | |
|           xorAcc := xorAcc xor aluOutInt(index);
 | |
|         end loop;
 | |
|         cOut      <= xorAcc;
 | |
|       when 10 =>                                        -- COMPARE sX, kk
 | |
|         yArith    <= aArith - bArith;
 | |
|         aluOutInt <= yArith(aluOut'range);
 | |
|         cOut      <= yArith(yArith'high);
 | |
|       when 12 =>                                        -- ADD sX, kk
 | |
|         yArith    <= aArith + bArith;
 | |
|         aluOutInt <= yArith(aluOut'range);
 | |
|         cOut      <= yArith(yArith'high);
 | |
|       when 13 =>                                        -- ADDCY sX, kk
 | |
|         yArith    <= (aArith + bArith) + cInArith;
 | |
|         aluOutInt <= yArith(aluOut'range);
 | |
|         cOut      <= yArith(yArith'high);
 | |
|       when 14 =>                                        -- SUB sX, kk
 | |
|         yArith    <= aArith - bArith;
 | |
|         aluOutInt <= yArith(aluOut'range);
 | |
|         cOut      <= yArith(yArith'high);
 | |
|       when 15 =>                                        -- SUBCY sX, kk
 | |
|         yArith    <= (aArith - bArith) - cInArith;
 | |
|         aluOutInt <= yArith(aluOut'range);
 | |
|         cOut      <= yArith(yArith'high);
 | |
|       when 16 to 23 =>                                  -- SL sX
 | |
|         aluOutInt <= opA(opA'high-1 downto 0) & cInShift;
 | |
|         cOut      <= opA(opA'high);
 | |
|       when 24 to 31 =>                                  -- SR sX
 | |
|         aluOutInt <= cInShift & opA(opA'high downto 1);
 | |
|         cOut      <= opA(0);
 | |
|       when others =>
 | |
|         aluOutInt <= (others => '-');
 | |
|     end case;
 | |
|   end process aluOperation;
 | |
| 
 | |
|   aluOut <= aluOutInt;
 | |
|   zero <= '1' when aluOutInt = 0 else '0';
 | |
| 
 | |
| END ARCHITECTURE RTL;
 |