一.设计概况
本次试验要完成的工作主要包括:指令系统的设计,CPU的整体结构设计及其细化,逻辑设计的具体实现,软件模拟,硬件调试。试验的主要流程如下图所示:
指令系统设计
逻辑设计
具体实现
软件模拟
硬件调试 设计CPU的指令集。 分析并确定CPU主要功能模块,分析每条指令的执行过程,数据的流向和控制信号的产生,画出逻辑结构图 按模块分别实现并模拟 整体模拟仿真,检查时序关系配合是否正确 下载到FPGA中进行硬件调试
二.指令设计 1.指令格式设计
①单操作数指令
15 11 10 8 7 0 OPCODE 000 X
包括:JMP,JZ,JC ②寄存器-寄存器指令 15 11 10 8 7 3 2 0 OPCODE REG1 00000 REG2 包括:MOV,ADC,SBB,OR,AND
③寄存器-立即数(地址)指令 15 11 10 8 7 0 OPCODE REG DATA 包括:LDA,STA,MOV, ADC,SBB,OR,AND
④其他类型指令
15 11 10 0 OPCODE 00000000000 包括:CLC,STC
2.指令编码
OPCODE 00000 00001 00010 指令 MOV R, DATA MOV R, (AD) (LDA) MOV (AD),R (STA) 00011 00100 00101 00110 00111 01000 01001 01010 01011 01100 01101 01110 01111 10000 10001 10010
MOV R1,R2 MOV R1,(R2) MOV R,(R7//R6+DATA) ADC R,DATA ADC R1,R2(Cy) SBB R,DATA SBB R1,R2(Cy) AND R,DATA AND R1,R2 OR R,DATA OR R1,R2 CLC STC JMP ADDR (R//ADDR->PC) JZ DATA (PC+DATA->PC(Z=1)) JC DATA(PC+DATA->PC(Cy=1))
三.CPU逻辑设计
1.CPU整体框图
时钟管理模块 PC REG ADDR IR 运算模块DATA Rtemp 回写模块 存储管理模块 取值模块 DATA ALUOUT PC+1 Flag 访存控制 地址总线 数据总线 存储器
2.节拍设计
一个周期采用四个节拍。一个节拍完成取指。第二个节拍完成运算。第三个节拍访存。第四个节拍回写。
3.数据流说明
第一个节拍内,取指模块向访存控制发出访存信号,得到指令后,将指
令保存在指令寄存器IR中,并将指令送往后面的运算模块,存储管理模块,回写模块。同时将PC送入运算模块和回写模块。
第二个节拍内,运算管理模块将指令译码。如果是存数指令,则将地址存入ADDR寄存器,数据存入DATA存储器,等待下一个节拍访存。如果是取数指令,则将地址存入ADDR寄存器,等待下一个节拍访存。如果是其他非访存指令,则将计算结果存入ALUOUT寄存器,送往存储管理模块的Rtemp寄存器。 第三个节拍内,存储管理模块将指令译码。如果是存数指令,则向访存控制模块发出访存信号,则将第二个节拍内存好的ADDR寄存器的内容作为地址,把DATA寄存器里面的数据存入存储器对应的位置。如果是取数指令,则将第二
个节拍内存好的ADDR寄存器的内容作为地址,从存储器对应的位置取出数据,存入Rtemp存储器,并送往回写模块。如果是其他非访存指令,则将Rtemp寄存器里的内容直接送往回写模块。 第四个节拍内,回写模块先将指令译码。根据指令将需要回写的数据回写近响应的寄存器,并将PC+1后回写至取指模块的PC寄存器。
四.各模块详细说明 1、时钟管理模块
功能:产生节拍,控制各个模块的工作
CLK 时钟管理模块 K RST 信号名 CLK RST K
位数 1 1 4 方向 In In out 来源/去向 处理器板 处理器板 其余模块 意义 系统时钟 复位 输出节拍
2、取指模块
功能:向访存控制模块发出信号,取得指令
RST K1 Pcout 取指模块 Orderout Pcback Pcbacka AddrFlag Order
信号名 RST K1 Pcback Pcbacka Order Pcout Orderout Addrflag 位数 1 1 16 1 16 16 16 1
方向 I I I I I O O O 来源/去向 处理器板 时钟管理模块 回写模块 回写模块 内存 其他模块 其他模块 访存控制模块 意义 复位 时钟控制 回写PC 回写PC允许 指令 PC输出 指令输出 访存信号
3、运算管理模块
功能:进行各种指令的执行,同时对响应的跳转指令地址和存数、取数指令地址的输出。
K2 Aluout K3 Order 运算管理模块 Pcin Rst Addr Rwb Rwba
信号名 K2 K3 Order Pcin Rst Rwb Rwba Aluout addr 位数 1 1 16 16 1 8 1 16 16 方向 I I I I I I I O O 来源/去向 时钟模块 时钟模块 取值模块 取值模块 处理器板 回写模块 回写模块 访存模块、存储管理模块 访存模块 意义 时钟控制 时钟控制 指令输入 PC输入 复位 回写数据 回写数据允许 指令执行结果(包括PC) 指令中需要访存的地址
4、存储管理模块
功能:对存取数的相应控制信号和数据的管理,负责向访存控制模块发出访存信号;将运算结果送往回写模块。
K3 Rtmp Order sta Alu 存储管理模块 lda Datain dataout
信号名 K3 Order Alu Datain Rtmp Sta Lda 位数 1 16 16 8 16 1 1 方向 I I I I O O O 来源/去向 时钟模块 取指模块 运算模块 访存控制模块 意义 时钟控制 指令输入 运算结果输出 从内存读入的数 回写模块 数据输出 访存控制模块 存数控制 访存控制模块 取数控制 Dataout 8 O 访存控制模块 存入内存的数
5、访存控制模块
功能:负责与内存进行数据的交换
Sta orderout lda dataout Pcaddr 访存控制模块 ABUS addr CS flag RD DBUS WR 信号名 Sta Lda Pcaddr Addr Flag Dbus Orderout Dataout 位数 1 1 16 16 1 16 16 8 方向 I I I I I i/o O O 来源/去向 存储管理模块 存储管理模块 取指模块 运算管理模块 取指模块 内存 取指模块 存储管理模块 意义 存数指令 取指指令 PC输入 内存地址 取指标志 数据总线 指令输出 从内存读出的Cd Rd Wr Datain Abus 1 1 1 8 16 O O O I O 数 内存 片选 内存 读 内存 写 存储管理模块 需要存入内存的数 内存 内存地址
6、回写管理模块
功能:对相应该回写数据或地址的数据与地址进行回写管理。
K4 Pcback order Pcbacka Pcin 回写管理模块 dataout datain dataA
信号名 K4 Order Pcin 位数 1 16 16 方向 I I I 来源/去向 时钟管理模块 时钟管理模块 取指管理模块 意义 时钟控制 指令输入 PC输入 Datain 16 I Pcback Pcbacka Dataout dataA
16 1 8 1 O O O O 存储管理模块 需要回写的数据(包括JMP指令的PC) 取指模块 PC回写 取指模块 PC回写允许 运算管理模块 回写数据 运算管理模块 回写数据允许 附1:各模块波形与总测试波形
注:单独测试时,由于模块之间没有联系起来,故只测试了模块的单独工作下最基本功能,波形较简单。
时钟管理模块:
取指模块
运算管理模块
存储管理模块
回写模块
访存控制模块
下面是CPU总波形的测试:(由于测试指令太多,导致波形过长,故将波形分为三段):
附二、各模块实现代码 1.时钟管理模块 entity clk_ctrl is
port(
Clk:in std_logic; Rst:in std_logic;
k:out std_logic_vector(3 downto 0) );
end clk_ctrl;
architecture Behavioral of clk_ctrl is
signal tmp:std_logic_vector(3 downto 0); begin
process(Clk,Rst,tmp) begin
if Rst ='1' then --rst=1复位; --k<=\"0000\"; tmp<=\"0001\"; elsif Clk='1' and Clk'event then tmp(0)<=tmp(3); tmp(3 downto 1)<=tmp(2 downto 0); end if;
end process; k<=tmp; end Behavioral;
2.取指管理模块
entity irget is Port (
Rst : in STD_LOGIC;--复位;
Pcback : in STD_LOGIC_VECTOR (15 downto 0);--PC回写; Pcbacka : in STD_LOGIC;--PC回写允许; k1 : in STD_LOGIC;--时钟控制;
Order : in STD_LOGIC_VECTOR (15 downto 0);--指令
Pcout : out STD_LOGIC_VECTOR (15 downto 0);--PC输出; Orderout : out STD_LOGIC_VECTOR (15 downto 0);--指令输出; AddrFlag : out STD_LOGIC);--访址标志 end irget;
architecture Behavioral of irget is
signal tmpPC: std_logic_vector (15 downto 0); --指令地址; signal IR:std_logic_vector(15 downto 0);--指令寄存器; begin
process(Rst,Pcback,Pcbacka,k1,order,tmpPc) begin
if Rst='1' then
tmpPc<=\"0000000000000000\"; elsif k1='1' then Pcout<=tmpPc; AddrFlag<='1';--第一个节拍高电平取指; elsif Pcbacka='1' then
tmpPc<=Pcback;--pc回写允许 ---end if; --AddrFlag<='0'; else AddrFlag<='0'; end if ;
Orderout<=Order;--指令存入指令寄存器; end process;
--Orderout<=IR;--得到指令,准备送往后面的模块; end Behavioral;
3.访存管理模块
entity CPU_ToMomery is Port (
sta : in STD_LOGIC;--存数指令; lda : in STD_LOGIC;--取数指令; Addr: in STD_LOGIC_VECTOR(15 downto 0);--内存地址; flag: in STD_LOGIC;--取指标志; PCaddr: in STD_LOGIC_VECTOR(15 downto 0);--指令地址输入; orderout:out STD_LOGIC_VECTOR(15 downto 0);--指令输出; dataout : out STD_LOGIC_VECTOR (7 downto 0);--从内存中取出的数; datain : in STD_LOGIC_VECTOR (7 downto 0);--需要存入内存的数;
ABUS : out STD_LOGIC_VECTOR(15 downto 0);--地址总线?? DBUS : inout STD_LOGIC_VECTOR(15 downto 0);--数据总线; CS: out STD_LOGIC;--片选信号;低电平有效; RD: out STD_LOGIC;--读信号;低电平有效; WR: OUT STD_LOGIC; --写信号;低电平有???? nBHE:out std_logic; nBLE:out std_logic );
end CPU_ToMomery;
architecture Behavioral of CPU_ToMomery is begin
process(sta,lda,datain,DBUS,flag) begin
if flag='1' then --取指令; CS<='0'; RD<='0'; WR<='1'; nBHE<='0'; nBLE<='0'; ABUS<=PCaddr; orderout<=DBUS; DBUS<=\"ZZZZZZZZZZZZZZZZ\"; elsif sta='1' then --存数访存; CS<='0'; RD<='1'; WR<='0'; nBHE<='0'; nBLE<='0'; ABUS<=Addr; DBUS(7 downto 0)<=datain; DBUS(15 downto 8)<=\"11111111\";
elsif lda='1' then --取数访存; CS<='0'; RD<='0'; WR<='1'; nBHE<='0'; nBLE<='0'; ABUS<=Addr; dataout<=DBUS(7 downto 0); DBUS<=\"ZZZZZZZZZZZZZZZZ\"; else CS<='1'; RD<='1'; WR<='1'; nBHE<='1'; nBLE<='1'; DBUS<=\"ZZZZZZZZZZZZZZZZ\";
end if; end process; end Behavioral;
4.运算管理模块
entity CPU_operation is
Port ( k2 : in STD_LOGIC;--时钟控制;
k3 : in STD_LOGIC;--时钟控制;第三个时钟高电平改变标志寄存器的值;
order : in STD_LOGIC_VECTOR (15 downto 0);--命令输入; Pcin:in STD_LOGIC_VECTOR(15 downto 0);--pc输入; Rst:in STD_LOGIC;--复??;
Rwb : in STD_LOGIC_VECTOR (7 downto 0);--回写数据; Rwba : in STD_LOGIC;--回?丛市???高电平有效 Aluout : out STD_LOGIC_VECTOR (15 downto 0);--计算结果输出;
addr : out STD_LOGIC_VECTOR (15 downto 0)--内存?刂?? ); end CPU_operation;
architecture Behavioral of CPU_operation is
type reg is array(0 to 7) of std_logic_vector(7 downto 0); signal sreg:reg; signal F9:std_logic_vector(8 downto 0);--判断结果是否进位、是否为零; signal sregflag:std_logic_vector(1 downto 0);--标志寄存器; begin
process(Rwb,Rwba,k2,order,sreg,Pcin,sregflag,F9) begin
if Rwba='1' then
sreg(conv_integer(order(10 downto 8)))<=Rwb;--回写 end if; if Rst='1' then sreg(7)<=\"00000000\"; sreg(6)<=\"00000000\"; F9(8)<='0'; end if; if k2='1' then
case order(15 downto 11) is when \"00000\"=>--mov Ri,Im Aluout(7 downto 0)<=order(7 downto 0); Aluout(15 downto 8)<=\"11111111\"; when \"00001\"=>--LDA Ri,X addr(15 downto 8)<=sreg(7); addr(7 downto 0)<= order(7 downto 0); Aluout(15 downto 8)<=\"11111111\"; when \"00010\"=>--STA Ri,X Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8))); Aluout(15 downto 8)<=\"11111111\"; addr(7 downto 0)<=order(7 downto 0); addr(15 downto 8)<=sreg(7); when \"00011\"=>--mov Ri,Rj Aluout(7 downto 0)<=sreg(conv_integer(order(2 downto 0))); Aluout(15 downto 8)<=\"11111111\"; when \"00100\"=>--mov Ri,(Rj) addr(7 downto 0)<=sreg(conv_integer(order(2 downto 0))); addr(15 downto 8)<=sreg(7); when \"00101\"=>--mov Ri,[R7//R6+x] addr<= sreg(7)&sreg(6)+order(7 downto 0); when \"00110\"=>--Adc,Ri,Im Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8)))+order(7 downto 0)+sregflag(1); F9<=('0'&sreg(conv_integer(order(10 downto 8))))+('0'&order(7 downto 0)); Aluout(15 downto 8)<=\"11111111\"; when \"00111\"=>--Adc,Ri,Rj,Ri+Rj+Cy->Ri Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8)))+sreg(conv_integer(order(2 downto 0)))+sregflag(1); F9<=('0'&sreg(conv_integer(order(10 downto 8))))+('0'&order(7 downto 0)); Aluout(15 downto 8)<=\"11111111\";
when \"01000\"=>--SBB Ri,Im Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8)))-order(7 downto 0)-sregflag(1); F9<=('0'&sreg(conv_integer(order(10 downto 8))))-('0'&order(7 downto 0)); Aluout(15 downto 8)<=\"11111111\"; when \"01001\"=>--SBB Ri,Rj,Ri-Rj-Cy->Ri Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8)))-sreg(conv_integer(order(2 downto 0)))-sregflag(1); F9<=('0'&sreg(conv_integer(order(10 downto 8))))-('0'& order(7 downto 0)); Aluout(15 downto 8)<=\"11111111\"; when \"01010\"=>--AND Ri,Im Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8))) and order(7 downto 0); F9(7 downto 0)<=(sreg(conv_integer(order(10 downto 8))))and(order(7 downto 0)); Aluout(15 downto 8)<=\"11111111\"; when \"01011\"=>--AND Ri,Rj Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8))) and sreg(conv_integer(order(2 downto 0))); F9(7 downto 0)<=sreg(conv_integer(order(10 downto 8))) and order(7 downto 0); Aluout(15 downto 8)<=\"11111111\"; when \"01100\"=>--OR Ri,Im Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8))) or order(7 downto 0); F9(7 downto 0)<=(sreg(conv_integer(order(10 downto 8)))) or (order(7 downto 0)); Aluout(15 downto 8)<=\"11111111\"; when \"01101\"=>--OR Ri,Rj Aluout(7 downto 0)<=sreg(conv_integer(order(10 downto 8))) or sreg(conv_integer(order(2 downto 0))); F9(7 downto 0)<=(sreg(conv_integer(order(10 downto 8)))) or (order(7 downto 0)); Aluout(15 downto 8)<=\"11111111\"; when \"10000\"=>--JMP Addr Aluout<=sreg(7)&order(7 downto 0);
when \"10001\"=>--JZ sign if sregflag(0)='1' then if order(7)='0' then Aluout<= Pcin+(\"00000000\"&order(7 downto 0)); else Aluout <= Pcin+(\"11111111\" & order(7 downto 0)); end if; else Aluout <= Pcin; end if; when \"10010\"=>--JC sign if sregflag(1) = '1' then if order(7)='0' then Aluout<= Pcin+(\"00000000\"&order(7 downto 0)); else Aluout <= Pcin+(\"11111111\" & order(7 downto 0)); end if; else Aluout <= Pcin; end if;
when others=>NULL; end case; end if; end process;
process(k3,F9,order) begin if rst = '1' then sregflag(0)<='0'; sregflag(1)<='0'; elsif k3 = '1' then case order(15 downto 12) is when \"0011\" | \"0101\" | \"0100\" | \"0110\" => sregflag(1) <= F9(8); if F9(7 downto 0) = \"00000000\" then sregflag(0) <= '1'; else sregflag(0)<='0'; end if; when \"0111\"=> sregflag(0) <= order(11); when others => null; end case; end if;
end process; end Behavioral;
5.存储管理模块
entity CPU_Momery is Port (
k3 : in STD_LOGIC;--时钟控制;
order : in STD_LOGIC_VECTOR (15 downto 0);--命令输入; alu : in STD_LOGIC_VECTOR (15 downto 0);--计算结果输??; datain : in STD_LOGIC_VECTOR (7 downto 0);--从内存读入的??; dataout: out STD_LOGIC_VECTOR (7 downto 0);--存入内存的数;
Rtmp:out STD_LOGIC_VECTOR (15 downto 0);--数据输出;送向回写模块; sta : out STD_LOGIC;--存数控制;高电平有效; lda : out STD_LOGIC);--取数控制;高电平有效?? end CPU_Momery;
architecture Behavioral of CPU_Momery is
begin
process(k3,alu,order,datain) begin
if k3='1' then --高电平操作; case order(15 downto 11) is when \"00001\"=>--取数; lda<='1'; Rtmp(7 downto 0)<=datain; when \"00100\"=>--取数; lda<='1';
Rtmp(7 downto 0)<=datain; when \"00101\"=>--取数; lda<='1';
Rtmp(7 downto 0)<=datain; when \"00010\"=>--存数; sta<='1';
dataout<=alu(7 downto 0); when others=>
Rtmp<=alu;--不访存;运算结果直接送下一个模块; lda<='0'; sta<='0'; end case;
else
lda<='0'; sta<='0'; end if; end process; end Behavioral;
6.回写管理模块
entity WriteBack is port(
k4: in std_logic;--时钟控制;
order:in std_logic_vector(15 downto 0);--指令输入; Pcin:in std_logic_vector(15 downto 0);--pc输入;
datain:in std_logic_vector(15 downto 0);--需要回写的数据,包括跳转指令的PC??
Pcback:out std_logic_vector(15 downto 0);--pc回写; Pcbacka: out std_logic;--pc回写允许;
dataout:out std_logic_vector(7 downto 0);--回写数据输出; dataA:out std_logic);--回写允许;
end WriteBack;
architecture Behavioral of WriteBack is
begin
process(k4,order,Pcin,datain) begin
if k4='1' then
case order(15 downto 11) is when \"00000\" =>--mov Ri,Im Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0);
when \"00001\" =>--LDA Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0);
when \"00010\"=>--STA Pcbacka<='1'; Pcback<=Pcin+1; dataA<='0'; when \"00011\"=>--mov Ri,Rj Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"00100\"=>--mov Ri,(Rj) Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0);
when \"00101\"=>--mov Ri,[R7//R6+x] Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"00110\"=>--Adc Ri,Im Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"00111\"=>--Adc,Ri,Rj Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"01000\"=>--Sbb,Ri,Rj Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"01001\"=>--Sbb RI,Im Pcbacka<='1';
Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"01010\"=>--AND Ri,Im Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"01011\"=>--And Ri,Rj Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"01100\"=>--Or Ri,Im Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"01101\"=>--Or,Ri,Rj Pcbacka<='1'; Pcback<=Pcin+1; dataA<='1'; dataout<=datain(7 downto 0); when \"01110\"=>--Clc Pcbacka<='1'; Pcback<=Pcin+1; dataA<='0'; when \"01111\"=>--STC Pcbacka<='1'; Pcback<=Pcin+1; dataA<='0'; when \"10000\"=>--Jmp Addr Pcbacka<='1'; Pcback<=datain+1; dataA<='0'; when \"10001\"=>--Jz sign
Pcbacka<='1'; Pcback<=datain+1; dataA<='0'; when \"10010\"=>--Jc sign Pcbacka<='1'; Pcback<=datain+1; dataA<='0'; when others=>NULL; end case; else
Pcbacka<='0'; dataA<='0'; end if;
end process; end Behavioral;
7.CPU总代码
entity CPU_main is port(
RST:in std_logic; CLK:in std_logic;
ABUS:out std_logic_vector(15 downto 0); DBUS:inout std_logic_vector(15 downto 0); nMREQ:out std_logic; nRD:out std_logic; nWR:out std_logic; nBHE:out std_logic; nBLE:out std_logic;
nABUS:out std_logic_vector(15 downto 0); nDBUS:out std_logic_vector(15 downto 0); IR:out std_logic_vector(15 downto 0); Ti:out std_logic_vector(3 downto 0); CS:OUT STD_LOGIC; WR:OUT STD_LOGIC; RD:OUT STD_LOGIC; BH:OUT STD_LOGIC; BL:OUT STD_LOGIC );
end CPU_main;
architecture Behavioral of CPU_main is component CPU_Momery is port(
k3 : in STD_LOGIC;--时钟控制;
order : in STD_LOGIC_VECTOR (15 downto 0);--命令输入; alu : in STD_LOGIC_VECTOR (15 downto 0);--计算结果输??; datain : in STD_LOGIC_VECTOR (7 downto 0);--从内存读入的??; dataout: out STD_LOGIC_VECTOR (7 downto 0);--存入内存的数;
Rtmp:out STD_LOGIC_VECTOR (15 downto 0);--数据输出;送向回写模块; sta : out STD_LOGIC;--存数控制;高电平有效; lda : out STD_LOGIC);--取数控制;高电平有效?? end component;
component CPU_ToMomery is port(
sta : in STD_LOGIC;--存数指令; lda : in STD_LOGIC;--取数指令; Addr: in STD_LOGIC_VECTOR(15 downto 0);--内存地址; flag: in STD_LOGIC;--取指标志; PCaddr: in STD_LOGIC_VECTOR(15 downto 0);--指令地址输入; orderout:out STD_LOGIC_VECTOR(15 downto 0);--指令输出; dataout : out STD_LOGIC_VECTOR (7 downto 0);--从内存中取出的数; datain : in STD_LOGIC_VECTOR (7 downto 0);--需要存入内存的数;
ABUS : out STD_LOGIC_VECTOR(15 downto 0);--地址总线?? DBUS : inout STD_LOGIC_VECTOR(15 downto 0);--数据总线; CS: out STD_LOGIC;--片选信号;低电平有效; RD: out STD_LOGIC;--读信号;低电平有效; WR: OUT STD_LOGIC; --写信号;低电平有???? nBHE:out std_logic; nBLE:out std_logic ); end component;
component CPU_operation is port(
k2 : in STD_LOGIC;--时钟控制;
k3 : in STD_LOGIC;--时钟控制;第三个时钟高电平改变标志寄存
器的值;
order : in STD_LOGIC_VECTOR (15 downto 0);--命令输入; Pcin:in STD_LOGIC_VECTOR(15 downto 0);--pc输入; Rst:in STD_LOGIC;--复??;
Rwb : in STD_LOGIC_VECTOR (7 downto 0);--回写数据; Rwba : in STD_LOGIC;--回?丛市???高电平有效 Aluout : out STD_LOGIC_VECTOR (15 downto 0);--计算结果输出;
addr : out STD_LOGIC_VECTOR (15 downto 0)--内存?刂??? );
end component;
component WriteBack is port(
k4: in std_logic;--时钟控制;
order:in std_logic_vector(15 downto 0);--指令输入; Pcin:in std_logic_vector(15 downto 0);--pc输入;
datain:in std_logic_vector(15 downto 0);--需要回写的数据,包括跳转指令的PC??
Pcback:out std_logic_vector(15 downto 0);--pc回写; Pcbacka: out std_logic;--pc回写允许;
dataout:out std_logic_vector(7 downto 0);--回写数据输出; dataA:out std_logic--回写允许; );
end component;
component irget is port(
Rst : in STD_LOGIC;--复位;
Pcback : in STD_LOGIC_VECTOR (15 downto 0);--PC回写; Pcbacka : in STD_LOGIC;--PC回写允许; k1 : in STD_LOGIC;--时钟控制;
Order : in STD_LOGIC_VECTOR (15 downto 0);--指令
Pcout : out STD_LOGIC_VECTOR (15 downto 0);--PC输出; Orderout : out STD_LOGIC_VECTOR (15 downto 0);--指令输出; AddrFlag : out STD_LOGIC--访址标志 );
end component;
component clk_ctrl is
port(
Clk:in std_logic; Rst:in std_logic;
k:out std_logic_vector(3 downto 0) );
end component;
signal a,b,c,d,e:std_logic;
signal t:std_logic_vector(3 downto 0);
signal data7,data8,data9:std_logic_vector(7 downto 0);
signal data1,data2,data3,data4,data5,data6,data10,data11,data12:std_logic_vector(15 downto 0);
signal u,v,w,x,y:std_logic;
begin --irget:
--data1:回写的pc; --data2:指令输入; --data3: pc输出; --data4:指令输出?? --a:PC回写允许; --b:访??标志;
--operation:
--data9:回写数据; --data5:Aluout
--data6:Addr输出;
--memory:
--data7:从内存读入的数; --data8:存入内存??;
--data10:送往回写模块的数; --c:存数控制 --d:取数控制,送?
--ToMemory: --ABUS,DBUS --CS RD WR;
么???块
--writeback:
--e回写数据允许; --a回写pc允许;
u1: clk_ctrl port map(CLK, RST, t);
u2: irget port map(RST, data1, a, t(0), data2, data3, data4, b);
u3: CPU_operation port map(t(1),t(2),data4,data3,Rst,data9,e,data5,data6); u4: CPU_Momery port map(t(2),data4,data5,data7,data8,data10,c,d); u5: CPU_ToMomery map(c,d,data6,b,data3,data2,data7,data8,data11,DBUS,u,v,w,x,y); u6: WriteBack port map(t(3),data4,data3,data10,data1,a,data9,e);
IR<=data2; Ti<=t;
nMREQ<=u; CS<=u; nRD<=v; RD<=v; WR<=w; nWR<=w; BH<=x; nBHE<=x; BL<=y; nBLE<=y;
ABUS<=data11; nABUS<=data11;
nDBUS<=DBUS;
end Behavioral;
五.硬件调试 1.ucf文件
NET \"ABUS<0>\" LOC = \"P60\" ; NET \"ABUS<10>\" LOC = \"P129\" ; NET \"ABUS<11>\" LOC = \"P202\" ;
port
NET \"ABUS<12>\" LOC = \"P203\" ; NET \"ABUS<13>\" LOC = \"P205\" ; NET \"ABUS<14>\" LOC = \"P206\" ; NET \"ABUS<15>\" LOC = \"P103\" ; NET \"ABUS<1>\" LOC = \"P61\" ; NET \"ABUS<2>\" LOC = \"P62\" ; NET \"ABUS<3>\" LOC = \"P63\" ; NET \"ABUS<4>\" LOC = \"P2\" ; NET \"ABUS<5>\" LOC = \"P108\" ; NET \"ABUS<6>\" LOC = \"P109\" ; NET \"ABUS<7>\" LOC = \"P112\" ; NET \"ABUS<8>\" LOC = \"P126\" ; NET \"ABUS<9>\" LOC = \"P127\" ; NET \"BH\" LOC = \"P138\" ; NET \"BL\" LOC = \"P137\" ; NET \"CLK\" LOC = \"P75\" ; NET \"CS\" LOC = \"P168\" ;
NET \"DBUS<0>\" LOC = \"P167\" ; NET \"DBUS<10>\" LOC = \"P123\" ; NET \"DBUS<11>\" LOC = \"P128\" ; NET \"DBUS<12>\" LOC = \"P132\" ; NET \"DBUS<13>\" LOC = \"P133\" ; NET \"DBUS<14>\" LOC = \"P134\" ; NET \"DBUS<15>\" LOC = \"P135\" ; NET \"DBUS<1>\" LOC = \"P165\" ; NET \"DBUS<2>\" LOC = \"P1\" ; NET \"DBUS<3>\" LOC = \"P163\" ; NET \"DBUS<4>\" LOC = \"P162\" ; NET \"DBUS<5>\" LOC = \"P161\" ; NET \"DBUS<6>\" LOC = \"P160\" ; NET \"DBUS<7>\" LOC = \"P153\" ; NET \"DBUS<8>\" LOC = \"P120\" ; NET \"DBUS<9>\" LOC = \"P122\" ; NET \"IR<0>\" LOC = \"P4\" ; NET \"IR<10>\" LOC = \"P22\" ; NET \"IR<11>\" LOC = \"P23\" ; NET \"IR<12>\" LOC = \"P24\" ; NET \"IR<13>\" LOC = \"P25\" ; NET \"IR<14>\" LOC = \"P28\" ; NET \"IR<15>\" LOC = \"P29\" ; NET \"IR<1>\" LOC = \"P5\" ; NET \"IR<2>\" LOC = \"P8\" ; NET \"IR<3>\" LOC = \"P9\" ; NET \"IR<4>\" LOC = \"P11\" ;
NET \"IR<5>\" LOC = \"P12\" ; NET \"IR<6>\" LOC = \"P15\" ; NET \"IR<7>\" LOC = \"P16\" ; NET \"IR<8>\" LOC = \"P18\" ; NET \"IR<9>\" LOC = \"P19\" ;
NET \"nABUS<0>\" LOC = \"P179\" ; NET \"nABUS<10>\" LOC = \"P115\" ; NET \"nABUS<11>\" LOC = \"P116\" ; NET \"nABUS<12>\" LOC = \"P119\" ; NET \"nABUS<13>\" LOC = \"P140\" ; NET \"nABUS<14>\" LOC = \"P144\" ; NET \"nABUS<15>\" LOC = \"P145\" ; NET \"nABUS<1>\" LOC = \"P178\" ; NET \"nABUS<2>\" LOC = \"P177\" ; NET \"nABUS<3>\" LOC = \"P172\" ; NET \"nABUS<4>\" LOC = \"P171\" ; NET \"nABUS<5>\" LOC = \"P151\" ; NET \"nABUS<6>\" LOC = \"P150\" ; NET \"nABUS<7>\" LOC = \"P147\" ; NET \"nABUS<8>\" LOC = \"P146\" ; NET \"nABUS<9>\" LOC = \"P113\" ; NET \"nBHE\" LOC = \"P83\" ; NET \"nBLE\" LOC = \"P98\" ; NET \"nDBUS<0>\" LOC = \"P31\" ; NET \"nDBUS<10>\" LOC = \"P47\" ; NET \"nDBUS<11>\" LOC = \"P48\" ; NET \"nDBUS<12>\" LOC = \"P49\" ; NET \"nDBUS<13>\" LOC = \"P50\" ; NET \"nDBUS<14>\" LOC = \"P55\" ; NET \"nDBUS<15>\" LOC = \"P56\" ; NET \"nDBUS<1>\" LOC = \"P33\" ; NET \"nDBUS<2>\" LOC = \"P34\" ; NET \"nDBUS<3>\" LOC = \"P35\" ; NET \"nDBUS<4>\" LOC = \"P36\" ; NET \"nDBUS<5>\" LOC = \"P39\" ; NET \"nDBUS<6>\" LOC = \"P40\" ; NET \"nDBUS<7>\" LOC = \"P41\" ; NET \"nDBUS<8>\" LOC = \"P42\" ; NET \"nDBUS<9>\" LOC = \"P45\" ; NET \"nMREQ\" LOC = \"P185\" ; NET \"nRD\" LOC = \"P82\" ; NET \"nWR\" LOC = \"P77\" ; NET \"RD\" LOC = \"P139\" ; NET \"RST\" LOC = \"P51\" ;
NET \"Ti<0>\" LOC = \"P196\" ; NET \"Ti<1>\" LOC = \"P193\" ; NET \"Ti<2>\" LOC = \"P192\" ; NET \"Ti<3>\" LOC = \"P190\" ; NET \"WR\" LOC = \"P152\" ;
2.测试程序
0111 mov R1,11
1188 sta (10001000),R1
0a88 lda R2,(10001000)
12 sta (10001001),R2
1b01 mov R3,R1
138a sta (10001011),R3
2401 mov R4,(R1)
148b sta (10001011),R4
2d80 mov R5,[R6//R7+80]
158c sta (10001100),R5
31f0 adc R1,1111000
1188 sta (10001000),R1
3a01 adc R2,R1
12 sta (10001001),R2
4101 sbb R1,01
1188 sta,(10001000),R1
4a01 sbb R2,R1
12 sta (10001001),R2
51ff and R1,ff
1188 sta,(10001000),R1
5a01 and R2,R1
12 sta (10001001),R2
6191 or R1,10010001
1188 sta (10001000),R1
6902 or,R1,R2
1188 sta (10001000),R1
7800 STC
3a01 adc R2,R1
12 sta (10001001),R2
3a01 adc R2,R1
7000 CLC
3a01 adc R2,R1
12 sta(10001001),R2
8000 JMP R7//00000000
注:JZ,JC不太容易与其他指令一起测试,故下面单独测试。
JZ JC测试程序: 0101 mov R1,1
4101 sbb R1,1
90FC JC -4
8802 JZ 2
88FF JZ FF
88FF JZ FF
4101 SBB R1,1
90FC JC -4
CPU总体波形测试程序:
0111 mov R1,11
0a88 sta(10001000),R1 1188 lda R2,(10001000) 1a01 mov R2,R1 2401 mov R4,(R1)
2d80 mov R5,[R6//R7+10000000] 31f0 adc R1,11110000 3a01 adc R2,R1
4101 sbb R1,00000001 4a01 sbb,R2,R1 51ff and R1,ff 5101 and R1,R2
6191 or R1,10010001 6902 or R1,R2 7000 clc 7800 stc
8081 jmp R7//10000001 8881 jz 9081 jc
六.设计、调试、波形、下载过程中遇到的问题及解决方法。
问题一:何时访存?访存的时候如何避免冲突?
解决方法:第一个节拍高电平访存取指,第二个节拍准备好访存的地址和需要与内存交换的数据,第三个节拍高电平发信号、访存。第四个节拍不访存。这样,就避免了对数据总线和地址总线的竞争。
问题二:如何对访存模块进行调试?
解决方法:由于在波形模拟的时候并没有真正与内存相连,所以只能在DBUS上人工置一个数。
问题三:波形调试正确,但是下载的时候不正确。
解决方法:检查了例化和管脚定义,发现管教定义出现问题。修改后下载过程依然有问题,于是开始检查代码。改变了代码的写法,突然就好使了。
七.总结与体会
通过这次计算设计与实践与课程,掌握了Xilinx ISE集成开发环境和ModelSim仿真工具的使用,通过自己对CPU的设计并将其实现,也使自己对VHDL语言和FPGA编程方法及调试手段有了更进一步的掌握,更加深刻的理解了处理器结构和计算机系统的整体原理。同时,也锻炼了自己的思维,提升了自己的信心。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务