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

📄 cpu.vhd

📁 vhdl代码实现8位cpu功能
💻 VHD
字号:
library  ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

use work.xue.all;


entity  cpu is
	port(
	     reset:       in std_logic;
		 clock:       in std_logic;
		 M_data_in:   in std_logic_vector( 7 downto 0);
		 Write_Read  :       out std_logic;
		 M_data_out:  out std_logic_vector( 7 downto 0);
		 M_address:   out std_logic_vector( 11 downto 0);
		 overflow:    out std_logic;
		 R0out:       out std_logic_vector( 7 downto 0);
		 R1out:       out std_logic_vector( 7 downto 0);
		 R2out:       out std_logic_vector( 7 downto 0);
	 	 R3out:       out std_logic_vector( 7 downto 0);
	     PCout:       out std_logic_vector( 4 downto 0);
	     status2:     out std_logic_vector( 2 downto 0)
	
		);
end cpu;

architecture  rtl of cpu  is
	signal  IR:  std_logic_vector( 15 downto 0);
	signal  MDR: std_logic_vector( 7 downto 0);
	signal  MAR: std_logic_vector( 11 downto 0);
	signal  R0:  std_logic_vector(7 downto 0):="00000000";
	signal  R1:  std_logic_vector(7 downto 0):="00000000";
	signal  R2:  std_logic_vector(7 downto 0):="00000000";
	signal  R3:  std_logic_vector(7 downto 0):="00000000";
	signal  A:   std_logic_vector(7 downto 0):="00000000"; 
	signal  status: integer range 0 to 6;
	signal  PC:  std_logic_vector(11 downto 0);
	signal  OP:  std_logic_vector(3 downto 0);
