CMP设计分享 http://blog.sciencenet.cn/u/accsys 没有逆向思维就没有科技原创。 不自信是科技创新的大敌。

博文

CPU设计我要让更多的人掌握它

已有 14000 次阅读 2010-1-2 08:00 |个人分类:计算机核|系统分类:科研笔记| CPU设计, 计算机核, 计算机核, 计算机核, 计算机核, FPGA, FPGA, FPGA, FPGA, 个人设计计算机, 个人设计计算机, 个人设计计算机, 个人设计计算机

姜咏江
 
“这个小小的芯片从国外购买的价格最高可以到几万元,占到整个服务器成本的70%以上。我们国家信息产业就是因为这项核心技术的缺失,基本没钱可赚,利润率只有2%到3%,还不如传统产业。国外大公司每年从中国赚走100多亿美元,比我国购买飞机、石油、汽车花的钱还要多。”这是中国“龙芯”芯片设计专家胡武伟某年月日说道一段话,是从网上搜到的。
 
发展我国自己的计算机芯片产业,要同时作两件事,一是发展超大规模集成电路制造技术,二是发展计算机核心芯片设计技术。前者个人无法办到,需要国家从战略的角度出钱购买技术设备,尽快创建我国自己的高端集成电路产业基地。后者如今可以通过个人的努力完全办到。
 
我国将计算机产业叫“高科技产业”,该产业这样叫,足显出我们过去对计算机制造业的无知和无能。过去,因为技术和设备的原因,我们一直没有能力去设计和制造计算机的核心部件。现在,芯片设计的基础技术发生了变化,有了可编程阵列器件FPGA/CPLD,个人设计计算机CPU芯片的时代已经到来了!
 
为了能够让更多的人进入计算机芯片设计行列,让更多的人掌握CPU的设计方法,我要借助于科学网,通过我的博客,将我的设计经验告诉那些有志于此项技术的初学者,将他们领进计算机核心设计的大门。
 
现在就开始!
 
1. CPU设计使用的软件和硬件
 
通过计算机进行CPU设计工作需要EDA软件,目前这种软件有几家公司的产品,这里就介绍自己常用的Altera公司的Quartus II吧。
 
Quartus II软件很人性化,电子电路产品的设计可以使用原理图方式,也可以使用硬件编程语言编程方式,还可以这两种设计方式混合使用。Quartus II构造的是一个电子电路设计的集成环境,可以很方便地进行电路设计的编辑、编译、仿真验证检查、下载到FPGA芯片上实际运行测试等。Altera公司还提供配套的电子电路设计开发板。其实,用买来的FPGA芯片,自己就可以制作开发板,或者干脆自己制作计算机。Altera公司的推荐的开发板DE2-70约售价5000元,DE1开发板要1000元左右。我主张自己做开发板,成本也就要几百元,还可以根据自己需要取材,当然这需要有一些电子电路制作方面的技术。
 
2. 软件人员搞CPU设计
 
我的经验是计算机软件人员可以从事CPU设计,甚至他们做起来要比学习电子电路的人员搞CPU设计更容易。因此我呼吁那些有抱负的软件科技人员,如果有能力,一定要进入CPU设计领域,因为“软硬件一体化”的计算机技术已经成为了计算机设计的主流。我先给你一个用Verilog HDL语言设计的例子。Verilog HDL语言借鉴了c语言,因而很适合软件工程师使用。找一本Verilog HDL语言的书看看,下面描述的能够运行程序的计算机核就可以弄懂了,或者看一下我写的《计算机原理综合课程设计》一书,也许会理解的更快。
 
2.1 最简单的计算机核设计
 
这里给出用Verilog HDL语言设计的一个能够运行简单程序的计算机核,是我在研究生班教学中作为设计实例完成的。这个设计已经在Quartus II软件的环境下测试通过,并且下载到自制的开发实验板上运行过。其中存储器是哈佛结构,直接使用了Quartus II给的存储器元件组织的。
【程序】 
//基本输入时钟clock
 
//复位控制:reset_n,低电位有效
 
//基本输出:o
 
//程序存储器iram,16位,高5位是类指令代码,用imem16.mif初始化
 
//数据存储器dram,16位,不用数据文件初始化
 
//用lpm存储器的地址信号要稳定1拍,才可以读写数据
 
//指令格式:高5位指令代码,11位地址码,16位立即数(分高低8位)
 
module test
 
(
 
clock,
 
reset_n,
 
o,
 
//调试输出(可以不要):
 
opc,
 
omar,
 
ojp,
 
oqw,
 
olda,
 
oadd,
 
oout
 
);
 
input clock;
 
input reset_n;
 
output [15:0] o;
 
output [15:0] oqw;
 
output [10:0] opc,omar;
 
output [2:0] ojp;
 
output olda,oadd,oout;
 
wire dwren;
 
wire [15:0] q_w;
 
wire [15:0] q_data;
 
reg [15:0] b,a,ir,da,oo,ddata;
 
