代码联系二维码免费获取。
1 x86的划时代意义(可跳过)
早期的IBM凭借大型机技术成为计算机市场的领头羊,直到后来个人计算机兴起,苹果公司诞生。但是,那个时候,无论是大型机还是个人计算机,每家的CPU架构都不一样。如果一直是这样,个人电脑、平板电脑、手机等等,都没办法形成统一的体系,就不会有我们现在通用的计算机了,更别提什么云计算、大数据这些统一的大平台了。
好在历史将x86平台推到了开放、统一、兼容的位置。我们继续来看IBM和x86的故事。
IBM开始做IBM PC时,一开始并没有让最牛的华生实验室去研发,而是交给另一个团队。一年时间,软硬件全部自研根本不可能完成,于是他们采用了英特尔的8088芯片作为CPU,使用微软的MS-DOS做操作系统。
谁能想到IBM PC卖的超级好,好到因为垄断市场而被起诉。IBM就在被逼的情况下公开了一些技术,使得后来无数IBM-PC兼容机公司的出现,也就有了后来占据市场的惠普、戴尔等等。
能够开放自己的技术是一件了不起的事。从技术和发展的层面来讲,它会使得一项技术大面积铺开,形成行业标准。就比如现在常用的Android手机,如果没有开放的Android系统,我们也没办法享受到这么多不同类型的手机。
对于当年的PC机来说,其实也是这样。英特尔的技术因此成为了行业的开放事实标准。由于这个系列开端于8086,因此称为x86架构。
后来英特尔的CPU数据总线和地址总线越来越宽,处理能力越来越强。但是一直不能忘记三点,一是标准,二是开放,三是兼容。因为如此大的一个软硬件生态都要基于这个架构,如果是封闭或者不兼容的,那谁都不答应。
2 自己设计简易版CPU原理
2.1 指令集设计
2.2 数据通路
3 VHDL代码实现
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