begin
    
	process(reset, clock)
	variable Rx: std_logic_vector(7 downto 0);
	variable Ry: std_logic_vector(7 downto 0);
	variable temp: bit_vector(7 downto 0);
	variable Rst:std_logic_vector(7 downto 0);
	variable aRst:std_logic_vector(8 downto 0);
	variable IR_in: std_logic_vector(1 downto 0);       --寄存器选择信号
	variable over_r1: std_logic_vector(8 downto 0);
	variable over_r2:std_logic_vector(8 downto 0);	
	begin	
	
	   if reset = '0' then
	   status <= 0;
	   R0 <= "00000000";
	   R1 <=  "00000000";
	   R2 <= "00000000";
	   R3 <= "00000000";
	   A <= "00000000";
	   PC <= "000000000000";
	   MDR <= "00000000";
	   IR <= "0000000000000000";
	   elsif (clock'event and clock='1') then 
	     
		   case status is
		    when 0=> 
		          overflow <= '0';
		          IR(15 downto 8) <= M_data_in;
		          OP <= M_data_in(7 downto 4);           --get operation code
		          Write_Read <= '0';
		          status <= 1;
		    when 1=>
			      if IR(9 downto 8)="00" then        --确定Ry
		                Ry:=R0;
		          elsif IR(9 downto 8)="01" then
		                Ry:=R1;
		          elsif IR(9 downto 8)="10" then
		                Ry:=R2;
		          else 
		                Ry:=R3;
		          end if;
		
		          IR_in:=IR(11 downto 10);
		          if IR_in="00" then        --确定Rx
		                Rx:=R0;
		          elsif IR_in="01" then
		                Rx:=R1;
		          elsif IR_in="10" then
		                Rx:=R2;
		          else 
		                Rx:=R3;
		          end if;
		
		          if OP=load then                     --操作数为load
		             R0(7 downto 4)<="0000";    
		             R0(3 downto 0)<=IR(11 downto 8);  --R0 <= "0000" & IR(11 downto 8);
			      elsif OP = move then       --传数据             
		             Rx := Ry;
		          elsif OP = shrp then                   --逻辑右移
		             temp := to_bitvector(Rx);       --转化成位矢量
		             temp := temp srl 1; 
		             Rx := to_stdlogicvector(temp);  --位矢量转化为vector
		          elsif OP=shlp then
		             temp := to_bitvector(Rx);
		             temp := temp sll 1;
		             Rx := to_stdlogicvector(temp);
		          elsif ( OP = andp or OP = orp or OP = xorp or OP = swap) then
		             A <= Ry;
		             status <= 2;
		          elsif OP = addp then
		             if Rx(7) = '0' then  --求两数补码
				  	 over_r1 := '0' & Rx;
				     else
				     over_r1 := '1' & Rx;
				     end if;
				
				     if Ry(7) = '0' then
				  	 over_r2 := '0' & Ry;
				     else
				     over_r2 := '1' & Ry;
				     end if;
					 status <= 2;
					
				  elsif  OP = subp then
			
			         if Rx(7) = '0' then  --求两数补码
				  	 over_r1 := '0' & Rx;
				     else
				     over_r1 := "11" & (not Rx(6 downto 0) +1);
				     end if;
				
				     if Ry(7) = '0' then
				     over_r2 := "11" & (not Ry(6 downto 0) +1);
				  	 
				     else
				     over_r2 := "00"& Ry (6 downto 0);
				     end if;
					 status <= 2;
					
		          else 
		             NULL;
		          end if;
		
		          if OP /= load then
		             if IR_in = "00" then
		                R0 <= Rx;
		             elsif IR_in = "01" then
		                R1 <=Rx;
		             elsif IR_in = "10" then
		                R2<=Rx;
		             else 
		                R3 <= Rx;
		             end if;
		          end if;
		          if OP/=stop then
		             PC <= PC+1;
		             MAR <= PC+1;
		             status <= 2;
		          else status <= 1;
		          end if;
		    when 2=>
		          if (OP=load or OP=move or OP=shrp or OP=shlp or OP=stop or OP=idle or OP=jmp or OP=jz or OP=read or OP=write) then
		              NULL;
		          elsif OP=addp then           --几个逻辑运算和算术运算的第二步。
		              
		              aRst:=over_r1+over_r2;
		              overflow <= aRst(8) xor aRst(7);
		              Rst:=aRst(7 downto 0);
		               
		          elsif OP=subp then
					  aRst:=over_r1+over_r2;
		              overflow <= aRst(8) xor aRst(7);		        
		              Rst:=aRst(7 downto 0); 
		
		          elsif OP=andp then
		              Rst:=(A and Rx);
		          elsif OP=orp then
		              Rst:=Rx or A;
		          elsif OP=xorp then
		              Rst:=Rx xor A;
		          elsif OP=swap then             --交换运算中Ry<-Rx;
		              if IR(9 downto 8)="00" then
		                 R0 <= Rx;
		              elsif IR(9 downto 8)="01" then
		                 R1 <= Rx;
		              elsif IR(9 downto 8)="10" then
		                 R2 <= Rx;
		              else
		                 R3 <= Rx;
		              end if;
		          end if;

		          if (OP=addp or OP=subp or OP=xorp or OP=orp or OP=andp) then  --几个运算后将结果送回(Rx)
		              if IR_in="00" then
		                 R0 <= Rst;
		              elsif IR_in="01" then
		                 R1 <= Rst;
		              elsif IR_in="10" then
		                 R2 <= Rst;
		              else 
		                 R3 <= Rst;
		              end if;
		          end if;
		          if (OP=swap or OP=jmp or OP=jz or OP=read or OP=write) then
		              status <= 3;
		              MAR <= PC;
		          else 
		              status <= 0;
		              MAR <= PC;
		          end if;

		    when 3=>
		          if OP=swap then
		             if IR_in="00" then
		                 R0 <= A;
		             elsif IR_in="01" then
		                 R1 <= A;
		             elsif IR_in="10" then
		                 R2 <= A;
		             else 
		                 R3 <= A;
		             end if;
		             status <= 0;
		          elsif (OP=read or OP=write or OP=jmp or OP=jz) then 
		              IR(7 downto 0)<=M_data_in;
		              status <= 4;
		              PC <= PC+1;
		              Write_Read <= '0';
		          end if;
		    when 4=>
		          if OP=read then
		             MAR <= IR(11 downto 0);
		             status <= 5;
		          elsif OP=write then
		             MDR <= R0;
		             MAR <= IR(11 downto 0);
		             status <= 5;
		          elsif OP=jmp then
		             PC <= IR(11 downto 0);
		             MAR <= IR(11 downto 0);
		             status <= 5;
		          elsif OP=jz then
		             if(R0="00000000") then
		                PC <= IR(11 downto 0);
		                MAR <= IR(11 downto 0);
		                status <= 5;
		             else 
		                MAR <= PC;
		                status <= 5;
		             end if;
		          else
		             status <= 0;
		          end if;
		    when 5=>
		          if (OP=jmp or OP=jz) then
		             status <= 0;
		          elsif OP=read then
		             Write_Read <= '0';
		             status <= 6;
		          elsif OP=write then
		             status <= 6;
		          end if;
		          MAR <= PC;
		    when 6=>
		          if OP=Read then
		             R0 <= M_data_in;     
		          end if;
		          status <= 0;
		    when others=>
		          status <= 0;
		   end case;
	        if  status = 4 and OP = write then
			Write_Read <= '1';
		else
			Write_Read <= '0';
		end if;
 	end if;
	end process;
		
	M_address <= MAR;
	M_data_out <= MDR;
	PCout <= PC( 4 downto 0 );
	
	R0out <= R0;
	R1out <= R1;
	R2out <= R2;
	R3out <= R3;
	
	with status select --把整数转换成信号
	     status2  <= 
	            "000"  when 0,
	            "001"  when 1,
	            "010"  when 2,
	            "011"  when 3,
	            "100"  when 4,
	            "101"  when 5,
	            "110"  when 6;
	
end rtl;

⌨️ 快捷键说明

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