总算解决一大心头之患了,比想象中容易,通宵两夜,刷完了十个实验,这个实验就是最后的了。感慨颇多。特地写篇总结。

  • 想做一件事,就立马去做把。你会发现没那么困难,往往最大的困难,是心里的困难

  • 培养了HDL(Hardware Description Language)思维,并行串行混合。它先是一个电路,再才是一个程序电路为主,程序为辅,用RTL的思维去思考。

  • 这个实验也不怎么难,就是一个大的模拟题,当年ACM给我良好的代码功底受益颇多。

  • 能硬件级别揣摩CPU的一点点运行方式,但是还有很多疑问,需要看书去解决。

  • 这次的实验只是在心里面扎了一个种子(种子当然很重要啦~),需要看完CSAPP,和硬件/软件接口那两本书才能成长为苍天大树。

  • 实验驱动型+看书解决型,现阶段最好的学习方法了~

以下是本次实验的数据通路

module cpu

module cpu(clk,reset,ALU_OP,inst,rs,rt,rd,rs_data,rt_data,rd_data,ZF,OF,Write_Reg,PC,PC_new,rd_rt_s,W_Addr,imm,W_Data,imm_s,imm_data
,ALU_B,rt_imm_s,Mem_Write,M_R_Data,ALU_Data,alu_mem_s,w_r_s,wr_data_s,PC_s,address);
input wire clk;
input reset;
output [2:0] ALU_OP; //操作符
output [31:0] inst; //指令存放
output [4:0] rs; //rs地址
output [4:0] rt; //rt地址
output [4:0] rd; //rd地址
output [31:0] rs_data; //rs数据
output [31:0] rt_data; //rt数据
output [31:0] rd_data; //rd数据
output [31:0] PC;
output [31:0] PC_new;
output ZF;
output OF;
output Write_Reg; //是否写入
output [31:0] W_Data;
output rd_rt_s; //控制那个作为目的寄存器
output [4:0]W_Addr;//目的操作数地址
output [15:0] imm; //立即数
output [31:0] imm_data;//被扩展的立即数
output imm_s;//是否需要扩展
output rt_imm_s; //B端选择rt或者是imm
output [31:0] ALU_B; //ALU_B端口数据
output Mem_Write; //是否写入数据rom
output [31:0]M_R_Data;//从数据rom读出来的数据
output [31:0]ALU_Data;//ALU运算出来的结果,根据alu_mem_s选择由M_W_Data或者W_Data来赋值
output alu_mem_s;//看上面
output [1:0] w_r_s;
output [1:0] wr_data_s;
output [1:0] PC_s;//PC选择器
output [25:0] address;//地址解析数据
//读指令
ex7 pc (
.clka(clk),
.douta(inst),
.rst(reset),
.PC(PC),
.PC_new(PC_new),
.PC_s(PC_s),
.R_Data_A(rs_data),
.imm_data(imm_data),
.address(address)
//解析指令
);
analysis_inst analysis_inst(
.inst(inst),
.ALU_OP(ALU_OP),
.rs(rs),
.rt(rt),
.rd(rd),
.Write_Reg(Write_Reg),
.imm(imm),
.rd_rt_s(rd_rt_s),
.imm_s(imm_s),
.rt_imm_s(rt_imm_s),
.Mem_Write(Mem_Write),
.alu_mem_s(alu_mem_s),
.address(address),
.w_r_s(w_r_s),
.wr_data_s(wr_data_s),
.PC_s(PC_s),
.ZF(ZF)
);
//读取源操作数的值:
assign W_Addr = (w_r_s[1])?5'b11111:((w_r_s[0])?rt:rd);
assign imm_data = (imm_s)?{{16{imm[15]}},imm}:{{16{1'b0}},imm}; reg1 Reg(
.R_Addr_A(rs),
.R_Addr_B(rt),
.Clk(clk),
.W_Addr(W_Addr),
.W_Data(W_Data),
.R_Data_A(rs_data),
.R_Data_B(rt_data),
.Reset(reset),
.Write_Reg(Write_Reg) //不写入
);
assign ALU_B=(rt_imm_s)?imm_data:rt_data;
//对源操作数运算,存于目的操作数
ex3 ALU(
.ALU_OP(ALU_OP),
.A(rs_data),
.B(ALU_B),
.F(ALU_Data),
.ZF(ZF),
.OF(OF)
);
//----
wire clk_temp;
wire d_outn;
reg d_out=0;
assign clk_temp = clk ^ d_out ;
assign d_outn = ~d_out ;
//----
always@(posedge clk_temp)
begin
d_out <= d_outn ;
end
//数据存储器
Data_Rom Datarom (
.clka(clk_temp), // input clka
.wea(Mem_Write), // input [0 : 0] wea
.addra(ALU_Data[5:0]), // input [5 : 0] addra
.dina(rt_data), // input [31 : 0] dina
.douta(M_R_Data) // output [31 : 0] douta
);
assign W_Data = (wr_data_s[1])?PC_new:(wr_data_s[0]?M_R_Data:ALU_Data); endmodule

module pc

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 03:28:40 05/17/2016
// Design Name:
// Module Name: ex7
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ex7(clka,douta,rst,PC,PC_new,PC_s,R_Data_A,imm_data,address
);
input rst;
input clka;
input [1:0] PC_s;
output wire [31:0] douta;
output reg [31:0] PC;
output [31:0] PC_new;
input [31:0] R_Data_A;
input [31:0] imm_data;
input [25:0] address; wire [31:0]dina;
reg [0:0] wea=0;
assign PC_new=PC+4; ex77 regrom (
.clka(clka), // input clka
.wea(wea), // input [0 : 0] wea
.addra(PC[7:2]), // input [5 : 0] addra
.dina(dina), // input [31 : 0] dina
.douta(douta) // output [31 : 0] douta
);
always@(posedge rst or negedge clka)
begin
if(rst)
PC<=32'h00000000;
else
begin
case(PC_s)
2'b00: PC<=PC_new;
2'b01: PC<=R_Data_A;
2'b10: PC<=PC_new+(imm_data<<2);
2'b11: PC<={PC_new[31:28],address,2'b00};
endcase
end
end
endmodule

module analysis_inst

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 07:31:58 05/17/2016
// Design Name:
// Module Name: analysis_inst
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module analysis_inst(
inst,ALU_OP,rs,rt,rd,Write_Reg,imm,rd_rt_s,imm_s,rt_imm_s,Mem_Write,alu_mem_s,address,w_r_s,wr_data_s,PC_s,ZF
);
input [31:0] inst;
output reg [2:0] ALU_OP;
output reg [4:0] rs;
output reg [4:0] rt;
output reg [4:0] rd;
output reg Write_Reg;
output reg [15:0] imm;
output reg rd_rt_s;
output reg imm_s;
output reg rt_imm_s;
output reg Mem_Write;
output reg alu_mem_s;
output reg [25:0] address;
output reg [1:0] w_r_s;
output reg [1:0] wr_data_s;
output reg [1:0] PC_s;
input ZF;
always@(*)
begin
//--------------------处理R型指令----------------------
if(inst[31:26]==6'b000000) //判断是否为R型
begin
rd=inst[15:11]; //rd
rt=inst[20:16]; //rt
rs=inst[25:21]; //rs
w_r_s=2'b00;
imm_s=0;//此处无所谓
wr_data_s=2'b00;
// alu_mem_s=0;//此处废弃不用,被wr_data_s替代
Mem_Write=0;//是否写入数据存储器
//rd_rt_s=0;//rd作为目的存储器//此处废弃不用吧被w_r_s替代
rt_imm_s=0;//rt作为源操作数
case(inst[5:0]) //映射对应的ALU
6'b100000:begin ALU_OP=3'B100; Write_Reg=1;PC_s=2'b00;end
6'b100010:begin ALU_OP=3'B101; Write_Reg=1;PC_s=2'b00;end
6'b100100:begin ALU_OP=3'B000; Write_Reg=1;PC_s=2'b00;end
6'b100101:begin ALU_OP=3'B001; Write_Reg=1;PC_s=2'b00;end
6'b100110:begin ALU_OP=3'B010; Write_Reg=1;PC_s=2'b00;end
6'b100111:begin ALU_OP=3'B011; Write_Reg=1;PC_s=2'b00;end
6'b101011:begin ALU_OP=3'B110; Write_Reg=1;PC_s=2'b00;end
6'b000100:begin ALU_OP=3'B111; Write_Reg=1;PC_s=2'b00;end
6'b001000:begin ALU_OP=3'B100; Write_Reg=0;PC_s=2'b01;end
endcase
end
//------------------处理I型立即寻址指令------------------------
if(inst[31:29]==3'b001)
begin
imm=inst[15:0];
rt=inst[20:16]; //rt
rs=inst[25:21]; //rs
Mem_Write=0;//是否写入数据存储器
rd_rt_s=1;//rt作为目的存储器
rt_imm_s=1;//imm作为源操作数
// alu_mem_s=0;//以alu结果输出
w_r_s=2'b01;
Write_Reg=1;
wr_data_s=2'b00;
PC_s=2'b00;
//判断属于那条指令
case(inst[31:26])
6'b001000: begin imm_s=1; ALU_OP=3'B100;end
6'b001100: begin imm_s=0; ALU_OP=3'B000;end
6'b001110: begin imm_s=0; ALU_OP=3'B010;end
6'b001011: begin imm_s=0; ALU_OP=3'B110;end
endcase
end
//----------------处理I型取数/存数指令------------------
if(inst[31:30]==2'b10&&inst[28:26]==3'b011)
begin
imm=inst[15:0];
rt=inst[20:16]; //rt
rs=inst[25:21]; //rs
rd_rt_s=1;//rt作为目的存储器
rt_imm_s=1;//imm作为源操作数
imm_s=1;
w_r_s=2'b01;
wr_data_s=2'b01;
PC_s=2'b00;
//判断属于那条指令
//读取数据时,以mem输出的数据写入,所以alu_mem_s=1;
case(inst[31:26])
6'b100011: begin alu_mem_s=1; Mem_Write=0;Write_Reg=1;ALU_OP=3'B100;end
6'b101011: begin Mem_Write=1;Write_Reg=0;ALU_OP=3'B100;end
endcase
end
//----------------处理I型跳转指令------------------------
if(inst[31:27]==5'b00010)
begin
imm=inst[15:0];
rt=inst[20:16]; //rt
rs=inst[25:21]; //rs
case(inst[31:26])
6'b000100:begin rt_imm_s=0;ALU_OP=3'b101;Write_Reg=0;Mem_Write=0;PC_s=(ZF?2'b10:2'b00); end
6'b000101:begin rt_imm_s=0;ALU_OP=3'b101;Write_Reg=0;Mem_Write=0;PC_s=(ZF?2'b00:2'b10); end
endcase
end
//----------------处理J型跳转指令-------------------------
if(inst[31:27]==5'b00001)
begin
address=inst[25:0];
case(inst[31:26])
6'b000010:begin w_r_s=2'b00;Write_Reg=0;Mem_Write=0;PC_s=2'b11; end
6'b000011:begin w_r_s=2'b10;wr_data_s=2'b10;Write_Reg=1;Mem_Write=0;PC_s=2'b11; end
endcase
end
end
endmodule

module Reg

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 00:34:10 05/17/2016
// Design Name:
// Module Name: reg1
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module reg1(R_Addr_A,R_Addr_B,Clk,W_Addr,W_Data,R_Data_A,R_Data_B,Reset,Write_Reg
);
input Clk,Reset;
input wire Write_Reg;
input wire[4:0] R_Addr_A;
input wire[4:0] W_Addr;
input wire[4:0] R_Addr_B;
input wire[31:0] W_Data;
reg[31:0] REG_Files[31:0];
output wire[31:0] R_Data_A;
output wire[31:0] R_Data_B; integer i=0;
always @(posedge Clk or posedge Reset) //下降沿存储
begin
if(Reset) //初始化
begin
for(i=0;i<=31;i=i+1)
REG_Files[i]<=32'h00000000;
end
else
begin
if(Write_Reg)
REG_Files[W_Addr]<=W_Data;
end
end
assign R_Data_A=REG_Files[R_Addr_A];
assign R_Data_B=REG_Files[R_Addr_B];
endmodule

module ALU

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 14:06:30 03/31/2016
// Design Name:
// Module Name: ex3
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module ex3(ALU_OP,A,B,F,ZF,OF
);
input[2:0] ALU_OP;
input[31:0] A,B;
output reg [31:0] F;
output reg ZF,OF;
reg C32,C31;
reg [7:0]i;
always@(*)
begin case(ALU_OP)
3'b000:F=A&B;
3'b001:F=A|B;
3'b010:F=A^B;
3'b011:F=~(A|B);
3'b100:begin{C32,F}=A+B;OF=C32^A[31]^B[31]^F[31];end
3'b101:begin{C32,F}=A-B;OF=C32^A[31]^B[31]^F[31];end
3'b110:begin if(A<B)
F=1;
else
F=0;
end
3'b111:F=B<<A;
default: begin end
endcase ZF=((F==32'h00000000)?1:0);
end
endmodule

[计算机组成原理][实验十.R-I-J型指令CPU设计实验总结]的更多相关文章

  1. 重学计算机组成原理(十)- "烫烫烫"乱码的由来

    程序 = 算法 + 数据结构 对应到计算机的组成原理(硬件层面) 算法 --- 各种计算机指令 数据结构 --- 二进制数据 计算机用0/1组成的二进制,来表示所有信息 程序指令用到的机器码,是使用二 ...

  2. 重学计算机组成原理(五)- "旋转跳跃"的指令实现

    CPU执行的也不只是一条指令,一般一个程序包含很多条指令 因为有if-else.for这样的条件和循环存在,这些指令也不会一路平直执行下去. 一个计算机程序是怎么被分解成一条条指令来执行的呢 1 CP ...

  3. 计组CPU设计实验关键材料和关键设计

    我记得这是2016春季学期搞得,参考和学习了很多别人的东西,这里小小的总结一下,逻辑性还不是太强,还需要好好整理 首先是指令集 CPU架构 外部接线架构 指令格式 机器状态自动机 这部分忘了,汗 这部 ...

  4. 201671010456-张琼 实验十四 团队项目评审&课程学习总结

    博文简要信息表 项目 内容 这个作业属于哪个课程 http://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu- ...

  5. 201671030107 胡文艳 实验十四 团队项目评审&课程项目总结

    项目 内容 这个作业属于哪个课程 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 1.掌握软件项目评审会议流程 ...

  6. 201671030118 索郎卓玛 实验十四 团队项目评审&课程学习总结

    项目 内容 作业课程地址 任课教师首页链接 作业要求 团队项目评审&课程学习总结 课程学习目标 项目的验收以及课程的学习进行总结与反思 一 对<实验一 软件工程准备>的任务提出的问 ...

  7. 王天悦 201671030121 实验十四 团队项目评审&课程学习总结

    项目 内容 课程名称 2016级计算机科学与工程学院软件工程(西北师范大学) 作业要求 实验十四 团队项目评审&课程学习总结 课程学习目标 (1)掌握软件项目评审会流程,(2)反思总结课程学习 ...

  8. 201671030128周琳 实验十四 团队项目评审&课程学习总结

    项目 内容 这个作业属于哪个课程 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 掌握软件项目评审会流程:反思 ...

  9. 201671030126 赵佳平 实验十四 团队项目评审&课程学习总结

    项目 内容 这个作业属于那个课程 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 掌握软件项目评审会流程:反思 ...

随机推荐

  1. Eclipse,hadoop2.7.2 hadoop-eclipse-plugin.jar的制作

    装好了hadoop后发现有装个eclipse的必要,于是参照文章A(http://www.powerxing.com/hadoop-build-project-using-eclipse/)进行安装, ...

  2. css优先级计算

    主要的css选择器有id,class,tag,[],:,::等,而通常需要对其优先级进行判断的有id,class,tag,另外内联样式和!important也和css的优先级有关系. 如果将这五种不同 ...

  3. 学习OkHttp wiki--Interceptors

    Interceptors 拦截器(Interceptors)是一种强有力的途径,来监控,改写和重试HTTP访问.下面是一个简单的拦截器,对流出的请求和流入的响应记录日志. class LoggingI ...

  4. 业余编程 SQL 编程学习——1 (SQL Server 2008 R2)

    1.建立test数据库: 2.创建test1数据表: test1表属性如下: 其中,ID字段设置为标识增量,增量种子为1: 这个实例是实现从第一行数据开始,将每一行最后一个字段值加下一行第二个字段值再 ...

  5. struct可以拥有class般的构造函数

    struct A { int a, b; A(int x, int y) :a(x), b(y){} }; int main() { A a(1, 2); cout << a.a < ...

  6. MySQL 5.6 root密码丢失,使用mysqld --skip-grant-tables

    MySQL 5.6 root密码丢失,(window平台)使用mysqld –skip-grant-tables启动MySQL服务,出现警告: 1 [Warning] TIMESTAMP with i ...

  7. 在.NET MVC下不用iframe实现局部加载html

    最近在做个后台系统,之前都是用iframe来实现加载内容,左侧菜单不刷新.但一直不喜欢这种方法,有许多弊端.今天自己在网上查找了一番后找到了比较好的替代方案: 一.利用html的锚点标记来实现无刷新页 ...

  8. mysql分表方法实现

    一般来说,当我们的数据库的数据超过了100w记录的时候就应该考虑分表或者分区了,这次我来详细说说分表的一些方法.目前我所知道的方法都是MYISAM的,INNODB如何做分表并且保留事务和外键,我还不是 ...

  9. 『信息收集』GoogleHacking快速定位目标网站

    第一次接触到“GoogleHacking”是在学校初次Geek大赛上. 很有意思的一道题目,网页中原题大致是这样的: 下面是数学之美(吴军著)的封面,请找出这本书的ISBN码(这一关的Key值) 很不 ...

  10. Servlet 中的out.print()与out.writer()的区别

    PrintWriter out = response.getWriter(); out.print(obj)其源码如下: public void print(Object obj) { write(S ...