⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.vhd

📁 8位CPU的VHDL设计,16条指令系统,以及部分测试代码,开发工具是quartusii_60_pc
💻 VHD
字号:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;			

PACKAGE c_define IS		
	CONSTANT idle  : std_logic_vector(3 DOWNTO 0) := "0000";
	CONSTANT load  : std_logic_vector(3 DOWNTO 0) := "0001";
	CONSTANT move  : std_logic_vector(3 DOWNTO 0) := "0010";
	CONSTANT addP  : std_logic_vector(3 DOWNTO 0) := "0011";
	CONSTANT subp  : std_logic_vector(3 DOWNTO 0) := "0100";
	CONSTANT andp  : std_logic_vector(3 DOWNTO 0) := "0101";
	CONSTANT orp   : std_logic_vector(3 DOWNTO 0) := "0110";
	CONSTANT xorp  : std_logic_vector(3 DOWNTO 0) := "0111";
	CONSTANT shrp  : std_logic_vector(3 DOWNTO 0) := "1000";
	CONSTANT shlp  : std_logic_vector(3 DOWNTO 0) := "1001";
	CONSTANT swap  : std_logic_vector(3 DOWNTO 0) := "1010";
	CONSTANT jmp   : std_logic_vector(3 DOWNTO 0) := "1011";
	CONSTANT jz    : std_logic_vector(3 DOWNTO 0) := "1100";
	CONSTANT read  : std_logic_vector(3 DOWNTO 0) := "1101";
	CONSTANT write : std_logic_vector(3 DOWNTO 0) := "1110";
	CONSTANT stop  : std_logic_vector(3 DOWNTO 0) := "1111";
	
END c_define;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use work.c_define.all;

entity cpu is
   port( reset: in std_logic;
         clock: in std_logic;
         M_address:  out std_logic_vector(11 downto 0);
         M_data_in:  in  std_logic_vector(7 downto 0);
         M_data_out: out std_logic_vector(7 downto 0);
         Write_Read: out std_logic;
         Overflow:   out std_logic;
         R0out,R1out,R2out,R3out:out std_logic_vector(7 downto 0);
         PCout:      out std_logic_vector(11 downto 0);
         OPout:      out std_logic_vector(3downto 0);
         status:     out integer range 0 to 6
        );
end cpu;

architecture cpu_behavor of cpu is

signal op: std_logic_vector(3 DOWNTO 0); 
signal R0,R1,R2,R3,A,MDR: std_logic_vector(7 downto 0);
signal IR: std_logic_vector(15 downto 0);
signal over0,over1: std_logic_vector(8 downto 0);
signal MAR,PC: std_logic_vector(11 downto 0);
signal present_state,next_state: integer range 0 to 6;

