天天看點

簡單計算機系統綜合設計(CPU)簡單計算機系統綜合設計(CPU)

簡單計算機系統綜合設計(CPU)

前言:作為一位來自于大學的大學生,讓我最難忘記的就是這一次CPU的綜合設計了。

基本部件

數字邏輯實驗中我們要求完成的有以下基本部件,使用VHDL源完成程式設計。

0000:指令寄存器IR,

a) 子產品的接口設計

控制信号:LDIR,CLK,I[7…0]

輸入信号:需執行指令I[7…0] 輸出信号:需執行指令out1[7…0]

b) 功能實作

根據指令寄存器IR的功能可知:

當HALT = 1 時,輸出信号 x[7…0] 為高阻态;

否則,當處于時鐘下降沿時,LDIR = 1時,輸出信号out[7…0]為輸入信号I[7…0]。

VHDL的實作如下所示:

library ieee;
use ieee.std_logic_1164.all;
entity IR is
	port (LDIR, CLK : in std_logic;
		I : in std_logic_vector(7 downto 0);
		OUT1 : out std_logic_vector(7 downto 0)
		);
end IR;

architecture behavior of IR is
	signal command: std_logic_vector(7 downto 0);
	begin
		OUT1 <= command;
		process(CLK)
			begin
				if (CLK'event and CLK = '0' and LDIR = '1') then
					command <= I;
				end if;
			end process;
end behavior;
           

0001:指令譯碼器DECODING,

a) 子產品的接口設計

控制信号:EN 輸入信号:需執行指令IR[7…0]

輸出信号:需執行指令IR[7…0],

各項指令的控制信号:MOVA,MOVB,MOVC,ADD,SUB,OR1,NOT1,RSR,RSL,JMP,JZ,JC,IN1,OUT1,NOP,HALT

b) 功能實作

根據指令譯碼器的功能可知:

當EN = 1時,輸入資訊:需執行指令IR[7…0]對應一個指令控制信号。

指令譯碼器需要完成指令機器碼和指令控制信号的一一對應。

VHDL的實作如下所示:

library ieee;
use ieee.std_logic_1164.all;

entity DECODING is
port(EN:in std_logic;
	 IR:in std_logic_vector(7 downto 0);
	 MOVA, MOVB, MOVC, ADD, SUB, OR1, NOT1, RSR, RSL, JMP, JZ, JC, IN1, OUT1, NOP, HALT: out std_logic);
end DECODING;

architecture behavior of DECODING is 
signal R: std_logic_vector(7 downto 0):="00000000"; 
signal signalB,signalC: std_logic;
begin    
	MOVA <= '1' when 
	IR(7 downto 4) = "1111" and (not (IR(3 downto 2) = "11")) and (not (IR(1 downto 0) = "11")) and EN = '1' else '0';
	MOVB <= '1' when 
	IR(7 downto 4) = "1111" and (IR(3 downto 2) = "11") and (not (IR(1 downto 0) = "11")) and EN = '1' else '0';
	MOVC <= '1' when 
	IR(7 downto 4) = "1111" and (not (IR(3 downto 2) = "11")) and (IR(1 downto 0) = "11") and EN = '1' else '0';
	ADD <= '1' when 
	IR(7 downto 4) = "1001" and EN = '1' else '0';
	SUB <= '1' when 
	IR(7 downto 4) = "0110" and EN = '1' else '0';
	OR1 <= '1' when 
	IR(7 downto 4) = "1011" and EN = '1' else '0';
	NOT1 <= '1' when 
	IR(7 downto 4) = "0101" and EN = '1' else '0';
	RSR <= '1' when 
	IR(7 downto 4) = "1010" and (IR(1 downto 0) = "00") and EN = '1' else '0';
	RSL <= '1' when 
	IR(7 downto 4) = "1010" and (IR(1 downto 0) = "11") and EN = '1' else '0';
	JMP <= '1' when 
	IR(7 downto 0) = "00010000" and EN = '1' else '0';
	JZ <= '1' when 
	IR(7 downto 0) = "00010001" and EN = '1' else '0';
	JC <= '1' when 
	IR(7 downto 0) = "00010010" and EN = '1' else '0';
	IN1 <= '1' when 
	IR(7 downto 4) = "0010" and EN = '1' else '0';
	OUT1 <= '1' when 
	IR(7 downto 4) = "0100" and EN = '1' else '0';
	NOP <= '1' when 
	IR(7 downto 0) = "01110000" and EN = '1' else '0';
	HALT <= '1' when 
	IR(7 downto 0) = "10000000" and EN = '1' else '0';

end behavior;

           

0010:控制信号産生邏輯 LOGIC,

a) 子產品的接口設計

控制信号:SM

輸入信号:MOVA,MOVB,MOVC,ADD,SUB,OR1,NOT1,RSR,RSL,JMP,JZ,JC,IN1,OUT1,NOP,HALT,C,Z

輸出信号:INPC,LDPC,LDIR,WE,FBUS,FLBUS,FRBUS,CS,DL,XL,M,HALT_out

b) 功能實作

當SM = 1時,輸入資訊:需執行指令IR[7…0]對應一個指令控制信号。

指令譯碼器需要完成指令機器碼和指令控制信号的一一對應。

VHDL的實作如下所示:

library ieee;
use ieee.std_logic_1164.all;
entity control_logism is
       port(SM,MOVA,MOVB,MOVC,ADD,SUB,OR1,NOT1,RSR,RSL,JMP,JZ,JC,IN1,OUT1,NOP,HALT,C,Z:in std_logic;
            IR: in std_logic_vector(7 downto 0);
            RAA,RWBA,MADD: out std_logic_vector(1 downto 0);
            S: out std_logic_vector(3 downto 0);
            INPC,LDPC,LDIR,WE,FBUS,FLBUS,FRBUS,CS,DL,XL,M,HALT_out: out std_logic
            );
end control_logism;

architecture control_logism_behavior of control_logism is
begin
	process(MOVA,MOVB,MOVC,ADD,SUB,OR1,NOT1,RSR,RSL,JMP,JZ,JC,C,Z,IN1,OUT1,NOP,HALT,IR)
	  begin
		S(3) <= IR(7);
		S(2) <= IR(6);
		S(1) <= IR(5);
		S(0) <= IR(4);
		LDIR <= not SM;
		INPC <= (not SM);
		LDPC <= JMP or (Z and JZ) or (C and JC);
		WE <= ((not MOVA) and (not MOVC) and (not ADD) and (not SUB) and (not OR1) and (not NOT1) and (not RSR) and (not RSL) and (not IN1)) or (not SM);
		RAA <= IR(1 downto 0);
		RWBA <= IR(3 downto 2);		
		M <= ADD or SUB or OR1 or NOT1;
		FBUS <= MOVA or MOVB or ADD or SUB or OR1 or NOT1 or OUT1;
		FLBUS <= RSL;
		FRBUS <= RSR;
		DL <= (not SM) or MOVC or JMP or JC or JZ;
		XL <= MOVB;
		MADD(1) <= MOVB;
		MADD(0) <= MOVC;			
		HALT_out <= HALT;
	end process;     
end control_logism_behavior;
           

0011:函數發生器ALU,

a) 控制信号:M,S[3…0]

輸入信号:資料A[7…0],B[7…0]

輸出信号:資料COUT[7…0],C,Z

b) 功能實作

根據函數發生器ALU的功能可知:

根據 M,S[3…0],需要判斷:

對資料進行加法運算,減法運算,或運算,取反運算還是不處理;

根據資料A[7…0],B[7…0],可以得到各種運算的結果;

通過運算結果可以得到輸出的資料COUT[7…0],以及C,Z

函數發生器ALU需要完成:

對A口,B口進入的資料進行各種運算并且處理輸出結果。

VHDL的實作如下所示:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity model_operator_ALU is

	port (
		m : in std_logic;
		s : in std_logic_vector(3 downto 0);
		a, b : in std_logic_vector(7 downto 0);		
		T : out std_logic_vector(7 downto 0);
		cf, zf : out std_logic);
end model_operator_ALU;

architecture Behavior of model_operator_ALU is
	signal temp : std_logic_vector(8 downto 0);
	signal pf,pf2 : std_logic_vector(0 downto 0);
	begin
	pf <= "0";
	pf2 <= "1";
	with m&s select
		temp <= (pf&b) + (pf&a) when "11001",
			(pf2&b) - (pf&a) when "10110",
			(pf&b) or (pf&a) when "11011",
			not (pf&b) when "10101",
			pf&a when "11111",
			pf&a when "01111",
			pf&b when "11010",
			pf&b when "01010",
			pf&b when "00100",
			pf&b when "10100",
			"011111111" when others;
	T <= temp(7 downto 0);
	cf <= temp(8);
	zf <= not(temp(8) or temp(7) or temp(6) or temp(5) or temp(4) or temp(3) or temp(2) or temp(1) or temp(0));
