代码联系二维码免费获取。
早期的IBM凭借大型机技术成为计算机市场的领头羊,直到后来个人计算机兴起,苹果公司诞生。但是,那个时候,无论是大型机还是个人计算机,每家的CPU架构都不一样。如果一直是这样,个人电脑、平板电脑、手机等等,都没办法形成统一的体系,就不会有我们现在通用的计算机了,更别提什么云计算、大数据这些统一的大平台了。
好在历史将x86平台推到了开放、统一、兼容的位置。我们继续来看IBM和x86的故事。
IBM开始做IBM PC时,一开始并没有让最牛的华生实验室去研发,而是交给另一个团队。一年时间,软硬件全部自研根本不可能完成,于是他们采用了英特尔的8088芯片作为CPU,使用微软的MS-DOS做操作系统。
谁能想到IBM PC卖的超级好,好到因为垄断市场而被起诉。IBM就在被逼的情况下公开了一些技术,使得后来无数IBM-PC兼容机公司的出现,也就有了后来占据市场的惠普、戴尔等等。
能够开放自己的技术是一件了不起的事。从技术和发展的层面来讲,它会使得一项技术大面积铺开,形成行业标准。就比如现在常用的Android手机,如果没有开放的Android系统,我们也没办法享受到这么多不同类型的手机。
对于当年的PC机来说,其实也是这样。英特尔的技术因此成为了行业的开放事实标准。由于这个系列开端于8086,因此称为x86架构。
后来英特尔的CPU数据总线和地址总线越来越宽,处理能力越来越强。但是一直不能忘记三点,一是标准,二是开放,三是兼容。因为如此大的一个软硬件生态都要基于这个架构,如果是封闭或者不兼容的,那谁都不答应。
2.1 指令集设计
2.2 数据通路
3.1 设计的整体架构
图片有点模糊,只要观察到整体的设计感即可。
3.2 各模块的具体实现
3.2.1 计数器模块PC
时钟上升沿控制,从00000000开始计数,当LD_PC有效时计数加一,当Lod_PC有效时输出当前计数值。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity PC is
PORT (
reset,clk:in std_logic;
PC_in: in std_logic_vector(7 downto 0);PC_out: out std_logic_vector(7 downto 0);
Lod_PC,LD_PC:in std_logic
);end PC;
architecture PC_ar of PC is
signal data:std_logic_vector(7 downto 0):="00000000";
begin
process (clk,Lod_PC,LD_PC,reset)
begin
if reset='1' then
PC_out<="10000000";
else
if (clk'event and clk='1' and Lod_PC='1')then
data<=PC_in;
end if;
if(clk'event and clk='1' and LD_PC='1') then
data<=data+1;
end if;
end if;
PC_out<=data;
end process;
end PC_ar;
3.2.2 通用寄存器组模块common_reg
- 输入:RE为读控制信号,WE为写控制信号,WA[1…0]为寄存器编号00代表A,01代表B,10和11代表C,reg_in[7…0]为寄存器输入信号;
- 输出:reg_out[7…0]代表通用寄存器输出信号;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity common_reg is
port(RE,WE,clk:in std_logic;
WA:in std_logic_vector(1 downto 0);
RA:in std_logic_vector(1 downto 0);
reg_out:out std_logic_vector(7 downto 0);
reg_in:in std_logic_vector(7 downto 0);
reset:in std_logic
);
end common_reg;
architecture reg_ar of common_reg is
signal A:std_logic_vector(7 downto 0):="00000011";
signal B:std_logic_vector(7 downto 0):="10110100";
signal C:std_logic_vector(7 downto 0):="00000111";
begin
process(clk,WE,RE,reset)
begin
if reset='1' then
if(clk'event and clk='1') then
if(WE='1') then
if(WA="00") then
A<=reg_in;
reg_out<=A;
elsif(WA="01") then
B<=reg_in;
reg_out<=B;
elsif(WA="10" or WA="11") then
C<=reg_in;
reg_out<=C;
end if;
elsif (RE='1') then
if(RA="00") then
reg_out<=A;
elsif(RA="01") then
reg_out<=B;
elsif(RA="10" or RA="11") then
reg_out<=C;
end if;
end if;
end if;
else
reg_out<="00000000";
end if;
end process;
end reg_ar;
3.2.3 选择器模块xuanzeqi
lod为选择控制信号,lod=0时输出B,lod=1时输出A;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity xuanzeqi is
port(lod:in std_logic;
A,B: in std_logic_vector(7 downto 0);
data_out: out std_logic_vector(7 downto 0));
end xuanzeqi;
architecture xuanzeqi_ar of xuanzeqi is
signal temp:std_logic_vector(7 downto 0);
begin
process(lod,A)
begin
if(lod='1') then
temp<=A;
data_out<=temp;
else
temp<=B;
data_out<=temp;
end if;
end process;
end xuanzeqi_ar;
3.2.4 暂存器/指令寄存器IR模块:jicunqi
lod为选择控制信号,lod=1时输出jicun_in[7…0],lod=0时输出之前的值;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;
entity jicunqi is
port(lod,clk:in std_logic;
jicun_in: in std_logic_vector(7 downto 0);
jicun_out: out std_logic_vector(7 downto 0));
end jicunqi;
architecture jicunqi_ar of jicunqi is
signal temp: std_logic_vector(7 downto 0);
begin
process(clk,lod,jicun_in)
begin
if(clk'event and clk='1') then
if(lod='1') then
temp <= jicun_in;
jicun_out <= temp;
else
temp<=temp;
jicun_out <= temp;
end if;
end if;
end process;
end jicunqi_ar;
3.2.5 地址寄存器寄存器模块:MAR
Lod_MAR为选择控制信号,Lod_MAR=1时输出MAR_in[7…0],Lod_MAR=0时输出之前的值;
library ieee;
use ieee.std_logic_1164.all;
entity MAR is
port(
lod_MAR:in std_logic;
clk,reset:in std_logic;
MARin:in std_logic_vector(7 downto 0);
MARout:out std_logic_vector(7 downto 0)
);
end MAR;
architecture one of MAR is
signal MARsout:std_logic_vector(7 downto 0);
begin
process (clk)
begin
if reset='1' then MARout<="00000000";
else
if (clk'event and clk='1' and lod_MAR='1') then
MARout<=MARin;
end if;
end if;
end process;
end one;
3.2.6 内存模块:RAM
- cs为使能信号,cs=0输出高阻态
- dl,xl为读写控制信号,当xl为1时,将RAM_in[7…0]写入对应内存;当dl为1是,输出对应内存。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity RAM is
port(dl,xl,cs,clk:in std_logic;
RAM_in:in std_logic_vector(7 downto 0);
RAM_out:out std_logic_vector(7 downto 0)
);
end RAM;
architecture RAM_ar of RAM is
type ram is array(0 to 11) of std_logic_vector(7 downto 0); --12*8 ram
signal temp:std_logic_vector(7 downto 0);
begin
process(dl,xl,cs,clk)
variable r:ram;
begin
r(0):="00110001";r(1):="10010001";r(2):="01100001";r(3):="11100010";r(4):="0101000 r(5):="10100000";r(6):="10100011";r(7):="00010000";r(8):="00010001";r(9):="00010010";
r(10):="01110000";r(11):="10000000";
if(clk'event and clk='1' and cs='0') then
if(xl='1' and dl='0') then
r(conv_integer(RAM_in(7 downto 0))):=RAM_in ;
elsif(dl='1' and xl='0') then
temp <= r(conv_integer(RAM_in(7 downto 0))+7);
end if;
elsif (clk'event and clk='1' and cs='1') then
temp<="ZZZZZZZZ";
end if;
end process;
RAM_out <= temp;
end RAM_ar;
3.2.7 控制输入模块:putin
in_en为选择信号,当in_en=1时输出外部输入信号cin[7…0],当in_en=0时输出总线数据
library ieee;
use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;
entity putin is
port(in_en:in std_logic;
cin:in std_logic_vector(7 downto 0);aluin:in std_logic_vector(7 downto 0);
clk:in std_logic;cout:out std_logic_vector(7 downto 0));
end putin;
architecture putin_ar of putin is
begin
process(clk,in_en,cin)
begin
if(clk'event and clk='1') then
if in_en='1' then
cout<="00000111";
else
cout<=aluin;
end if;
end if;
end process;
end putin_ar;
3.2.8 运算模块:ALU
输入:
- M为使能信号,M=1时执行相应运算将结果输出,否则不执行运算
- S[3…0]为功能段,0011(MOV)直接输出A[7…0];
- 1001(ADD)计算A[7…0]+B[7…0];
- 0110(SUB)计算A[7…0]-B[7…0];
- 1110(AND)计算A[7…0] and B[7…0];
- 0101(NOT)计算not A[7…0];
- 1010(SH),0100(out)直接输出A[7…0];
输出:
- cout为加法运算进位;
- ALU_out[7…0]为运算器结果;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ALU is
port(M:in std_logic;
S:in std_logic_vector(3 downto 0);
A,B:in std_logic_vector(7 downto 0);
ALU_out:out std_logic_vector(7 downto 0);
cout:out std_logic);
end ALU;
architecture ALU_ar of ALU is
signal temp:std_logic_vector(8 downto 0);
begin
process(S,A,B)
begin
if(M='1') then
case S is
when "0011"=>
ALU_out<=A;
when "1001"=>
ALU_out<= A+B;
temp<=('0'&A)+('0'&B);
cout<=temp(8);
when "0110"=>
ALU_out<= A-B;
when "1110"=>
ALU_out<= A and B;
when "0101"=>
ALU_out<= not A;
when "1010"=>
ALU_out<= A;
when "0100"=>
ALU_out<= A;
when others =>NULL;
end case;
end if;
end process;
end ALU_ar;
3.2.9 移位运算模块:yiweiqi
- 输入:ywen为使能端,当ywen=0时,输出高阻;lod_yw为运算开关,lod_yw=1时进行移位运算,ywR2[1…0]为移位模式,ywR2[1…0]=00时右移,ywR2[1…0]=11时左移,其他情况时不进行移位操作直接输出;
- 输出:ywout[7…0]为移位运算结果。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ALU is
port(M:in std_logic;
S:in std_logic_vector(3 downto 0);
A,B:in std_logic_vector(7 downto 0);
ALU_out:out std_logic_vector(7 downto 0);
cout:out std_logic);
end ALU;
architecture ALU_ar of ALU is
signal temp:std_logic_vector(8 downto 0);
begin
process(S,A,B)
begin
if(M='1') then
case S is
when "0011"=>
ALU_out<=A;
when "1001"=>
ALU_out<= A+B;
temp<=('0'&A)+('0'&B);
cout<=temp(8);
when "0110"=>
ALU_out<= A-B;
when "1110"=>
ALU_out<= A and B;
when "0101"=>
ALU_out<= not A;
when "1010"=>
ALU_out<= A;
when "0100"=>
ALU_out<= A;
when others =>NULL;
end case;
end if;
end process;
end ALU_ar;
3.2.10 跳转控制模块:jump
- 输入:JMP、JZ、JC为移位控制信号,JMP=1时执行JMP指令,JZ=1时执行JZ指令,JC=1时执行JC指令; cout为运算结果,当JZ,JC有效时起作用; RAM_in[7…0]和address[7…0]分别为总线数据和目标地址;
- 输出:ywout[7…0]为移位运算结果。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity jump is
port(reset:in std_logic;
JMP,JZ,JC:in std_logic;
cout:in std_logic;
RAM_in:in std_logic_vector(7 downto 0);
address:in std_logic_vector(7 downto 0);
jump_O:out std_logic_vector(7 downto 0));
end jump;
architecture jump_ar of jump is
begin
process (JMP,JZ,JC,reset)
begin
if reset='1' then
jump_O<="00000000";
else
if JMP='1' then
jump_O<=address;
elsif JZ='1' then
if cout='0' then
jump_O<=address;
end if;
elsif JC='1' then
if cout='1' then
jump_O<=address;
end if;
else
jump_O<=RAM_in;
end if;
end if;
end process;
end jump_ar;
3.2.11 译码控制模块:yimaqi
- 输入:yimaqi_in[7…0]为输入的指令,address_i[7…0]为地址,跳转时有用,contclk为时钟控制信号。
- 输出:Lod_IR、DL、XL、CS、M、Lod_MAR、Lod_SA、Lod_SB、Lod_xa、Lod_xb、LD_PC、Lod_PC、RE、WE、S[3…0]、RA[1…0]、WA[1…0]、contR2、contlod_yw、contywen、address_o、NOP、reset、in_en、JMP、JZ、JC均为上述提到的控制信号。
控制信号的产生:
当我们从存储器中取指令到IR后,先对其进行译码操作,译码后可以对不同指令进行不同的执行方法,以调用相应的执行周期。如下为各指令的执行过程:
MOV R1,R2 ①SA<-R2 ②R1<-SA
MOV M,R2 ①SA<-R2 ②AR<-C ③M<-AR ④M<-SA
MOV R1,M ①AR<-C ②M<-AR ③R1<-M
ADD R1,R2和SUB R1,R2和AND R1,R2 ①SA<-R1 ②SB<-R2 ③R1<-SA+SB
NOT R1 ①SA<-R1 ②R1<-SA
SHR R1和SHL R1 ①SA<-R1 ②R1<-SH SA
JMP add ①AR<-PC ②M<-AR ③PC<-M
JZ add和JC add ①AR<-PC ②M<-AR ③PC<-M
IN R1 ①R1<-IN
OUT R1 ①SA<-R1
NOP ①PC<-PC+1
HALT ①HALT
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity yimaqi is
port(
contclk:in std_logic;
yimaqi_in:in std_logic_vector(7 downto 0);
address_i:in std_logic_vector(7 downto 0);
Lod_IR,DL,XL,CS,M,Lod_MAR,Lod_SA,Lod_SB,Lod_xa,Lod_xb,LD_PC,Lod_PC,RE,WE:out std_logic;
S:out std_logic_vector(3 downto 0);
RA,WA:out std_logic_vector(1 downto 0);
contR2:out std_logic_vector(1 downto 0);
contlod_yw:out std_logic;
contywen:out std_logic;
address_o:out std_logic_vector(7 downto 0);
NOP:out std_logic;
reset:out std_logic;
in_en:out std_logic;
JMP:out std_logic;
JZ:out std_logic;
JC:out std_logic);
end yimaqi;
architecture yimaqi_ar of yimaqi is
signal num:std_logic_vector(4 downto 0);
signal order:std_logic_vector(3 downto 0);
signal Rstart:std_logic_vector(1 downto 0);
signal Rend:std_logic_vector(1 downto 0);
begin
order<=yimaqi_in(7 downto 4);
Rstart<=yimaqi_in(3 downto 2);
Rend<=yimaqi_in(1 downto 0);
process(num,yimaqi_in,contclk)
begin
if(contclk'event and contclk='1') then
address_o<=address_i;
contywen<='0';
if (order="1000") then --关机
reset<='1';
else
if num="00000" then
Lod_PC<='1';
LD_PC<='0';
Lod_MAR<='1';
Lod_IR<='1';
Lod_xa<='1';
WE<='0';
RE<='0';
XL<='0';
DL<='1';
CS<='0';
JMP<='0';
JZ<='0';
JC<='0';
else
case num is
when "00110"=> --first step
if(order="0011") then --MOV第一步
if(Rstart="11" or Rend="11") then
WE<='0'; RE<='1';
RA<=Rend;--寄存器和内存之间需要读出通用寄存器C的值
WA<=Rend;
Lod_xb<='0'; --selects1
Lod_SB<='0'; --zcqb
Lod_SA<='0'; --zcqa M<='0'; --ALU
S<=order;
Lod_xa<='0'; --selects2
Lod_MAR<='1'; --MAR DL<='0'; --SRAM
xl<='0';
cs<='0';
contlod_yw<='0';
contR2<="00";
else WE<='0'; --第一步读出Rend中数据
RE<='1';
RA<=Rend;
WA<=Rstart;
Lod_xb<='0'; --selects1 Lod_SB<='0'; --zcqb
Lod_SA<='1'; --zcqa从选择器A过
M<='0'; --ALU不计算
S<=order;
Lod_PC<='0'; Ld_PC<='1'; Lod_xa<='0'; --selects2
Lod_MAR<='0'; --MAR DL<='0'; --SRAM
XL<='0';
CS<='0';
contlod_yw<='0';
contR2<="00";
end if;
elsif(order="0101") then --NOT第一步把R1拿出来
Lod_PC<='0'; --PC
Ld_PC<='0';
DL<='0'; --RAM
XL<='0';
CS<='0';
M<='1'; --ALU进行计算
S<=order;
RA<=Rstart; --tyjcqz
WA<="00";
RE<='1';
WE<='0';
Lod_SA<='1'; --zcq从选择器A过
Lod_SB<='0';
Lod_IR<='0'; --IR
Lod_MAR<='0'; --MAR
Lod_SB<='0'; --selector
Lod_xa<='0';
contlod_yw<='0';
contR2<="00";
elsif(order="1001" or order="0110" or order="1110") then
--AND SUB ADD 第一步取数
Lod_PC<='0'; --PC
Ld_PC<='0';
DL<='0'; --RAM
XL<='0';
CS<='0';
M<='0'; --ALU不计算
S<=order;
RA<=Rstart; --tyjcqz
WA<="00";
in_en<='0';
RE<='1';
WE<='0';
Lod_SA<='1'; --zcq
Lod_IR<='0'; --IR
Lod_MAR<='0'; --MAR
Lod_SB<='0'; --selector
Lod_xa<='0';
Lod_xb<='0';
contlod_yw<='0';
contR2<="00";
elsif(order="1010") then --SHL SHR
Lod_PC<='0'; --PC
Ld_PC<='0';
DL<='0'; --RAM
XL<='0';
CS<='0';
M<='1'; --ALU
S<=order;
RA<=Rstart; --tyjcqz
WA<="00";
RE<='1';
WE<='0';
Lod_SA<='1'; --zcq从选择器A过
Lod_SB<='0';
Lod_IR<='0'; --IR
Lod_MAR<='0'; --MAR
Lod_SB<='0'; --selector
Lod_xa<='0';
contlod_yw<='1';
contR2<=Rend; --00右移 11左移
contywen<='1';
elsif(order="0111") then --计数加一
NOP<='1';
Lod_PC<='0';
Ld_PC<='1';
elsif(order="0010") then --输入R1
in_en<='1';
WE<='1';
RE<='0';
WA<=Rstart;
RE<='0';
elsif(order="0100") then --输出寄存器R1
RE<='1';
WE<='0';
RA<=Rstart;
Lod_SA<='1';
M<='1';
elsif(order="0001") then --跳转
Lod_MAR<='1';
if Rend="00" then
JMP<='1';
elsif Rend="01" then
JZ<='1';
elsif Rend="10" then
JC<='1';
end if;
Lod_PC<='1';
Ld_PC<='0';
end if;
when "01000"=> --second step
if(order="0011") then --MOV第二步
if(Rstart="11" or Rend="11") then
--寄存器与内存之间 写回RAM
WE<='0'; --yujcqz
RE<='1';
RA<=Rend; --后两位所表示的寄存器的值送到RAM里
WA<=Rend; --tyjcq中的值,是后两位 Lod_xb<='0'; --selects1
Lod_SB<='0'; --zcqb
Lod_SA<='1'; --zcqa
M<='1'; --ALU
S<=order;
Lod_PC<='1';
Ld_PC<='0';
Lod_xa<='1'; --selects2
Lod_MAR<='1'; --MAR
DL<='1'; --SRAM
XL<='0';
CS<='0';
contlod_yw<='0';
contR2<="00";
else
WE<='1'; --yujcqz
RE<='0';
RA<=Rstart;
WA<=Rstart;
in_en<='0';
Lod_xb<='0'; --selects1
Lod_SB<='0'; --zcqb
Lod_SA<='0'; --zcqa
M<='1'; --ALU
S<=order;
Lod_PC<='0'; Ld_PC<='0';
Lod_xa<='0'; --selects2
Lod_MAR<='1'; --MAR
DL<='1'; --SRAM
XL<='0';
CS<='0';
contlod_yw<='0';
contR2<="00";
end if;
elsif(order="0101") then --NOT结果写入R1
Lod_PC<='0'; --PC
Ld_PC<='0';
DL<='0'; --RAM
XL<='0';
CS<='0';
M<='0'; --ALU进行计算
S<=order;
RA<="00"; --tyjcqz
WA<=Rstart;
RE<='0';
WE<='1';
in_en<='0';
Lod_SA<='0'; --zcq从选择器A过
Lod_SB<='0';
Lod_IR<='0'; --IR
Lod_MAR<='0'; --MAR
Lod_SB<='0'; --selector
Lod_xa<='0';
contlod_yw<='0';
contR2<="00";
elsif(order="1010") then --SHR SHL最后一步
DL<='0'; --RAM
XL<='0';
CS<='0';
M<='1'; --ALU
S<=order;
RA<="00"; --tyjcqz
WA<=Rstart;
RE<='0';
WE<='1';
Lod_SA<='0'; --zcq
Lod_SB<='0';
Lod_IR<='0'; --IR
Lod_MAR<='0'; --MAR
Lod_xb<='0'; --selector
Lod_xa<='0';
contlod_yw<='1';
contR2<=Rend;
elsif(order="1001" or order="0110" or order="1110") then
--AND SUB ADD 第二步取第二个数
DL<='0'; --RAM
XL<='0';
CS<='0';
M<='0'; --ALU
S<=order;
RA<=Rend; --tyjcqz
WA<="01";
RE<='1';
WE<='0';
Lod_SA<='0'; --zcq从SB过
Lod_SB<='1';
Lod_IR<='0'; --IR
Lod_MAR<='0'; --MAR
Lod_xb<='1'; --selector
Lod_xa<='0';
contlod_yw<='0';
contR2<="00";
end if;
when "01100"=> --third step
if(order="0011") then --MOV第3步
if(Rstart="11" or Rend="11") then
--寄存器与内存之间 写回RAM
WE<='1'; --yujcqz
RE<='0';
RA<=Rend;--后两位所表示的寄存器的值送到RAM WA<=Rstart; --tyjcq中的值,是后两位 Lod_xb<='0'; --selects1
Lod_SB<='0'; --zcqb
Lod_SA<='0'; --zcqa
Ld_PC<='0';
Lod_PC<='1';
M<='0'; --ALU
S<=order;
Lod_xa<='0'; --selects2
Lod_MAR<='0'; --MAR
DL<='0'; --SRAM
XL<='0';
CS<='0';
contlod_yw<='0';
contR2<="00";
end if;
elsif(order="1001" or order="0110" or order="1110") then --AND SUB ADD 第三步计算写回
DL<='0'; --RAM
XL<='0';
CS<='0';
M<='1'; --ALU
S<=order;
RA<="00"; --tyjcqz
WA<=Rstart;
RE<='0';
WE<='1';
Lod_SA<='0'; --zcq
Lod_SB<='0';
Lod_IR<='0'; --IR
Lod_MAR<='0'; --MAR
Lod_xb<='0'; --selector
Lod_xa<='0';
contlod_yw<='0';
contR2<="00";
else
Lod_xa<='1';
DL<='1';
end if;
when "01111"=> --fourth step
Lod_MAR<='1';
Lod_xa<='1'; --MAR
if(order="1010") then
contywen<='1';
end if;
when "10010"=>
if(order="1010") then
contywen<='0';
end if;
Lod_MAR<='1';
Ld_PC<='1';
Lod_PC<='0';
Lod_xa<='1';
DL<='1';
XL<='0';
CS<='0';
Lod_IR<='1';
num<="00000";
when others=> NOP<='0';reset<='0';
end case;
end if;
num<=num+"00001";
end if;
end if;
end process;
end yimaqi_ar;
4.1 测试环境
Quantus
4.2 测试结果
RAM中输出00110001对应MOV指令,将暂存器A中10110100数据存入寄存器B中,之后PC加一RAM输出10010001对应ADD指令,将暂存器A、B中数据10110100 10110100通过ALU计算的出结果01101000
RAM输出01100001,对应指令SUB,将暂存器A、B中的值00000011 10110100通过ALU计算并存入通用寄存器A中;之后PC加一,RAM输出11100010对应AND指令,将将暂存器A、B中的值01001111 00000111通过ALU进行and运算并存入通用寄存器A中。
RAM输出01010001对应NOT指令,将通用寄存器A读入暂存器A中,再将暂存器中数据00000011通过ALU取反存进通用寄存器A中;之后PC加一RAM输出10100000对应指令SHR,将通用寄存器A读入暂存器A中,再将暂存器中数据11111100通过yiwei_ALU右移输出01111110,存入寄存器A中
RAM输出10100011对应SHL指令,将通用寄存器A读入暂存器A中,再将暂存器中数据00000011通过yiwei_ALU左移存进通用寄存器A中;
RAM输出10100011对应SHL指令,将通用寄存器A读入暂存器A中,再将暂存器中数据00000011通过yiwei_ALU左移存进通用寄存器A中;
RAM输出00010000对应JMP指令,将地址寄存器中的地址00001110取出作为跳转的目标地址,使PC跳转。同理00010001对应JZ指令,当ALU结果为0时PC跳转到address;00010010对应JC指令,当ALU运算结果有进位时PC跳转到address。
RAM输出00100000对应IN指令,将拨码开关输入(cin=“00000000”)送入通用寄存器A中。
RAM输出01000000对应OUT指令,通用寄存器A中数据00000011输出。
RAM输出01110000对应NOP指令,PC+1进入下一条指令;之后RAM输出10000000进入关机状态,所有的器件输出都一直保持在初始状态不动。
- CPU的设计主要由控制器模块、选择器模块、存储器模块组成,其中控制器模块和数据通路模块是关键。在实现译码的过程时,要分清每一条指令的执行步骤,在不同的步骤里将相应的器件导通或者关闭。
- 想要实现条件跳转,必须得有信号量,只得再次改运算模块,使之有进位,并判断是否为0,最后连接到大模块中实现跳转。
- 当有多个期间的输出要连接到总线中时,需要将这些器件在控制信号无效时输出高阻,否则编译会报错。
- 由于每一个时序逻辑器件都需要一个时钟周期来执行,所以在每一个步骤之间要有分配有足够的时钟周期以便使数据能够正确的传输到相应的位置。
- 调试每一条指令时一定要有耐心,将中间控制信号输出可以有效的帮助我们进行调试。 同一个信号不能够在不同的进程中进行赋值。