begin         
  
  process(reset,clock,present_state,IR(15 downto 12))
   
  begin
       op <= IR(15 downto 12);
     if reset = '0' then
       present_state <= 0;
       next_state <= 0;
       A   <= "00000000";
       R0  <= "00000000";
       R1  <= "00000000";
       R2  <= "00000000";
       R3  <= "00000000";
       IR  <= "0000000000000000";
       PC  <= "000000000000";
       MAR <= "000000000000";
       MDR <= "00000000";
            
     elsif clock'event and clock = '1' then
       
 case present_state is

 when 0 =>

          IR(15 downto 8) <= M_data_in;
          next_state <= 1;
          PC <= PC + 1;

 when 1 =>
             MAR <= PC;

          if op = stop then
             next_state <= 1;
          else
             next_state <= 2;
          end if;
          
          if op = load then
             R0 <= "0000" & IR(11 downto 8);
          
          elsif op = move then
       case IR(11 downto 8) is
         when "0000" =>
           NULL;
         when "0001" =>
           R0 <= R1;
         when "0010" =>
           R0 <= R2;
         when "0011" =>
           R0 <= R3;
         when "0100" =>
           R1 <= R0;
         when "0101" =>
           NULL;
         when "0110" =>
           R1 <= R2;
         when "0111" =>
           R1 <= R3;
         when "1000" =>
           R2 <= R0;
         when "1001" =>
           R2 <= R1;
         when "1010" =>
           NULL;
         when "1011" =>
           R2 <= R3;
         when "1100" =>
           R3 <= R0;
         when "1101" =>
           R3 <= R1;
         when "1110" =>
           R3 <= R2;
         when "1111" =>
           NULL;
       end case;

          elsif op = shrp then
       case IR(11 downto 10) is
         when "00" =>
           R0<= ('0' & R0(7 downto 1));
         when "01" =>
           R1<= ('0' & R1(7 downto 1));
         when "10" =>
           R2<= ('0' & R2(7 downto 1));
         when "11" =>
           R3<= ('0' & R3(7 downto 1));
       end case;

          elsif op = shlp then
       case IR(11 downto 10) is
         when "00" =>
           R0 <= (R0(6 downto 0) & '0');
         when "01" =>
           R1 <= (R1(6 downto 0) & '0');
         when "10" =>
           R2 <= (R2(6 downto 0) & '0');
         when "11" =>
           R3 <= (R3(6 downto 0) & '0');
       end case;
           
          elsif op = addp or op = subp or op = andp or op = orp or op = xorp or op = swap then
       
       case IR( 9 downto 8 ) is
         when "00" =>
           A<= R0;
         when "01" =>
           A<= R1; 
         when "10" =>
           A<= R2; 
         when "11" =>
           A<= R3; 
       end case;
             
         else
             null;
         end if;   
 when 2 =>
          if op = swap or op = jmp or op = jz or op = write or op = read then
		     next_state <= 3;
		  else
		     next_state <= 0;
		  end if;
		
          --if op = idle or op = load or op = move  or op = shrp or op = shlp or op = stop then
             --null; 

          if op = addp then
        case IR(11 downto 10) is
         when "00" =>
             --over0(7 downto 0) <= A;
		     --over0(8) <= A(7);
             --over1(7 downto 0) <= R0;
             --over1(8) <= R0(7);
             --over1 <= over0 + over1;
             --R0 <= over1(7 downto 0);
             --if over1(7) /= over1(8) then
                --Overflow <= '1';
             --else
                --Overflow <= '0';
             --end if;
             R0 <= R0 + A;
         when "01" =>
             over0(7 downto 0) <= A;
		     over0(8) <= A(7);
             over1(7 downto 0) <= R1;
             over1(8) <= R1(7);
             over1 <= over0 + over1;
             R1 <= over1(7 downto 0);
             if over1(7) /= over1(8) then
                Overflow <= '1';
             else
                Overflow <= '0';
             end if;
         when "10" =>
             over0(7 downto 0) <= A;
		     over0(8) <= A(7);
             over1(7 downto 0) <= R2;
             over1(8) <= R2(7);
             over1 <= over0 + over1;
             R2 <= over1(7 downto 0);
             if over1(7) /= over1(8) then
                Overflow <= '1';
             else
                Overflow <= '0';
             end if;
         when "11" =>
             over0(7 downto 0) <= A;
		     over0(8) <= A(7);
             over1(7 downto 0) <= R3;
             over1(8) <= R3(7);
             over1 <= over0 + over1;
             R3 <= over1(7 downto 0);
             if over1(7) /= over1(8) then
                Overflow <= '1';
             else
                Overflow <= '0';
             end if;
       end case;
             
          elsif op = subp then
       case IR(11 downto 10) is
          when "00" =>
             --over0(7 downto 0) <= A;
		     --over0(8) <= A(7);
             --over1(7 downto 0) <= R0;
             --over1(8) <= R0(7);
             --over1 <= over1 - over0;
             --R0 <= over1(7 downto 0);
             --if over1(7) /= over1(8) then
                --Overflow <= '1';
             --else
                --Overflow <= '0';
             --end if;
             R0 <= R0 - A;
         when "01" =>
             over0(7 downto 0) <= A;
		     over0(8) <= A(7);
             over1(7 downto 0) <= R1;
             over1(8) <= R1(7);
             over1 <= over1 - over0;
             R1 <= over1(7 downto 0);
             if over1(7) /= over1(8) then
                Overflow <= '1';
             else
                Overflow <= '0';
             end if;
         when "10" =>
             over0(7 downto 0) <= A;
		     over0(8) <= A(7);
             over1(7 downto 0) <= R2;
             over1(8) <= R2(7);
             over1 <= over1 - over0;
             R2 <= over1(7 downto 0);
             if over1(7) /= over1(8) then
                Overflow <= '1';
             else
                Overflow <= '0';
             end if;
         when "11" =>
             over0(7 downto 0) <= A;
		     over0(8) <= A(7);
             over1(7 downto 0) <= R3;
             over1(8) <= R3(7);
             over1 <= over1 - over0;
             R3 <= over1(7 downto 0);
             if over1(7) /= over1(8) then
                Overflow <= '1';
             else
                Overflow <= '0';
             end if;
       end case;
             
          elsif op = andp then
       case IR(11 downto 10) is
         when "00" =>
           R0 <= (R0) and (A);
         when "01" =>
           R1 <= (R1) and (A);
         when "10" =>
           R2 <= (R2) and (A);
         when "11" =>
           R3 <= (R3) and (A);
       end case;   
   
          elsif op = orp then
       case IR(11 downto 10) is
         when "00" =>
           R0 <= (R0) or (A);
         when "01" =>
           R1 <= (R1) or (A);
         when "10" =>
           R2 <= (R2) or (A);
         when "11" =>
           R3 <= (R3) or (A);
       end case;  
     
          elsif op = xorp then
       case IR(11 downto 10) is
         when "00" =>
           R0 <= (R0) xor (A);
         when "01" =>
           R1 <= (R1) xor (A);
         when "10" =>
           R2 <= (R2) xor (A);
         when "11" =>
           R3 <= (R3) xor (A);
       end case; 
      
          elsif op = swap then
       case IR(11 downto 8) is
         when "0000" =>
           NULL;
         when "0001" =>
           R1 <= R0;
         when "0010" =>
           R2 <= R0;
         when "0011" =>
           R3 <= R0;
         when "0100" =>
           R0 <= R1;
         when "0101" =>
           NULL;
         when "0110" =>
           R2 <= R1;
         when "0111" =>
           R3 <= R1;
         when "1000" =>
           R0 <= R2;
         when "1001" =>
           R1 <= R2;
         when "1010" =>
           NULL;
         when "1011" =>
           R3 <= R2;
         when "1100" =>
           R0 <= R3;
         when "1101" =>
           R1 <= R3;
         when "1110" =>
           R2 <= R3;
         when "1111" =>
           NULL;
       end case;
          else --if op = read or op = jmp or op = jz  or op = write then
             null;
          end if;
 when 3 =>

          if op = swap then
       case IR( 11 downto 10 ) is
          when "00" =>
             R0<= A;
          when "01" =>
             R1<= A; 
          when "10" =>
             R2<= A; 
          when "11" =>
             R3<= A; 
       end case;      
             next_state <= 0;
          elsif op = read or op = jmp or op = jz  or op = write then
             IR(7 downto 0) <= M_data_in;
             PC <= PC + 1;
             next_state <= 4;
          end if;
 when 4 =>
          next_state <= 5; 
          if op = read then
             MAR <= IR(11 downto 0); 
          elsif op = write then
             MAR <= IR(11 downto 0);
             MDR <= R0; 
          elsif op =jmp  then
             PC  <= IR(11 downto 0);
             MAR <= IR(11 downto 0);
          elsif op = jz then
            if  R0 = "00000000" then
                PC  <= IR(11 downto 0);
                MAR <= IR(11 downto 0); 
            else
                MAR <= PC; 
          end if;
         end if;
 when 5 =>
          MAR <= PC;
          if op = jmp or op = jz then
             next_state <= 0;
          elsif op = read or op = write then 
             next_state <= 6;
          end if;
 when 6 =>
          next_state <= 0;
       if op = read then 
          R0 <= M_data_in;
       end if;     
 end case;
      
       elsif clock'event and clock = '0' then
             present_state <= next_state;
     end if;
 end process;
  
  status <= present_state;
  PCout <= PC;
  R0out <= R0;
  R1out <= R1;
  R2out <= R2;
  R3out <= R3;
  OPout <= op;
  M_address <= MAR;  
  M_data_out <= MDR;    
  Write_Read <= '1' 
     when reset='1' and present_state = 5 and op = write else '0';
          
end cpu_behavor;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -