[计算机组成原理][实验十.R-I-J型指令CPU设计实验总结]
2016-06-01 02:53
891 查看
总算解决一大心头之患了,比想象中容易,通宵两夜,刷完了十个实验,这个实验就是最后的了。感慨颇多。特地写篇总结。
想做一件事,就立马去做把。你会发现没那么困难,往往最大的困难,是心里的困难。
培养了
这个实验也不怎么难,就是一个大的模拟题,当年ACM给我良好的代码功底受益颇多。
能硬件级别揣摩CPU的一点点运行方式,但是还有很多疑问,需要看书去解决。
这次的实验只是在心里面扎了一个种子(种子当然很重要啦~),需要看完CSAPP,和硬件/软件接口那两本书才能成长为苍天大树。
实验驱动型+看书解决型,现阶段最好的学习方法了~
以下是本次实验的
想做一件事,就立马去做把。你会发现没那么困难,往往最大的困难,是心里的困难。
培养了
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
相关文章推荐
- 相机标定
- Base64编码解码原理详解
- 线程池网络服务模型
- 网络设备中使用的算法
- 数据结构:模板实现栈和队列
- IOS网络——检测网络状态:Reachability
- 数据结构——链表实现通讯录
- 数据结构——栈
- http://www.cnblogs.com/worfdream/articles/1956449.
- 理解tomcat之搭建简易http服务器
- 基于Rsync算法的简单云盘实现(下)
- XMLHttpRequest设置超时
- THE SWIFT CODE之网络编程 NSURLSESSION
- Swift网络开发之NSURLSession学习笔记
- 千万级规模高性能、高并发的网络架构经验分享
- CornerStone使用教程(配置SVN,HTTP及svn简单使用)
- Retrofit缓存网络数据RxCache--RxJava和数据库
- Http格林尼治时间和毫秒的相互转化EEE, dd MMM y HH:mm:ss 'GMT'
- 通信协议之Http、TCP、UDP详解
- [javaSE] 网络编程(TCP服务端客户端互访阻塞)