精华内容
下载资源
问答
  • MIPS32位单周期CPU 32位MIPS单周期CPU 可以实现16条指令
  • 使用logisim布线完成的MIPS单周期CPU,可支持28条指令。跑马灯的代码已经装入了寄存器,可以直接开启时钟运行。
  • MIPS32位单周期CPU 32位MIPS单周期CPU 可以实现16条指令
  • 31条指令单周期CPU

    2018-12-08 00:00:34
    采用单周期方式实现了MIPS的31条指令,具体指令参见压缩包中的PDF文件。配有31条指令仿真测试的coe文件以及每一条指令单独测试文件和测试结果,在Vivado2016和Modelsim上验证通过。
  • 使用logisim布线完成的MIPS单周期CPU,可支持28条指令。跑马灯的代码已经装入了寄存器,可以直接开启时钟运行。
  • MIPS单周期CPU设计(24条指令)

    万次阅读 多人点赞 2020-07-22 21:14:25
    MIPS单周期可执行24条指令CPU 实验要求 本实训项目帮助学生构建支持 24 条指令的 MIPS 单周期 CPU ,最终实现的处理器能运行 benchmark 测试程序。~~另外希望学有余力的同学能为自己的处理器增加中断处理机制,能...

    MIPS单周期可执行24条指令CPU

    实验要求

    本实训项目帮助学生构建支持 24 条指令的 MIPS 单周期 CPU ,最终实现的处理器能运行 benchmark 测试程序。另外希望学有余力的同学能为自己的处理器增加中断处理机制,能响应外部设备中断请求。

    CPU 基本逻辑框架

    指令格式指令格式

    24条指令

    24条指令

    *为特殊格式指令


    指令详解

    R型

    R

    I型

    I

    J型

    J

    其中:

    在这里插入图片描述

    JumpAddr = ((PC + 4) & 0xf0000000) | ((address << 2) & 0x0ffffffc);
    

    设计硬布线

    ALU结构及规格

    ALU结构及规格

    Equal = (X == Y)?(1:0);
    

    控制信号

    控制信号产生条件控制信号产生条件

    ALU_OP及控制信号的确定

    根据 ALU 规格及控制信号产生条件即可得到下表,其中 X 代表无操作
    ALU_OP及控制信号
    根据 Logisim 分析组合逻辑电路功能可以自动生成控制器内部逻辑
    控制器逻辑

    设计数据通路

    因为是单周期 CPU,所有指令均在一个时钟周期内完成操作,所以指令与数据分别采用 ROM 及 RAM 存储

    • 取指

    • 取指

    指令存储器 ROM 容量为 1K * 32 bit

    由于指令存储器存储字长为 4B,而 PC 为指令字节地址,非指令字地址,故舍弃最低两位,将 2 ~ 11 位送入存储器地址端

    指令 IR 分线后送入单周期硬布线控制器译码,同时下一指令的地址通过多路选择器送入程序计数器的数据端口,等待时钟上升沿锁存

    PC下地址可通过下图产生,其中 X 代表该选择端无效:

    PC 下地址

    JMP_IF 为条件分支跳转成功信号,只响应 Beq 或 Bne 指令:
    J M P _ I F = B e q E q u a l + B n e E q u a l ‾ JMP\_IF = Beq Equal + Bne\overline{Equal} JMP_IF=BeqEqual+BneEqual

    PC = PC + 4;													// PC + 4, 无任何跳转
    PC = PC + 4 + (SignExtImm << 2);								// PC + imm,当 Beq 或 Bne 指令条件有效
    PC = ((PC + 4) & 0xf0000000) | ((address << 2) & 0x0ffffffc);	// PC_J_JAL, J 或者 Jal 指令
    PC = Reg[rs];													// PC_JR, JR指令
    
    • 执行

    执行

    Syscall 为系统调用指令,在该实验中,需要根据条件输出通用寄存器的值或产生停机信号:

    if ($v0 == 0x22)
        /* 若通用寄存器 $v0 的值为 0x22,则输出 LedData,而 LedData 由寄存器锁存通用寄存器 $a0 的值 */
        std::cout >> LedData;		 
    else{
        /* 否则,产生停机信号,程序不向下执行,直到 Go 按钮事件产生 */
        do{
            ;
        }while(Go != true );
    }
    
    1. A

      通用寄存器 V0 编号为 2a0 编号为 4,执行 syscall 指令时,多路选择器选择该组信号,其余指令选择 rs,rt

      通用寄存器 $ra 编号为 0x1f,记录返回地址,jal 指令可类比 x86 指令集中的 call 指令,所以该指令执行时,多路选择器选择 1 端口,写入寄存器 W# 选择 ra,将返回地址 PC + 4 写入寄存器文件(RegFile)

    2. B

      根据控制信号 AluSrcB 及 SignedExt 作为多路选择器选择端,算逻运算单元 ALU 的 B 端输入数据如下图:

    ALU B 端数据来源

    另外,(PC + imm)即为上文的具体实现

    1. C

      JMP_IF 信号上文已叙述

      PC_JR 为 JR 指令执行时,指令中通用寄存器 rs 的值,该值作为新的 PC

      • 执行 syscall 指令且通用寄存器 $v0 值不为 0x22 时,使停机信号 Halt 置 1 ,该信号经非门使程序计数器使能端置 0 ,将其封锁
      • 若 $v0 值为 0x22,则 LED 更换数据信号 LED_EN 置 1 ,在下一个时钟的上升沿将通用寄存器 $a0 值锁存至 LedData 寄存器中
    2. D

      数据存储器 RAM 的容量与指令 ROM 一致,均为 1K * 32 bit

      本实验唯一用到数据存储器 RAM 的指令只有 lwsw ,地址线依旧舍弃最低两位

      MDin 为寄存器文件输出端 R2 的值,在 sw 指令执行时, 通过 MemWrite 信号,在时钟上升沿将其写入 RAM 中

      与此类似, lw 指令执行时,多路选择器选择内存数据,送入寄存器文件 Din 端口,在时钟上升沿写入 RegFile

    备注

    CLK 为时钟信号,RESET 为测试时清空各寄存器及 RAM 信号

    最后完成的单周期 CPU

    完整 CPU 框架

    展开全文
  • 24条指令MIPS单周期CPU课设设计有这个压缩包足够
  • • 用硬件描述语言(Verilog)设计MIPS CPU,支持如下指令集 • ISA1 = {ADD/ADDU/SUB/SUBU/SLL/SRL/SRA/SLLV/SRLV/SRAV/AND/OR/XOR/NOR/ SLT/SLTU/ADDI/ADDIU/ANDI/ORI/XORI/LUI/SLTI/SLTIU/LB/LBU/LH/LH U/LW/SB/...
  • 31MIPS指令单周期CPU

    2019-03-25 00:36:18
    本科生计算机组成原理课程大作业,使用Xilinx N4开发板,实验实现:31MIPS指令单周期CPU 可通过前仿真但不能下板,原因未查明
  • 单周期CPU8指令实现

    2020-12-07 12:46:03
    【压缩包中含有完整代码】 计组实验课的Verilog代码实现单周期8指令CPU Ps:使用前先阅读readme 文件
  • 计算机组成原理课设要求做的31条单周期cpu,代码中有注释,可以根据需要适当修改
  • Verilog 单周期CPU代码 及汇编代码 完美运行各种代码
  • 我想问一下R型指令是通过什么特性实现单周期完成一条指令的。这张图想表现的延时该怎么实现![图片说明](https://img-ask.csdn.net/upload/201609/04/1472962909_703497.png)
  • ZJU计算机组成课程作业,内含各部件代码,支持18条指令,包括slt,lui,slr,sll,jr,jal等指令
  • 单指令周期CPU MIPS 移动操作指令

    代码放在github上
    在之前实现的基础上继续增加了移动操作指令(增加了特殊寄存器HI和LO,以及对他们的操作)
    之前操作的传送门:
    单指令周期ori指令的实现
    单指令周期CPU—–逻辑、移位操作和空指令

    指令简介

    MIPS指令集架构中定义6条移动操作指令:movn、movz、mfhi、mthi、mflo、mtlo

    后4条指令涉及对特殊寄存器HI、LO的读写操作

    HI、LO寄存器用于保存乘法、除法结果

    6条移动操作指令格式:
    这里写图片描述
    由指令格式可以看出指令码都是6’b000000(bit26\~31),由功能码(0\~5bit)判断是哪个指令,并且指令6~10bit都是0
    - movn(功能码是6’b001011):用法:movn rd, rs, rt;作用:if rt != 0 then rd <- rs(如果rt通用寄存器里的值不为0,则将地址为rs的通用寄存器的值赋值给地址为rd的通用寄存器)
    - movz(功能码是6’b001010):用法:movn rd, rs, rt;作用:if rt == 0 then rd <- rs(如果rt通用寄存器里的值为0,则将地址为rs的通用寄存器的值赋值给地址为rd的通用寄存器)
    - mfhi(功能码是6’b010010):用法:mflo rd 作用:rd <- lo将特殊寄存器HI的值赋给地址为rd的通用寄存器
    - mflo(功能码是6’b010000):用法 mflo rd 作用:rd <- lo将特殊寄存器LO的值赋给地址为rd的通用寄存器
    - mthi(功能码是6‘b010001):用法:mthi rs 作用:hi <- rs将地址为rs的通用寄存器的值赋给特殊寄存器HI
    - mtlo(功能码是6’b010011):用法:mtlo rs 作用:lo <- rs,将地址为rs的通用寄存器的值赋给特殊寄存器LO

    修改系统结构

    对之前的结构进行改变
    1. 增加HILO模块,实现HI、LO寄存器
    2. 增加执行模块EX的输入接口,接收从HILO模块传来的HI、LO寄存器的值;输出到WB模块是否要写HILO、写入HI寄存器的值、写入LO寄存器的值
    3. 增加回写模块WB的输入输出接口
    这里写图片描述

    添加HILO模块,实现HI、LO寄存器

    module hilo_reg(
        input wire clk,
        input wire rst,
    
        //写端口
        input wire we,
        input wire[`RegBus] hi_i,
        input wire[`RegBus] lo_i,
    
        //读端口
        output reg[`RegBus] hi_o,
        output reg[`RegBus] lo_o
    );
    always @(posedge clk)begin
      if(rst==`RstEnable) begin
        hi_o <= `ZeroWord;
        lo_o <= `ZeroWord;
      end else if(we == `WriteEnable) begin
        hi_o<=
      end
    end

    修改译码阶段的ID模块

    首先把移动操作这令的这六条指令的功能码和操作码以及操作类型的宏定义添加到defines.v文件中去:

    `define EXE_MOVZ  6'b001010     //指令MOVZ的功能码
    `define EXE_MOVN  6'b001011     //指令MOVN的功能码
    `define EXE_MFHI  6'b010000     //指令MFHI的功能码
    `define EXE_MTHI  6'b010001     //指令MTHI的功能码
    `define EXE_MFLO  6'b010010     //指令MFLO的功能码
    `define EXE_MTLO  6'b010011     //指令MTLO的功能码
    `define EXE_MOVZ_OP  8'b00001010
    `define EXE_MOVN_OP  8'b00001011
    `define EXE_MFHI_OP  8'b00010000
    `define EXE_MTHI_OP  8'b00010001
    `define EXE_MFLO_OP  8'b00010010
    `define EXE_MTLO_OP  8'b00010011
    `define EXE_RES_MOVE 3'b011 

    其次在译码模块ID中根据六条指令的功能码判断是那一条指令:
    这里写图片描述
    - MFLO和MFHI:将特殊寄存器LO和HI赋给通用寄存器,则可以知道肯定是要修改寄存器的即wreg_o为WriteEnable,而且不需要读取寄存器的值即reg1_read_o和reg2_read_o都为0,另外运算类型为EXE_RES_MOVE
    - MTHI和MTLO:将通用寄存器的值赋值给特殊寄存器LO和HI,则可知不需要修改通用寄存器的值即wreg_o为WriteDisable,需要读取端口1的寄存器的值,也就是指令中rs的值即reg1_read_o 为1,另外运算类型为EXE_RES_NOP
    - MOVN和MOVZ:需要读取rs,rt寄存器的值即reg1_read_o和reg2_read_o都为1,从端口1中读取rs寄存器(指令的21\~25bit)的值,从端口2中读取rt寄存器(指令第16\~20bit),判断读出的rt寄存器的值,根据rt寄存器的值是否为0,决定wreg_o为WriteEnable还是WriteDisable

            case(op)
                `EXE_SPECIAL_INST:  begin //SPECIAL
                    case(op2)
                        5'b00000: begin
                            case(op3)
                            ...
                                `EXE_MFHI: begin
                                    wreg_o <= `WriteEnable;
                                    aluop_o <= `EXE_MFHI_OP;
                                    alusel_o <= `EXE_RES_MOVE;
                                    reg1_read_o <= 1'b0;
                                    reg2_read_o <= 1'b0;
                                    instvalid <= `InstValid;    
                                    end
                                `EXE_MFLO: begin
                                    wreg_o <= `WriteEnable;
                                    aluop_o <= `EXE_MFLO_OP;
                                    alusel_o <= `EXE_RES_MOVE;
                                    reg1_read_o <= 1'b0;
                                    reg2_read_o <= 1'b0;
                                    instvalid <= `InstValid;    
                                    end
                                `EXE_MTHI: begin
                                    wreg_o <= `WriteDisable;
                                    aluop_o <= `EXE_MTHI_OP;
                                    reg1_read_o <= 1'b1;
                                    reg2_read_o <= 1'b0; 
                                    instvalid <= `InstValid;    
                                    end
                                `EXE_MTLO: begin
                                    wreg_o <= `WriteDisable;
                                    aluop_o <= `EXE_MTLO_OP;
                                    reg1_read_o <= 1'b1;
                                    reg2_read_o <= 1'b0; 
                                    instvalid <= `InstValid;    
                                end
                                `EXE_MOVN: begin
                                    aluop_o <= `EXE_MOVN_OP;
                                    alusel_o <= `EXE_RES_MOVE;
                                    reg1_read_o <= 1'b1;
                                    reg2_read_o <= 1'b1;
                                    instvalid <= `InstValid;
                                    if(reg2_o != `ZeroWord) begin //reg2_o的值为rt通用寄存器的值
                                        wreg_o <= `WriteEnable;
                                    end else begin
                                        wreg_o <= `WriteDisable;
                                    end
                                end
                                `EXE_MOVZ: begin
                                    aluop_o <= `EXE_MOVZ_OP;
                                    alusel_o <= `EXE_RES_MOVE;   
                                    reg1_read_o <= 1'b1;    
                                    reg2_read_o <= 1'b1;
                                    instvalid <= `InstValid;
                                    if(reg2_o == `ZeroWord) begin
                                        wreg_o <= `WriteEnable;
                                    end else begin
                                        wreg_o <= `WriteDisable;
                                    end                                 
                                end 
                                ....

    修改执行阶段EX模块

    • 首先得到最新的HI、LO的值
    always @ (*) begin
        if(rst == `RstEnable) begin
            {HI,LO} <= {`ZeroWord,`ZeroWord};
        end else begin
            {HI,LO} <= {hi_i,lo_i};         
        end
    end 
    • 针对不同的移动操作指令确定moveres的值,变量moveres存储的是移动操作指令的结果
    always @ (*) begin
        if(rst == `RstEnable) begin
            moveres <= `ZeroWord;
        end else begin
           moveres <= `ZeroWord;
           case (aluop_i)
            `EXE_MFHI_OP:       begin
                moveres <= HI;
            end
            `EXE_MFLO_OP:       begin
                moveres <= LO;
            end
            `EXE_MOVZ_OP:       begin
                moveres <= reg1_i;
            end
            `EXE_MOVN_OP:       begin
                moveres <= reg1_i;
            end
            default : begin
            end
           endcase
        end
    end  
    • 再在选择运算结果里添加依据EXE_RES_MOVE的运算类型,将moveres作为运算结果
    always @ (*) begin
        wd_o <= wd_i;       //要写的目的寄存器地址
        wreg_o <= wreg_i;
        case(alusel_i)
            ...
            `EXE_RES_MOVE:      begin
                wdata_o <= moveres;
            end 
            ...
        endcase
    end
    • 最后确定是否要写HI、LO寄存器,如果指令为MTHI何MTLO,则需要些HI、LO寄存器,则输出信号whilo_o为WriteEnable,根据是哪一条指令,制定reg1_i的值输出到HI和LO哪一寄存器
    always @ (*) begin
        if(rst == `RstEnable) begin
            whilo_o <= `WriteDisable;
            hi_o <= `ZeroWord;
            lo_o <= `ZeroWord;      
        end else if(aluop_i == `EXE_MTHI_OP) begin
            whilo_o <= `WriteEnable;
            hi_o <= reg1_i;
            lo_o <= LO;
        end else if(aluop_i == `EXE_MTLO_OP) begin
            whilo_o <= `WriteEnable;
            hi_o <= HI;
            lo_o <= reg1_i;
        end else begin
            whilo_o <= `WriteDisable;
            hi_o <= `ZeroWord;
            lo_o <= `ZeroWord;
        end             
    end 

    修改回写模块wb

    增加由执行模块传来的HI、LO特殊寄存器的数值和是否写入信息,根据传入信息传到HILO特殊寄存器

        always @ (*) begin
            if(rst == `RstEnable) begin
                wb_wd <= `NOPRegAddr;
                wb_wreg <= `WriteDisable;
                wb_wdata <= `ZeroWord;  
                wb_hi <= `ZeroWord;
                wb_lo <= `ZeroWord;
                wb_whilo <= `WriteDisable;
            end else begin
                wb_wd <= ex_wd;
                wb_wreg <= ex_wreg;
                wb_wdata <= ex_wdata;
                wb_hi <= ex_hi;
                wb_lo <= ex_lo;
                wb_whilo <= ex_whilo;   
            end    //if
        end      //always

    修改顶层模块openmips

    添加了HILO模块并且对多个模块的新增接口进行连接

    module openmips(
        input wire          clk,
        input wire          rst,
    
        input wire[`RegBus]         rom_data_i,
        output wire[`RegBus]        rom_addr_o,
        output wire                 rom_ce_o
    );
    //连接ID模块和EX模块
    wire[`AluOpBus] id_aluop;
    wire[`AluSelBus] id_alusel;
    wire[`RegBus] id_reg1;
    wire[`RegBus] id_reg2;
    wire          id_wreg;
    wire[`RegAddrBus] id_wd;
    //连接ID模块和Regfile模块
    wire reg1_read;
    wire reg2_read;
    wire[`RegBus] reg1_data;
    wire[`RegBus] reg2_data;
    wire[`RegAddrBus] reg1_addr;
    wire[`RegAddrBus] reg2_addr;
    //连接执行阶段与hilo模块的输出,即读取HI、LO寄存器
    wire[`RegBus]   hi;
    wire[`RegBus]   lo;
    //连接EX模块和WB模块
    wire ex_wreg;
    wire[`RegAddrBus] ex_wd;
    wire[`RegBus] ex_wdata;
    wire[`RegBus] ex_hi_o;
    wire[`RegBus] ex_lo_o;
    wire ex_whilo_o;
    //连接WB模块和Regfile模块
    wire[`RegAddrBus] wb_wd;
    wire wb_wreg;
    wire[`RegBus] wb_wdata;
    //连接WB模块和hilo_reg模块
    wire[`RegBus] wb_hi;
    wire[`RegBus] wb_lo;
    wire wb_whilo;
    //pc_reg real
    pc_reg pc_reg0(
        .clk(clk),  .rst(rst),  .pc(rom_addr_o),    .ce(rom_ce_o)
    );
    //ID real
    id id0(
        .rst(rst),  
        .pc_i(rom_addr_o), 
        .inst_i(rom_data_i),
        //来自Regfile模块的输入
        .reg1_data_i(reg1_data),    .reg2_data_i(reg2_data),
        //送到Regfile模块的信息
        .reg1_read_o(reg1_read),    .reg2_read_o(reg2_read),
        .reg1_addr_o(reg1_addr),    .reg2_addr_o(reg2_addr),
        //送到EX模块的信息
        .aluop_o(id_aluop),   .alusel_o(id_alusel),
        .reg1_o(id_reg1),     .reg2_o(id_reg2),
        .wd_o(id_wd),         .wreg_o(id_wreg)
    );
    //Regfile real
    regfile regfile1(
        .clk(clk),
        .rst(rst),
        //从WB模块传来信息
        .we(wb_wreg), .waddr(wb_wd),
        .wdata(wb_wdata),
        //ID模块传来的信息
        .re1(reg1_read),    .raddr1(reg1_addr), 
        .rdata1(reg1_data),
        .re2(reg2_read),    .raddr2(reg2_addr),
        .rdata2(reg2_data)
    );
    //EX real
    ex ex0(
        .rst(rst),
        //从ID模块传来的信息
        .aluop_i(id_aluop),   .alusel_i(id_alusel),
        .reg1_i(id_reg1),     .reg2_i(id_reg2),
        .wd_i(id_wd),         .wreg_i(id_wreg),
        //从hilo_reg模块传来的信息
        .hi_i(hi),
        .lo_i(lo),
        //送到WB模块的信息
        .wd_o(ex_wd),         .wreg_o(ex_wreg),
        .wdata_o(ex_wdata)
        .hi_o(ex_hi_o),
        .lo_o(ex_lo_o),
        .whilo_o(ex_whilo_o)
    
    );
    //WB real
    wb wb0(
        .rst(rst),
        .ex_wd(ex_wd),         .ex_wreg(ex_wreg),
        .ex_wdata(ex_wdata),
        .ex_hi(ex_hi_o),
        .ex_lo(ex_lo_o),
        .exwhilo(ex_whilo_o),
        .wb_wd(wb_wd),  .wb_wreg(wb_wreg),
        .wb_wdata(wb_wdata)
        .wb_hi(wb_hi),
        .wb_lo(wb_lo),
        .wb_whilo(wb_whilo)
    );
    hilo_reg hilo_reg0(
        .clk(clk),
        .rst(rst),
    
        //写端口
        .we(wb_whilo),
        .hi_i(wb_hi),
        .lo_i(wb_lo),
    
        //读端口1
        .hi_o(hi),
        .lo_o(lo)   
        );
    
    endmodule
    

    测试

       .org 0x0
       .set noat
       .global _start
    _start:
       lui $1,0x0000          # $1 = 0x00000000
       lui $2,0xffff          # $2 = 0xffff0000
       lui $3,0x0505          # $3 = 0x05050000
       lui $4,0x0000          # $4 = 0x00000000 
    
       movz $4,$2,$1          # $4 = 0xffff0000
       movn $4,$3,$1          # $4 = 0xffff0000
       movn $4,$3,$2          # $4 = 0x05050000
       movz $4,$2,$3          # $4 = 0x05050000
    
       mthi $0                # hi = 0x00000000
       mthi $2                # hi = 0xffff0000
       mthi $3                # hi = 0x05050000
       mfhi $4                # $4 = 0x05050000
    
       mtlo $3                # li = 0x05050000
       mtlo $2                # li = 0xffff0000
       mtlo $1                # li = 0x00000000
       mflo $4                # $4 = 0x00000000 

    经编译后得到用于指令寄存器的文件:

    3c010000
    3c02ffff
    3c030505
    3c040000
    0041200a
    0061200b
    0062200b
    0043200a
    00000011
    00400011
    00600011
    00002010
    00600013
    00400013
    00200013
    00002012

    仿真结果
    这里写图片描述

    展开全文
  • MIPS指令集的本文档为一份单周期CPU指令数据通路,内部部件连线,包括三种指令的数据通路
  • 2、单周期 CPU 是指一条指令的所有操作在一个时钟周期内执行完。设计中所有寄存器和存储器都是异步读同步写的,即读出数据不需要时钟控制,但写入数据需时钟控制。 故单周期 CPU 的运作即:在一个时钟周期内,根据 ...
  • 原理大家参照上一篇文章MIPS CPU单周期(8条指令)的设计,主要是还是两部分:控制器+数据通路。 传送门单周期8条指令 待会再更新哈,稍等稍等。 有问题可在下方评论或者私信q453682174. ...
    大家好,我是小黄鸭,文章下面有我的联系方式,有问题请私聊。
    

    原理大家参照上一篇文章MIPS CPU单周期(8条指令)的设计,主要是还是两部分:控制器+数据通路。
    传送门单周期8条指令

    单周期MIPS CPU 24条指令

    1. 总体结构设计
      单周期CPU设计实验我们首先设计一个硬布线控制器,利用硬布线控制器的设计原理,来实现一个支持24条指令的MIPS单周期CPU。利用在运算器实验和存储系统实验中构建的运算器、寄存器文件、存储系统等部件以及Logisim其他功能部件,来构建一个32位MIPS CPU单周期数据通路。
      在这里插入图片描述
    2. 数据通路的设计
      数据通路要将运算和功能部件进行连接,组成一个能个执行取值、译码、执行、进一步可能包含中断的数据连接,能够让指令从PC开始,流向各运算和功能部件,并成功指令相应的功能,给出相应的返回。并且数据通路要具备基本的CPU要求,能够形成相应的数据流和状态转移。
    展开全文
  • 31条指令单周期cpu设计(Verilog)-(二)总体设计

    万次阅读 多人点赞 2018-07-14 11:27:27
    31条指令单周期cpu设计(Verilog)-(一)相关软件 31条指令单周期cpu设计(Verilog)-(二)总体设计 31条指令单周期cpu设计(Verilog)-(三)指令分析 (重要) 31条指令单周期cpu设计(Verilog)-(四)数据输入输出关系表 ...
    • 目录

    31条指令单周期cpu设计(Verilog)-(一)相关软件

    31条指令单周期cpu设计(Verilog)-(二)总体设计

    31条指令单周期cpu设计(Verilog)-(三)指令分析                       (重要)

    31条指令单周期cpu设计(Verilog)-(四)数据输入输出关系表     (重要)

    31条指令单周期cpu设计(Verilog)-(五)整体数据通路图设计     (重要)

    31条指令单周期cpu设计(Verilog)-(六)指令操作时间表设计     (重要)

    31条指令单周期cpu设计(Verilog)-(七)整体代码结构                (重要)

    31条指令单周期cpu设计(Verilog)-(八)上代码→指令译码以及控制器(不重要)

    31条指令单周期cpu设计(Verilog)-(九)上代码→基本模块                  (不重要)

    31条指令单周期cpu设计(Verilog)-(十)上代码→顶层模块设计&总结

    • 说在前面

    开发环境:Vivado

    语言:Verilog

    cpu框架:Mips

    控制器:组合逻辑

    单周期处理器是指所有的指令在一个时钟周期内完成的处理器,尽管不同指令执行时间不同,但对单周期处理器而言,时钟周期必须设计成对所有指令都等长。在单周期处理器中,一条指令执行过程中数据通路的任何资源都不能被重复使用,因此,任何需要被多次使用的资源(如加法器)都需要设置多个,否则就会发生资源冲突。

    • 总体设计

    常规套路是从简单的八条指令cpu讲起,然后自己去扩展,31条指令cpu按照八条的那个流程来,无非是工作量大了点,网上八条指令cpu的教程也挺多的。

     

    指令介绍

    cpu的理论知识就不再多讲了,首先来看看我们要实现的31条指令。

     

    这些指令的详细介绍mips官方有给出:

    mips指令集

    在这部分(这个pdf带跳转功能的)

     

    在实现过程中,这31条指令看起来挺多,但是实际上部分指令的数据通路几乎一样,比如add---nor这几个,一定程度上减少了工作量。

    注意:这里面比较难的几条指令是lw,sw,jal

     

    设计流程

     

    1. 确定各条指令所需要的部件
    2. 确定各条指令中各个部件的输入输出关系
    3. 确定数据通路总图
    4. 根据各条指令所需要的部件以及总通路图,确定指令操作时间表(真值表)
    5. 根据指令操作时间表,设计控制器
    6. 根据总通路图以及指令操作时间表,码代码去,编写Verilog代码

     

    先放张总图压压

     

    1. PC存放指令地址(通过pc+4来读取下一条指令)
    2. (ram1)IMEM存放指令集
    3. 根据指令地址IMEM中取出对应指令
    4. 指令读取出来后送入指令译码器(具体是哪一条指令)
    5. 译码后将结果送入控制器,将该条指令相关部件的控制信号置为1(激活),使得cpu中该条指令的数据通路激活,进而执行此指令
    6. pc+4获取下一条指令,循环操作

    以上就是cpu的具体执行过程了,看起来还是挺简单的嘛。

     


     以上就是这节的内容了,下一节将具体介绍各条指令各个部件。

     

     

     

     

     

    展开全文
  • 包含华科计组实验 8条指令单周期cpu和多周期微程序地址转移,在同一个.circ文件中 包含24条指令cpu的.circ和excel的控制信号表,还有多周期微程序地址转移excel表。 还有相关的.jar等相关文件 以及包含24条指令cpu的...
  • 基于MIPS指令单周期CPU的课程设计,在Xilinx ISE14.6 环境下运行
  • 设计和实现一个支持如下十条指令单周期CPU。 非访存指令  清除累加器指令CLA  累加器取反指令COM  算术右移一位指令SHR:将累加器ACC中的数右移一位,结果放回ACC  循环左移一位指令CSL:对累加器中的数据...
  • 本次课程设计的基本任务是利用logisim平台设计构建一个32位 MIPS CPU 单周期处理器,要求支持24 MIPS 核心指令,最终设计实现的 MIPS 处理器能运行实验包中的 benchmark.asm。 课设设计报告如下: cpu设计...
  • 实验四、单周期 CPU 设计与实现——单指令 CPU

    千次阅读 多人点赞 2019-06-21 21:47:17
    实验四、单周期CPU设计与实现——单指令CPU 一、实验目的: 通过设计并实现支持一条指令的CPU,理解和掌握CPU设计的基本原理和过程。 二、实验内容: 设计和实现一个支持加法指令单周期CPU。要求该加法指令(表示...
  • 单周期24条指令.zip

    2020-07-02 17:21:19
    单周期CPU设计实验我们首先设计一个硬布线控制器,利用硬布线控制器的设计原理,来实现一个支持24条指令的MIPS单周期CPU。利用在运算器实验和存储系统实验中构建的运算器、寄存器文件、存储系统等部件以及Logisim...
  • 这对单周期CPU来说,这就变成不可能完成的指令了。以上 一个观点:所有的状态单元写端口一直都堵着数据,然而只有上升沿来到,状态单元才开始接纳这些数据 PS: 《计算机组成与设计:硬件/软件接口》 这本书很...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 79,155
精华内容 31,662
关键字:

单周期cpu基本7条指令