end Behavior;
           

0100:移位邏輯SHIFT,

a) 控制信号:FBUS,FLBUS,FRBUS

輸入信号:資料a[7…0] 輸出信号:資料 w[7…0],cf

b) 功能實作

根據移位邏輯的功能可知:

當FBUS = 1時,輸出資料 w[7…0]為輸入資料a[7…0];

當FLBUS = 1時,輸出資料 w[7…0]為輸入資料a[7…0]的邏輯左移;

當FRBUS = 1時,輸出資料 w[7…0]為輸入資料a[7…0]的邏輯右移;

通過結果可以得到cf;

移位邏輯需要完成:對輸入資料a[7…0]進行邏輯移位并且處理輸出結果。

VHDL的實作如下所示:

library ieee;
use ieee.std_logic_1164.all;

entity shift_logic is
   port(fbus,flbus,frbus: in std_logic;
        a: in std_logic_vector(7 downto 0);
        cf: out std_logic;
        w: out std_logic_vector(7 downto 0));
end shift_logic;

architecture behavior of shift_logic is
begin
  process(fbus,flbus,frbus)
    begin 
     if (flbus = '1' ) then 
     w <= a(6 downto 0) & '0';
     cf <= a(7);
     elsif (frbus = '1' ) then
     w <= '0' & a(7 downto 1) ;
     cf <= a(0);
     elsif (fbus = '1') then 
     w <= a;
     elsif (fbus = '0') then
     w <= "ZZZZZZZZ";
     end if;
  end process;
end behavior;
           

0101:使能信号SM,

a) 控制信号:CLK,EN 輸出信号:SM

b) 功能實作

根據SM信号發生器的功能可知:

當處于時鐘下降沿時,輸出信号與之前狀态的輸出信号相反。

VHDL的實作如下所示:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity SM_fun is
   port (CLK,EN: in std_logic;
   SM: out std_logic);
end SM_fun;
architecture behavior of SM_fun is
signal ls: std_logic:='0';
begin
  process(CLK,EN)
    begin
       if (CLK'event and (CLK = '0') and (EN = '1')) then
           ls <= not ls; 
       end if;
  end process;
  SM <= ls;
end behavior;
           

0110:指令計數器PC,

a) 子產品的接口設計

控制信号:LDPC,INPC,clk

輸入資料:位址值 indata[7…0] 輸出資料:位址值 outdata[7…0]

b) 功能實作

根據指令計數器PC的功能可知:

在時鐘的下降沿,若LDPC = 1,輸入外部的位址值,并輸出該位址值;

若INPC = 1,将原先的位址值加一,并輸出該位址值。

VHDL實作如下所示:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity Instruction_counter_PC is
   port(LDPC,INPC,CLK: in std_logic;
   indata: in std_logic_vector(7 downto 0);
   outdata: out std_logic_vector(7 downto 0));
end Instruction_counter_PC;

architecture behavior of Instruction_counter_PC is
signal pc: std_logic_vector(7 downto 0):= "00000000";
begin
  process(LDPC,INPC,CLK)
    begin
      if (CLK'EVENT and CLK = '0' and INPC = '1' and LDPC = '0') then
        pc <= pc + 1;
          elsif (CLK'EVENT and CLK = '0' and INPC = '0' and LDPC = '1') then
            pc <= indata;
      end if;
      outdata <= pc;
  end process; 
end behavior;
           

0111:通用寄存器組REGISTER,

a) 子產品的接口設計

控制信号:WE,RAA[1…0],RWBA[1…0],clk

輸入信号:總線資料I[7…0]

輸出信号:AO[7…0],BO[7…0]

CHECK: register_A [7…0],register_B[7…0],register_C [7…0]

b) 功能實作

根據通用寄存器組的功能可知:

當處于時鐘下降沿時,當WE = 0時:

根據 RWBA[1…0],需要向通用寄存器組中存入資料;

根據 RAA[1…0],RWBA[1…0],向A口和B口輸出資料

通用寄存器組需要完成:

對寄存器A,寄存器B,寄存器C進行資料的輸入和輸出。

VHDL的實作如下所示:

library ieee;
use ieee.std_logic_1164.all;

entity Universal_register_group is
port(
	RA : in std_logic_vector(1 downto 0);
	WA : in std_logic_vector(1 downto 0);
	I : in std_logic_vector(7 downto 0);
	WE : in std_logic;
	clk : in std_logic;
	AO : out std_logic_vector(7 downto 0);
	BO : out std_logic_vector(7 downto 0);
	register_A : out std_logic_vector(7 downto 0);
	register_B : out std_logic_vector(7 downto 0);
	register_C : out std_logic_vector(7 downto 0));
end Universal_register_group;

architecture behavior of Universal_register_group is
	signal A : std_logic_vector(7 downto 0) := "00000011";
	signal B : std_logic_vector(7 downto 0) := "00001100";
	signal C : std_logic_vector(7 downto 0) := "00110000";
	begin
--Output operation
  process(clk)
	begin
		if(clk'event and clk = '0')then
			if(WE = '0') then
				if(WA = "00")then
					A <= I;
				elsif(WA = "01")then
					B <= I;
				elsif(WA = "10")then
					C <= I;
				end if;
			end if;
		end if;	
  end process;	
--output operation                                                  	
  AO <= A when RA = "00" else
		B when RA = "01" else
		C when RA = "10" or RA = "11";
  BO <= A when WA = "00" else
		B when WA = "01" else
		C when WA = "10" or WA = "11";
  register_A <= A;
  register_B <= B;
  register_C <= C;
end behavior;
           

1000:選擇器SELECTOR

a) 子產品的接口設計

控制信号:MADD

輸入信号:I0[7…0],I1[7…0],I2[7…0] 輸出信号:OUT1[7…0]

b) 功能實作

根據選擇器的功能可知:

當MADD = 00時,輸出資訊 COUT[7…0] 輸入資訊 S0[7…0];

當MADD = 01時,輸出資訊 COUT[7…0] 輸入資訊 S1[7…0];

當MADD = 10時,輸出資訊 COUT[7…0] 輸入資訊 S2[7…0]。

VHDL的實作如下所示:

library ieee;
use ieee.std_logic_1164.all;

entity selector is
	port (MADD : in std_logic_vector(1 downto 0);
		I0, I1, I2 : in std_logic_vector(7 downto 0);
		OUT1 : out std_logic_vector(7 downto 0)
		);
end selector;

architecture behavior of selector is
begin
	OUT1 <= I0 when MADD = "00"
		else I1 when MADD = "01"
		else I2 when MADD = "10"
		else "ZZZZZZZZ" when MADD = "11";
end behavior;
           

1001:存儲器RAM,

a) 子產品的接口設計

控制信号:inclock ( clk ),we (XL),outenab(DL)

輸入信号:address[7…0] 輸出信号:dio[7…0]

b) 功能實作

簡單計算機系統綜合設計(CPU)簡單計算機系統綜合設計(CPU)

CPU邏輯圖

簡單計算機系統綜合設計(CPU)簡單計算機系統綜合設計(CPU)

CPU邏輯圖

簡單計算機系統綜合設計(CPU)簡單計算機系統綜合設計(CPU)

總結

模型機的設計坑比較多

下面我分類記錄了一下:

1:process的應用:我在仿真時發現信号輸出的值一直是預定義信号,後來發現是因為process隻能夠響應信号的變化,在信号一直為某一個值時,process不會作出響應。是以,除了帶有時鐘信号的部件,我一律棄用了process,改為并行。

2.無論我執行哪一個指令,發現通用寄存器組的輸出一直為0,是以我額外增加了register_A, register_B, register_C來CHECK我的信号,最後發現使我的BUS總線沒有輸入,是以我追溯到了我的ALU部分,原來是這裡阻塞了信号,使得ALU和shift_logic的輸出一直為高阻态,導緻BUS總線一直是高阻态。

3.我的指令譯碼器在開始時也是沒有輸出的,在此之前我曾将重寫了指令譯碼器,發現是因為指令譯碼器内部輸入和信号搞反了,這也算是一個低級錯誤了吧。

4.在設計CPU的時候,連線是一個較大的問題,因為好多的信号都會串在一起,是以可以采用不直接連線,而是通過端口的名稱定義為相同,進而間接将它們連接配接起來。

注:

本篇部落格僅用作學習交流使用,新學者還是建議還是自己敲一遍。