reg [10:0] pc,mar;
 
reg [2:0] jp; //节拍
 
reg dwrit; //写控制
 
//指令:
 
reg  lda, //取数:从数据单元取数到da
 
add, //加:da与数据单元相加,结果放入da
 
out, //输出:将数据单元内容输出到输出寄存器
 
sdal, //低8位立即数:将8位立即数扩充为16位送da
 
sdah,//高8位立即数:将8位立即数作为高8位,与原da低8位连接成16位放在da中
 
str; //da送数据存储单元:
 
//仿真信号输出:
 
assign o = oo;
 
assign opc = pc;
 
assign omar = mar;
 
assign ojp = jp;
 
assign oqw = q_w;
 
assign olda=lda;
 
assign oadd=add;
 
assign oout=out;
 
assign dwren = dwrit;
 
//指令存储器:
 
lpm_rom iram(.address(pc),.inclock(clock),.q(q_w)); //程序存储器
 
defparam iram.lpm_width = 16;
 
defparam iram.lpm_widthad = 11;
 
defparam iram.lpm_outdata = "UNREGISTERED";
 
defparam iram.lpm_indata = "REGISTERED";
 
defparam iram.lpm_address_control = "REGISTERED";
 
defparam iram.lpm_file = "imem16.mif"; //初始化文件,放置程序
 
//数据存储器:
 
lpm_ram_dq dram(.data(ddata),.address(mar),.we(dwren),.inclock(clock),.q(q_data)); defparam dram.lpm_width = 16;
 
defparam dram.lpm_widthad = 11;
 
defparam dram.lpm_outdata = "UNREGISTERED";
 
defparam dram.lpm_indata = "REGISTERED";
 
defparam dram.lpm_address_control = "REGISTERED";
 
always @(posedge clock or negedge reset_n)
 
begin
 
if (!reset_n)
 
begin
 
pc <= 0;
 
lda <= 0;
 
add <= 0;
 
out <= 0;
 
sdal <= 0;
 
sdah <= 0;
 
str <= 0;
 
jp<=0;
 
end
 
else
 
begin
 
jp<=jp+1;
 
case (jp)
 
0: begin
 
    end
 
1: begin
 
    case (q_w[15:11])
 
    5'b00001: lda <= 1; //lda:00001
 
    5'b00010: add <= 1; //add:00010
 
    5'b00011: out <= 1; //out:00011
 
    5'b00100: sdal <= 1; //低8位,扩充有符号16位
 
    5'b00101: sdah <= 1; //高8位,与前面低8位输入合成16位
 
    5'b00110: str <= 1; //da送数据单元
 
    endcase
 
   end
 
2: begin
 
    if (lda || add || out || str)
 
    mar<=q_w[10:0];
 
    end
 
3: pc<=pc+1;
 
4: begin
 
    if (lda)
 
    begin
 
    da<=q_data;
 
    jp <= 0;
 
    lda<= 0;
 
    end
 
    else
 
    if (add)
 
    begin
 
    b<=q_data;
 
    a<=da;
 
    end
 
    else
 
    if (out)
 
    begin
 
    oo <= q_data;
 
    jp <= 0;
 
    out<= 0;
 
    end
 
    else
 
    if (sdal)
 
    begin
 
    da <= {{8{q_w[7]}},q_w[7:0]}; //扩充成16位有符号数
 
    sdal<= 0;
 
    end
 
    else
 
    if (sdah)
 
    begin
 
    da[15:0] <= {q_w[7:0],da[7:0]};
 
    sdah <= 0;
 
    end
 
    else
 
    if (str)
 
    begin
 
    ddata <= da;
 
    dwrit <= 1;
 
    end
 
    end
 
5: begin
 
    if (add)
 
    begin
 
    da<=a+b;
 
    jp <= 0;
 
    add<= 0;
 
    end
 
    else
 
    if (str)
 
    begin
 
    str <= 0;
 
    dwrit <= 0;
 
    end
 
    end
 
    endcase
 
    end
 
end
 
endmodule
 
///////////// 仿真或执行程序实例 ///////////
 
// 汇编                                        编译 //
 
// sdal 5                                    2005 //
 
// sdah 6                                   2806 //
 
// str 10                                     300a //
 
// sdal 3                                    2003 //
 
// add 10                                  100a //
 
// str 15                                     300f //
 
// out 15                                    180f //
 
//将编译的16进制数写入imem16.mif //
 
/////// 16进制结果输出:0608 /////////////
 
【练习】用本机语言自己编一个程序,自己编译,然后用Quartus II检验一下。
 
---    待续  ---


https://blog.sciencenet.cn/blog-340399-283456.html

上一篇:YOCSEF需要大胆深入一些
下一篇:CPU设计我要让更多的人掌握它(续1)
收藏 IP: .*| 热度|

5 杨新铁 李世春 秦川 理论思维 zhaowanfu

发表评论 评论 (6 个评论)

数据加载中...
扫一扫,分享此博文

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-19 07:51

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部