2021-09-09

MIPS指令 31条多周期CPU(Verilog)

注意

这是本人大二《计算机组成与系统结构》实验的期末课设,毕业答辩时拿了95分。以下代码为全部代码,可直接使用,并带有CPU仿真代码,额外带有冒泡排序的汇编代码及其对应的机器代码作为该CPU的测试指令。

实验目的

(1)认识和掌握多周期数据通路原理及其设计方法;
(2)掌握多周期CPU的实现方法,代码实现方法;
(3)初步掌握了MARS的使用,将MIPS汇编程序编译为二进制机器码;
(4)掌握多周期CPU的测试方法。

实验内容

1、实验原理:
多周期CPU指的是将整个CPU的执行过程分成几个阶段,每个阶段用一个时钟去完成,然后开始
下一条指令的执行,而每种指令执行时所用的时钟数不尽相同,这就是所谓的多周期CPU。CPU
在处理指令时,一般需要经过以下几个阶段:
(1) 取指令(IF):根据程序计数器pc中的指令地址,从存储器中取出一条指令,同时,pc根据指令字长度自动递增产生下一条指令所需要的指令地址,但遇到“地址转移”指令时,则控制器把“转移地址”送入pc,当然得到的“地址”需要做些变换才送入pc。
(2)指令译码(ID):对取指令操作中得到的指令进行分析并译码,确定这条指令需要完成的操
作,从而产生相应的操作控制信号,用于驱动执行状态中的各种操作。
(3)指令执行(EXE):根据指令译码得到的操作控制信号,具体地执行指令动作,然后转移到
结果写回状态。
(4) 存储器访问(MEM):所有需要访问存储器的操作都将在这个步骤中执行,该步骤给出存储器的数据地址,把数据写入到存储器中数据地址所指定的存储单元或者从存储器中得到数据地址单元中的数据。
(5) 结果写回(WB):指令执行的结果或者访问存储器中得到的数据写回相应的目的寄存器中。
2、实验步骤:
(1)先将寄存器模块、PC模块、ALU模块、IR模块、指令存储器模块、扩展器模块、数据存储器模块、Br模块及各个多路选择器模块搭建好。
(2)编写控制模块,输出所有的控制信号。
(3)编写顶层模块,构建数据通路。
(4)测试指令,验证CPU的正确性:

31条指令为:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码

## 顶层模块
 `timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/05/30 18:34:50
// Design Name: 
// Module Name: main
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module main(
input clk,
output [2:0]state,
output [31:0] alu_a,
output [31:0] alu_b,
output [3:0]aluctr,
output [31:0]da,
output [31:0]db,
output [31:0]OP,
output rd,
output pcwr,
output pcwrcond,
output [1:0]pcsource,
output irwr,
output [31:0]i_pc,
output [31:0]o_pc,
output [31:0] aluout
    );
   
    wire [31:0] din,dout,outdata1,dw,py,pc0,outdata,outbr,insout;
    wire [4:0]rw;
    wire [1:0]alusela,aluselb,regdst,memtoreg;
    wire extop,brwr,regwr,memwr,overflow,Z,zero;
    parameter [31:0]si=4;
    parameter [4:0]ssy=5'b11111;          
    assign outdata1=outdata<<2;
    assign pc0={o_pc[31:28],OP[25:0],2'b0};
    assign py={27'b0,OP[10:6]};
 
    CU CU1(clk,OP[31:26],OP[5:0],zero,alusela,aluselb,extop,pcsource,brwr,regwr,regdst,memtoreg,irwr,memwr,rd,pcwr,aluctr,pcwrcond,state,Z);
    PC PC1(clk,i_pc,pcwr,pcwrcond,Z,o_pc);
    RAM RAM1(aluout,db,memwr,dout);
    ROM ROM1(rd,o_pc,insout);
    Br Br1(aluout,clk,brwr,outbr);
    IR IR1(clk,insout,irwr,OP);
    Extend Extend1(OP[15:0],extop,outdata);
    mux35 mux351(OP[20:16],OP[15:11],ssy,regdst,rw);
    mux3_2 mux3_21(aluout,dout,o_pc,memtoreg,dw);
    RegFile RegFile1(OP[25:21],OP[20:16],rw,dw,regwr,overflow,da,db);
    mux3_1 mux3_11(o_pc,da,py,alusela,alu_a);
    mux4 mux41(db,si,outdata,outdata1,aluselb,alu_b);
    alu alu1(alu_a,alu_b,aluctr,aluout,zero,overflow);
    mux4_1 mux4_11(pc0,aluout,outbr,da,pcsource,i_pc);
   
endmodule

## 控制模块
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/05/30 17:52:14
// Design Name: 
// Module Name: CU
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module CU(
input clk,
input [5:0] op,
input [5:0] func,
input zero,
//output [2:0] ALUop,
//output reg RTypes,
output reg [1:0]ALUSelA,
output reg [1:0]ALUSelB,
output reg ExtOp,
output reg [1:0]PCSource,
output reg BrWr,
output reg RegWr,
output reg [1:0]RegDst,
output reg [1:0]MemtoReg,
output reg IRWr,
output reg MemWr,
output reg IorD,
output reg PCWr,
output reg [3:0] ALUCtr,
output reg PCWrCond,
output reg[2:0]state,

output reg Z
    );
    //reg PCWr=0;
    parameter [2:0] s00=3'b000,
                     sif=3'b001,//?
                     sid=3'b010,
                     sexe=3'b011,
                     smem=3'b100,
                     swb=3'b101;
     //reg [2:0] state=3'b0;
     reg [2:0] next_state;
     wire i_add,i_addu,i_sub,i_subu,i_lw,i_sw,i_beq,i_j,i_ori,i_addi,
          i_and,i_or,i_xor,i_nor,i_slt,i_sltu,i_sll,i_srl,i_sra,i_sllv,
          i_srlv,i_srav,i_jr,i_addiu,i_andi,i_xori,i_lui,i_bne,i_slti,i_sltiu,i_jal;
     wire [3:0]addu,subu,add,sub,OR,AND,XOR,NOR,slt,sltu,sll,srl,sra,lui;
     assign addu=4'b0000;
     assign subu=4'b0100;
     assign add=4'b0001;
     assign sub=4'b0101;
     assign AND=4'b0011;
     assign OR=4'b0010;
     assign XOR=4'b0110;
     assign NOR=4'b0111;//或非
     assign slt=4'b1001;
     assign sltu=4'b1010;
     assign sll=4'b1011;
     assign srl=4'b1100;
     assign sra=4'b1101;
     assign lui=4'b1110;
    assign i_add=(op[5:0]==6'b000000&&func[5:0]==6'b100000)?1:0;
    assign i_addu=(op[5:0]==6'b000000&&func[5:0]==6'b100001)?1:0;
    assign i_sub=(op[5:0]==6'b000000&&func[5:0]==6'b100010)?1:0;
    assign i_subu=(op[5:0]==6'b000000&&func[5:0]==6'b100011)?1:0;
    assign i_and=(op[5:0]==6'b000000&&func[5:0]==6'b100100)?1:0;
    assign i_or= (op[5:0]==6'b000000&&func[5:0]==6'b100101)?1:0;  
    assign i_xor=(op[5:0]==6'b000000&&func[5:0]==6'b100110)?1:0;
    assign i_nor=(op[5:0]==6'b000000&&func[5:0]==6'b100111)?1:0;
    assign i_slt=(op[5:0]==6'b000000&&func[5:0]==6'b101010)?1:0;
    assign i_sltu=(op[5:0]==6'b000000&&func[5:0]==6'b101011)?1:0;
    assign i_sll=(op[5:0]==6'b000000&&func[5:0]==6'b000000)?1:0;
    assign i_srl=(op[5:0]==6'b000000&&func[5:0]==6'b000010)?1:0;
    assign i_sra=(op[5:0]==6'b000000&&func[5:0]==6'b000011)?1:0;
    assign i_sllv=(op[5:0]==6'b000000&&func[5:0]==6'b000100)?1:0;
    assign i_srlv=(op[5:0]==6'b000000&&func[5:0]==6'b000110)?1:0;
    assign i_srav=(op[5:0]==6'b000000&&func[5:0]==6'b000111)?1:0;
    assign i_jr=(op[5:0]==6'b000000&&func[5:0]==6'b001000)?1:0;
  //17  
    assign i_addi=(op[5:0]==6'b001000)?1:0;
    assign i_addiu=(op[5:0]==6'b001001)?1:0;
    assign i_andi=(op[5:0]==6'b001100)?1:0;
    assign i_ori=(op[5:0]==6'b001101)?1:0;
    assign i_xori=(op[5:0]==6'b001110)?1:0;
    assign i_lui=(op[5:0]==6'b001111)?1:0;
    assign i_lw=(op[5:0]==6'b100011)?1:0;
    assign i_sw=(op[5:0]==6'b101011)?1:0;
    assign i_beq=(op[5:0]==6'b000100)?1:0;
    assign i_bne=(op[5:0]==6'b000101)?1:0;
    assign i_slti=(op[5:0]==6'b001010)?1:0;
    assign i_sltiu=(op[5:0]==6'b001011)?1:0;
//12
    assign i_j=(op[5:0]==6'b000010)?1:0;
    assign i_jal=(op[5:0]==6'b000011)?1:0;
//2
     
     initial
     begin
     state=s00;
     PCWr=0;
     IRWr=0;
     MemWr=0;
     RegWr=0;
     PCWrCond=0;
     BrWr=0;
     IorD=0;
     PCSource=2'b00;
     Z=zero;
     //ALUCtr=0;
     end
     
     always@(zero or state)
     begin
     case(state)
     s00:begin0
          PCWr=1;
          PCSource=2'b01;
     next_state=sif;   
     end
   
     sif:begin ///1
     PCWr=1;
     BrWr=0;
     PCSource=2'b01;
     IRWr=1;
     IorD=1;//?
     MemWr=0;
     ALUSelA=2'b00;
     ALUSelB=2'b01;
     ALUCtr=addu;
     RegWr=0;
     next_state=sid;
     end
     sid:begin  2
     PCWr=0;
     BrWr=1;
     IRWr=0;
     PCWrCond=0;
     Z=zero;
     MemWr=0;
     ALUSelA=2'b00;
     ALUSelB=2'b11;
     ALUCtr=addu;
     IorD=0;
     ExtOp=1;
     RegWr&
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用python中的pymsql完成如下:表结构与数据创建 1. 建立 `users` 表和 `orders` 表。 `users` 表有用户ID、用户名、年龄字段,(id,name,age) `orders` 表有订单ID、订单日期、订单金额,用户id字段。(id,order_date,amount,user_id) 2 两表的id作为主键,`orders` 表用户id为users的外键 3 插入数据 `users` (1, '张三', 18), (2, '李四', 20), (3, '王五', 22), (4, '赵六', 25), (5, '钱七', 28); `orders` (1, '2021-09-01', 500, 1), (2, '2021-09-02', 1000, 2), (3, '2021-09-03', 600, 3), (4, '2021-09-04', 800, 4), (5, '2021-09-05', 1500, 5), (6, '2021-09-06', 1200, 3), (7, '2021-09-07', 2000, 1), (8, '2021-09-08', 300, 2), (9, '2021-09-09', 700, 5), (10, '2021-09-10', 900, 4); 查询语句 1. 查询订单总金额 2. 查询所有用户的平均年龄,并将结果四舍五入保留两位小数。 3. 查询订单总数最多的用户的姓名和订单总数。 4. 查询所有不重复的年龄。 5. 查询订单日期在2021年9月1日至9月4日之间的订单总金额。 6. 查询年龄不大于25岁的用户的订单数量,并按照降序排序。 7. 查询订单总金额排名前3的用户的姓名和订单总金额。 8. 查询订单总金额最大的用户的姓名和订单总金额。 9. 查询订单总金额最小的用户的姓名和订单总金额。 10. 查询所有名字中含有“李”的用户,按照名字升序排序。 11. 查询所有年龄大于20岁的用户,按照年龄降序排序,并只显示前5条记录。 12. 查询每个用户的订单数量和订单总金额,并按照总金额降序排序。
最新发布
06-03

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值