精华内容
下载资源
问答
  • 单周期处理器(CPU),支持以下指令:lw、sw、beq、addi、add、sub、and、or、slt。使用的开发环境是vivado,文件在压缩包中的single_cycle_processor.xpr内。压缩包内有单周期CPU的示意图。
  • 单周期处理器

    2018-07-08 16:19:57
    Verilog编程下的单周期处理器,实现基本的几条指令,单周期处理器由数据通路和控制器组成。采用模块化和层次化设计。
  • 【计组实验】P1 logisim完成单周期处理器开发 MIPS指令集-附件资源
  • 北航 机组 Project3 Logisim完成单周期处理器开发,供学弟学妹参考!
  • 自己设计的MIPS单周期微处理器,基于Verilog语言实现,只是针对某一问题设计的,因此指令数目较少,无法解决一些复杂问题
  • 用HDL开发7条指令的单周期处理器,包括指令集,并列出指令集的编码,详细给出设计实验的步骤,数据通路里面必要的部件列表,给出数据通路设计表格
  • 实现了一些指令的单周期ARM微处理器,可以在modelsim中进行仿真
  • 单周期处理器,就是每条指令都在一个时钟周期执行完任务,就是这个时钟周期很长很长,CPI是1,时钟频率是很低的,单周期处理器按照袁春风版的电路图,大概是像王道里面那个硬布线控制器(也就是组合逻辑控制)一样,...
    1. 多周期处理器
      多周期处理器就是书上最常见的那种,每条指令需要多个机器周期(比如取指周期,间址周期,执行周期,中断周期),然后每个机器周期又需要若干的时钟周期,这就是王道书上讲的那种。
    2. 单周期处理器
      单周期处理器,就是每条指令都在一个时钟周期执行完任务,就是这个时钟周期很长很长,CPI是1,时钟频率是很低的,单周期处理器按照袁春风版的电路图,大概是像王道里面那个硬布线控制器(也就是组合逻辑控制)一样,按照电路逻辑设计好每条指令的对应信号(电路学过一点,但是实在太费劲了)所有的控制信号在译码之后都同时产生了控制信号,这就是拿到408真题里面单周期处理器指令执行过程控制信号不变,王道讲了个鬼,写什么控制信号是pc,(这里的控制信号按我理解就是读写控制信号这一类,就王道书上那个硬布线的微操作命令信号)
      另外408这题里面选项,单总线结构,我认为是在说cpu内部单总线结构,这就一个时钟周期,cpu内部单总线里面好多的微操作就有问题了。

    袁春风版的单周期处理器,从大佬那粘来滴,电路学的一塌糊涂实在看不懂了,存个档等我能看懂再来。就暂时理解为硬布线电路那种控制信号早就设计好了不需要在执行时变化
    在这里插入图片描述
    自用存档,有错误欢迎指正。

    展开全文
  • 计算机组成原理复习资料,画出了重点的笔记,包括MIPS单周期处理器设计和流水线两份
  • 基于verilog的单周期处理器设计

    千次阅读 2020-05-06 17:37:47
    单周期处理器是指取指译码等操作在一个时钟周期内完成。本单周期处理器支持R型指令add,addu,sub,subu,slt,sltu;I型指令ori,lw,sw,beq,bne,移位指令sll,srl,sra指令;J型指令的J指令和Jr指令。单周期处理器设计包括两...

    单周期处理器是指取指译码等操作在一个时钟周期内完成。本单周期处理器支持R型指令add,addu,sub,subu,slt,sltu;I型指令ori,lw,sw,beq,bne,移位指令sll,srl,sra指令;J型指令的J指令和Jr指令。单周期处理器设计包括两大部分设计,一个是控制部件的设计,另一个是数据通路的设计。
    设计整体框图如下:
    在这里插入图片描述

    顶层模块如下

    module SingleCycleCpu(clk,rst_n);
    
    input clk;
    input rst_n;
    
    wire [31:0] instruction;
    wire RegDst;
    wire beq;
    wire bne;
    wire Jump;
    wire ExtOp;
    wire ALUSrc;
    wire [3:0] ALUctr;
    wire MemWr;
    wire RegWr;
    wire MemtoReg;
    wire jr;
    
    
    Controler Controler(
    		.instruction(instruction),
    		.RegDst(RegDst),
    		.bne(bne),
    		.beq(beq),
    		.Jump(Jump),
    		.ExtOp(ExtOp),
    		.ALUSrc(ALUSrc),
    		.ALUctr(ALUctr),
    		.MemWr(MemWr),
    		.RegWr(RegWr),
    		.MemtoReg(MemtoReg),
    		.jr(jr)
    );
    
    
    SingleDataPath  SingleDataPath(
    		.clk(clk),
    		.rst_n(rst_n),
    		.RegDst(RegDst),
    		.RegWr(RegWr),
    		.Jump(Jump),
    		.ExtOp(ExtOp),
    		.ALUSrc(ALUSrc),
    		.ALUctr(ALUctr),
    		.MemWr(MemWr),
    		.MemtoReg(MemtoReg),
    		.instruction(instruction),
    		.bne(bne),
    		.beq(beq),
    		.jr(jr)
    );
    
    
    endmodule 
    

    指令存储器设计如下

    module RomNoDelay(
       input clk,
       input [7:0] RdAddr,
       output [31:0] RdData
    );
      reg [31:0] rom [255:0];
      
      initial begin
         $readmemh("F:/work/digital_system_practise/data_path/rtl/inst_rom.data",rom);
      end 
      
      assign RdData  = rom[RdAddr];
    
    endmodule
    

    数据存储器设计如下

    module RamNoDelay(
      input clk,
      input wen,
      input [7:0] WrAddr,
      input [31:0] WrData,
      input [7:0] RdAddr,
      output [31:0] RdData
    );
     
     reg [31:0] ram [255:0];
     always@(posedge clk)begin
       if(wen)
         ram[WrAddr] <= WrData;
     end 
     
     assign RdData = ram[RdAddr];
    
    endmodule
    

    寄存器堆设计如下

    module dflipflop(
                 input          clk,
    				 input  [4:0]  	Ra,
    				 input  [4:0]   Rb,
    				 input  [4:0]   Rw,
    				 input          Wen,
    				 output [31:0]  BusA,
    				 output [31:0]  BusB,
    				 input  [31:0]  BusW
    );
    				 
    				 reg    [31:0]DataReg[31:0];			 
    	
    
    	            always@(posedge clk)
    		        begin	
    			         if(Wen & Rw!=5'd0)
    			        	DataReg[Rw] <= BusW;
    		        end		
    	
    	            assign BusA = (Ra==5'd0)?32'd0:DataReg[Ra];
    	            assign BusB = (Rb==5'd0)?32'd0:DataReg[Rb];
    		
    endmodule
    

    alu的框图如下:
    在这里插入图片描述
    alu模块代码如下:

    module alu(
      input [31:0] alu_DA,
      input [31:0] alu_DB,
      input [3:0] alu_CTL,
      input [4:0] alu_SHIFT,
      output alu_ZERO,
      output alu_Overflow,
      output reg [31:0] alu_DC 
    );
        
      /******************general ctr ****************************/
      wire SUBctr;
      wire SIGctr;
      wire Ovctr;
      wire [1:0] Opctr;
      wire [1:0] Logicctr;
      wire [1:0] Shiftctr;
      
      assign SUBctr = ((~alu_CTL[3]) &  ~alu_CTL[2] & alu_CTL[1])|(alu_CTL[3] & ~alu_CTL[2]);
      assign Opctr = alu_CTL[3:2];
      assign Ovctr = (alu_CTL[0] & ~alu_CTL[3] & ~alu_CTL[2])|(alu_CTL[3] & ~alu_CTL[2] & ~alu_CTL[1] & alu_CTL[0]);
      assign SIGctr = alu_CTL[0];
      assign Logicctr = alu_CTL[1:0];
      assign Shiftctr = alu_CTL[1:0];
    
      /*****************logic op****************************/
      reg [31:0] logic_result;
      
      always@(*)begin
        case(Logicctr)
    	   2'b00:logic_result = alu_DA & alu_DB;
    	   2'b01:logic_result = alu_DA | alu_DB;
    	   2'b10:logic_result = alu_DA ^ alu_DB;
    	   2'b11:logic_result = ~(alu_DA | alu_DB);
    	endcase
      end
      
      /********************shift op****************************/
      wire [31:0] shift_result;
      
      Shifter Shifter(
          .alu_DB(alu_DB),
          .ALUSHIFT(alu_SHIFT),
          .Shiftctr(Shiftctr),
    	  .shift_result(shift_result)
      ); 
      
      /************************add sub op*********************************/
      wire [31:0] BIT_M,XOR_M;
      wire ADD_carry,ADD_OverFlow;
      wire [31:0] ADD_result;
      wire [31:0] comp_M;
      assign BIT_M = {32{SUBctr}};
      assign XOR_M = (alu_DB[31] && SUBctr)?{1'b0,alu_DB[30:0]}:BIT_M ^ alu_DB;
      assign comp_M = (alu_DB[31] && SUBctr)?XOR_M: XOR_M + SUBctr;
      assign alu_Overflow = ADD_OverFlow & Ovctr;
      assign {ADD_carry,ADD_result} = alu_DA + comp_M;
      assign  ADD_OverFlow = (alu_DA[31] && comp_M[31] && !ADD_result[31]) +
                              (!alu_DA[31] && !comp_M[31] && ADD_result[31]); 
      assign alu_ZERO = (|ADD_result)?1'b0:1'b1;
      /****************************slt op****************************/
      wire [31:0] SLT_result;
      wire LESS_M1,LESS_M2,LESS_S,SLT_M;
      
      assign LESS_M1 = ADD_carry ^ SUBctr;
      assign LESS_M2 = ADD_OverFlow ^ ADD_result[31];
      assign LESS_S = (SIGctr == 1'b0)?LESS_M1:LESS_M2;
      assign SLT_result = (LESS_S)?32'hffff_ffff:32'h0000_0000;
      
      /****************************ALU_result***************************/
      always@(*)
      begin
        case(Opctr)
    	  2'b00:alu_DC = ADD_result;
    	  2'b01:alu_DC = logic_result;
    	  2'b10:alu_DC = SLT_result;
    	  2'b11:alu_DC = shift_result;	  
    	endcase
      end
     
    endmodule 
    

    移位器设计如下:

    module Shifter(
      input [31:0] alu_DB,
      input [4:0] ALUSHIFT,
      input [1:0] Shiftctr,
      output reg  [31:0] shift_result
    );
      
      wire [5:0] shift_n;
      assign shift_n = 6'd32 - ALUSHIFT;
      always@(*)begin
         case(Shiftctr)
    	     2'b00:  shift_result = alu_DB << ALUSHIFT;
    		 2'b01:  shift_result = alu_DB >> ALUSHIFT;
    		 2'b10:  shift_result = ({32{alu_DB[31]}} << shift_n) | (alu_DB >> ALUSHIFT);
    		default: shift_result = alu_DB;
    	 endcase
      end 
    
    endmodule 
    

    取指令部件的框图
    在这里插入图片描述
    取指令部件模块的代码

    module if_fetch(
       input rst_n,
       input clk,
       input jump,
       input beq,
       input bne,
       input zero,
       input jr,
       input [31:0] BusA,
       output [31:0] ins   
    );
    
    reg  [29:0] PC;
    wire [29:0] PC_next;
    wire [29:0] PC_sel;
    wire [29:0] PC_Branch;
    wire [29:0] PC_INC;
    wire [15:0] imme;
    
    RomNoDelay RomNoDelay(
       .clk(clk),
       .RdAddr(PC[7:0]),
       .RdData(ins)
    );
    
    always@(posedge clk or negedge rst_n)
       if(!rst_n)
         PC <= 30'd0;
       else 
         PC <= PC_next;
    	 
    
    assign imme = ins[15:0];
    assign PC_INC  =  PC + 1'b1;   
    assign PC_Branch  =  PC_INC + {{14{imme[15]}},imme};    
    assign PC_sel  =  ((beq && zero) || (bne && !zero))?PC_Branch:PC_INC;    
    assign PC_next = (jump)?{PC[29:26],ins[25:0]}
                     :(jr)? BusA[31:2]
    				     :PC_sel;
    
    endmodule 
    
    
    
    

    数据通路模块的代码如下

    module SingleDataPath(
    		clk,
    		rst_n,
    		RegDst,
    		RegWr,
    		Jump,
    		ExtOp,
    		ALUSrc,
    		ALUctr,
    		MemWr,
    		MemtoReg,
    		instruction,
    		bne,
    		beq,
    		jr
    );
    
    input clk;
    input rst_n;
    input RegDst;
    input RegWr;
    input Jump;
    input ExtOp;
    input ALUSrc;
    input [3:0]ALUctr;
    input MemWr;
    input MemtoReg;
    input bne;
    input beq;
    input jr;
    output [31:0]instruction;
    
    
    wire zero;
    wire [31:0]instruction;
    wire [4:0] Rw;
    wire Rwen;
    wire [31:0] BusA;
    wire [31:0] BusB;
    wire [31:0] BusBm;
    wire [31:0] BusW;
    wire [31:0] ALU_DC;
    wire [31:0]RdData;
    wire overflow;
    wire [31:0] Extimme;
    
    
    wire [4:0] Rs;
    wire [4:0] Rt;
    wire [4:0] Rd;
    wire [4:0] shift;
    wire [15:0] imme;
    
    assign Rs = instruction[25:21];
    assign Rt = instruction[20:16];
    assign Rd = instruction[15:11];
    assign shift = instruction[10:6];
    assign imme = instruction[15:0];
    assign Rw = (RegDst)?Rd:Rt;
    assign Rwen = (~overflow) & RegWr;
    assign BusW = (MemtoReg)?RdData:ALU_DC;
    assign Extimme = (ExtOp)?{{16{imme[15]}},imme}:{16'b0,imme};
    assign BusBm = (ALUSrc)?Extimme:BusB;
    
    alu alu(
    	  .alu_DA(BusA),
    	  .alu_DB(BusBm),
    	  .alu_CTL(ALUctr),
    	  .alu_SHIFT(shift),
    	  .alu_ZERO(zero),
    	  .alu_Overflow(overflow),
    	  .alu_DC(ALU_DC)
    );
    
    dflipflop regfile( 
             .clk(clk),
    		 .Ra(Rs),
    		 .Rb(Rt),
    		 .Rw(Rw),
    		 .Wen(Rwen),
    		 .BusA(BusA),
    		 .BusB(BusB),
    		 .BusW(BusW)
    );
    
    
    if_fetch if_fetch(
    	   .rst_n(rst_n),
    	   .clk(clk),
    	   .jump(Jump),
    	   .beq(beq),
    	   .bne(bne),
    	   .zero(zero),
    	   .jr(jr),
    	   .BusA(BusA),
    	   .ins(instruction)  
    );
    
    RamNoDelay RamNoDelay(
         .clk(clk),
    	  .wen(MemWr),
    	  .WrAddr(ALU_DC),
    	  .WrData(BusB),
    	  .RdAddr(ALU_DC),
    	  .RdData(RdData)
    );
    
    endmodule 
    

    控制部件的模块代码如下

    module Controler(
        instruction,
        RegDst,
        bne,
    	 beq,
        Jump,
        ExtOp,
        ALUSrc,
        ALUctr,
        MemWr,
    	 RegWr,
        MemtoReg,
    	 jr
    );
    
    input [31:0] instruction;
    output RegDst;
    output beq;
    output bne;
    output Jump;
    output ExtOp;
    output ALUSrc;
    output [3:0] ALUctr;
    output MemWr;
    output RegWr;
    output MemtoReg;
    output jr;
    
    wire [5:0] op;
    wire [5:0] func;
    wire R_type;
    wire [3:0] aluOp1;
    wire [3:0] aluOp2;
    
    
    assign op = instruction[31:26];
    assign func = instruction[5:0];
    assign jr = ((op == 6'b000000) && (func == 6'b001000));
    
    maincontrol maincontrol(
    		.op(op),
    		.RegDst(RegDst),
    		.beq(beq),
    		.bne(bne),
    		.Jump(Jump),
    		.ExtOp(ExtOp),
    		.ALUSrc(ALUSrc),
    		.aluOp(aluOp1),
    		.MemWr(MemWr),
    		.RegWr(RegWr),
    		.MemtoReg(MemtoReg),
    		.R_type(R_type)
    );
    
    aluControl aluControl(
    	   .func(func),
    	   .aluOp(aluOp2)
    );
    
    assign ALUctr = (R_type)?aluOp2:aluOp1;
    
    				
    endmodule 
    
    module maincontrol(
        op,
    	RegDst,
    	beq,
    	bne,
    	Jump,
    	ExtOp,
    	ALUSrc,
    	aluOp,
    	MemWr,
    	MemtoReg,
    	RegWr,
    	R_type
    );
    
    input [5:0] op;
    output RegDst;
    output RegWr;
    output Jump;
    output ExtOp;
    output ALUSrc;
    output [3:0] aluOp;
    output MemWr;
    output MemtoReg;
    output R_type;
    output beq;
    output bne;
    
    wire ls;
    wire lw = (op == 6'b100011);
    wire sw = (op == 6'b101011);
    wire beq1 = (op == 6'b000100);
    wire bne1 = (op == 6'b000101);
    wire j = (op == 6'b000010);
    wire ori = (op == 6'b001101);
    
    assign R_type = (op == 6'b000000);
    assign RegDst = R_type;
    assign RegWr = R_type | lw | ori;
    assign beq = beq1; 
    assign bne = bne1;
    assign Jump = j;
    assign ExtOp = lw | sw;
    assign ALUSrc = lw | sw | ori;
    assign MemWr  = sw;
    assign MemtoReg = lw;
    assign ls = lw | sw;
    
    assign aluOp =  ({4{ls}}&4'b0001) | ({4{beq}}& 4'b0011) | ({4{bne}}& 4'b0011)|({4{ori}}& 4'b0101);
    				
    endmodule 
    
    module aluControl(
       input [5:0] func,
       output [3:0] aluOp
    );
    
    wire add = (func == 6'b100000);
    wire addu = (func == 6'b100001);
    wire sub = (func == 6'b100010);
    wire subu = (func == 6'b100011);
    wire and1 = (func == 6'b100100);
    wire or1 = (func == 6'b100101);
    wire xor1 = (func == 6'b100110);
    wire nor1 = (func == 6'b100111);
    wire sltu = (func == 6'b101011);
    wire slt = (func == 6'b101010);
    wire sll = (func == 6'b000000);
    wire srl = (func == 6'b000010);
    wire sra = (func == 6'b000011);
    
    
    assign aluOp = ({4{add}} & 4'b0001) |
                   ({4{addu}} & 4'b0000) |
    			   ({4{sub}} & 4'b0011) |
    			   ({4{subu}} & 4'b0010) |
    			   ({4{and1}} & 4'b0100) |
    			   ({4{or1}} & 4'b0101) |
    			   ({4{xor1}} & 4'b0110) |
    			   ({4{nor1}} & 4'b0111) |
    			   ({4{sltu}} & 4'b1000) |
    			   ({4{slt}} & 4'b1001) |
    			   ({4{sll}} & 4'b1100) |
    			   ({4{srl}} & 4'b1101) |
    			   ({4{sra}} & 4'b1110);
    			   
    
    				
    endmodule 
    

    1、 总体仿真验证
    1.1 验证方案
    然后把之前编写的makefile,BinMem.exe,ram.ld放到源代码所在的目录,输入命令make all,得到与汇编代码相匹配的16进制格式的指令,仿真时将汇编代码的结果与仿真结果比较。
    编写的inst_rom.S如下:

    .org 0x0
       .set noat
       .set noreorder
       .set nomacro
       .global _start
    _start:
    
    
       ori   $1,$0,0x8000           # $1 = 0x00008000
       sll   $1,$1,16               # $1 = 0x80000000
       ori   $1,$1,0x0010           # $1 = 0x80000010
    
       ori   $2,$0,0x8000           # $2 = 0x00008000
       sll   $2,$2,16               # $2 = 0x80000000
       ori   $2,$2,0x0001           # $2 = 0x80000001
    
       ori   $3,$0,0x0000           # $3 = 0x00000000
       addu  $3,$2,$1               # $3 = 0x00000011
       ori   $3,$0,0x0000           # $3 = 0x00000000
       
    
       sub   $3,$1,$3              # $3 = 0x80000010         
       subu  $3,$3,$2              
       
    
       #########     slt\sltu    ##########
    
       ori   $1,$0,0xffff           # $1 = 0xffff
       sll  $1,$1,16               # $1 = 0xffff0000
       slt  $2,$1,$0               # $2 = 1
       sltu $2,$2,$0               # $2 = 0
      
       #########     lw\sw    ##########
       ori  $3,$0,0x4455
       sll  $3,$3,0x10
       ori  $3,$3,0x6677     
       sw   $3,0x8($0)       # [0x8] = 0x44, [0x9]= 0x55, [0xa]= 0x66, [0xb] = 0x77
       lw   $1,0x8($0)       # $1 = 0x44556677
       
       #########     sll\srl    ##########
       sll  $1,$1,4          # $1 = 0x45566770
       srl  $1,$1,4          # $1 = 0x04556677
       ori  $1,$0,0x8000    # $1 = 0x00008000
       sll   $1,$1,16        # $1 = 0x80000000
       sra   $1,$1,4         # $1 = 0xf8000000
       
       bne   $1,$0,N1   
       nop
       nop
       
       N1:   beq $1,$1,s3
       
       s3:   ori   $1,$0,0x80           #  $1 = 0x00000080
             jr    $1                     #  $1 =0x00000080   跳转到           0x00000080处
       
       .org 0x80
       j  0x90
       
       .org 0x90
       ori   $2,$0,56                 # $2 = 56 
       ori   $1,$0,4                 # $1 = 4
       ori   $3,$0,0                 # $3 = 0
       add   $3,$1,$2                # $3 = 60
    
    

    生成的初始化ROM中的16进制指令如下
    34018000
    00010c00
    34210010
    34028000
    00021400
    34420001
    34030000
    00411821
    34030000
    00231822
    00621823
    3401ffff
    00010c00
    0020102a
    0040102b
    34034455
    00031c00
    34636677
    ac030008
    8c010008
    00010900
    00010902
    34018000
    00010c00
    00010903
    14200002
    00000000
    00000000
    10210000
    34010080
    00200008
    00000000
    08000024
    00000000
    00000000
    00000000
    34020038
    34010004
    34030000
    00221820

    1.2 仿真结果(所有指令格式与ROM中一致,为16进制)
    34210010 ori $1,$1,0x0010 # $1 = 0x80000010
    观察BusW为0x80000010
    在这里插入图片描述
    00411821 addu $3,$2,$1 # $3 = 0x00000011
    观察BusW为0x00000011
    在这里插入图片描述
    00231822 sub $3,$1,$3 # $3 = 0x80000010
    观察BusW为0x80000010
    在这里插入图片描述
    0020102a slt $2,$1,$0 # $2 = 0xffffffff
    观察BusW为0xffffffff
    在这里插入图片描述
    ac030008为sw指令的16进制编码,8c010008为lw指令的16进制编码
    sw $3,0x8($0) # [0x8] = 0x44, [0x9]= 0x55, [0xa]= 0x66, [0xb] = 0x77
    lw $1,0x8($0) # $1 = 0x44556677
    观察BusW的为0x44556677
    在这里插入图片描述
    00010900 sll $1,$1,4 # $1 = 0x45566770
    观察BusW的为0x45566770
    在这里插入图片描述
    00010902 srl $1,$1,4 # $1 = 0x04556677
    观察BusW的为0x04556677
    在这里插入图片描述
    00010903 sra $1,$1,4 # $1 = 0xf8000000
    观察BusW的为0xf8000000
    在这里插入图片描述
    bne $1,$0,N1
    nop
    nop

    N1: beq $1,$1,s3

    s3: ori $1,$0,0x80 # $1 = 0x00000080
    如果执行到最后一步,说明beq和bne指令执行正确

    观察BusW的值为0x00000080,且取出的指令为34010080,就是ori指令的16进制编码
    在这里插入图片描述

    jr $1 # $1 =0x00000080 跳转到 0x00000080处
    .org 0x80
    j 0x90

    .org 0x90
    ori $2,$0,56 # $2 = 56
    ori $1,$0,4 # $1 = 4
    ori $3,$0,0 # $3 = 0
    add $3,$1,$2 # $3 = 60
    如果最后四条指令执行了,j和jr指令仿真正确

    Add指令16进制编码为00221820,为最后一条指令,最后结果得60
    观察BusW的值依次为56,4,0,60
    在这里插入图片描述
    到此完整的单周期处理器设计加仿真就完成了。
    附上控制器的仿真代码

    `timescale 1ns/1ns
    
    module Controler_tb;
    
    reg[31:0] instruction;
    wire RegDst;
    wire beq;
    wire bne;
    wire Jump;
    wire ExtOp;
    wire ALUSrc;
    wire [3:0] ALUctr;
    wire MemWr;
    wire MemtoReg;
    wire jr;
    wire RegWr;
    
    
    Controler Controler(
    		 .instruction(instruction),
    		 .RegDst(RegDst),
    		 .bne(bne),
    		 .beq(beq),
    		 .Jump(Jump),
    		 .ExtOp(ExtOp),
    		 .ALUSrc(ALUSrc),
    		 .ALUctr(ALUctr),
    		 .MemWr(MemWr),
    		 .MemtoReg(MemtoReg),
    		 .RegWr(RegWr),
    		 .jr(jr)
    );
    
    initial begin
        /**********add*******/
        instruction = 32'b000000_00000_00000_00000_00000_100000;
    	 #5;
    	 
    	 /**********addu*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_100001;
    	 #5;
    	 
    	 /**********sub*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_100010;
    	 #5;
    	 
    	 /**********subu*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_100011;
    	 #5;
    	 
    	 /**********slt*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_101010;
    	 #5;
    	 
    	 /**********sltu*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_101011;
    	 #5;
    	 
    	 /**********and*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_100100;
    	 #5;
    	 
    	 /**********or*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_100101;
    	 #5;
    	 
    	 /**********xor*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_100110;
    	 #5;
    	 
    	 /**********nor*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_100111;
    	 #5;
    	 
    	 /**********sll*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_000000;
    	 #5;
    	 
    	 /**********srl*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_000010;
    	 #5;
    	 
    	 /**********sra*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_000011;
    	 #5;
    	 
    	 /**********beq*******/
    	 instruction = 32'b000100_00000_00000_00000_00000_000000;
    	 #5;
    	 
    	 /**********bne*******/
    	 instruction = 32'b000101_00000_00000_00000_00000_000000;
    	 #5;
    	 
    	 /**********jr*******/
    	 instruction = 32'b000000_00000_00000_00000_00000_001000;
    	 #5;
    	 
    	 /**********j*******/
    	 instruction = 32'b000010_00000_00000_00000_00000_000000;
    	 #5;
    	 
    	 #10;
    	 $stop;
    
    end
    
    endmodule 
    
    展开全文
  • VerilogHDL 开发单周期处理器 一、目标 使用Verilog开发基于单周期的处理器。 使用Vivado对开发的处理器进行模拟仿真。 编写测试用汇编,使用Mars工具汇编成为机器代码,并使用它调试测试你开发的处理器。 二、...

    CPU设计之二——VerilogHDL 开发MIPS流水线处理器(支持42条指令)
    CPU设计之三——VerilogHDL 开发MIPS流水线处理器(支持50条指令)

    所有代码和参考文件已经上传至github:https://github.com/lcy19981225/Single-Cycle-CPU-10

    一、目标

    • 使用Verilog开发基于单周期的处理器。
    • 使用Vivado对开发的处理器进行模拟仿真。
    • 编写测试用汇编,使用Mars工具汇编成为机器代码,并使用它调试测试你开发的处理器。

    二、说明

    • 处理器应支持MIPS-Lite2指令集。
      • MIPS-Lite1 = { addu, subu, ori, lw, sw, beq, lui }
      • MIPS-Lite2 = { MIPS-Lite1, jal, jr}

    MIPS32指令集的pdf我已经上传到github中,建议大家先好好看看自己要完成的命令的具体含义再开始写!

    • 处理器为单周期设计。
    • 单周期处理器由 datapath(数据通路)和 controller(控制器)组成。 数据通路可以由以下模块组成:
      • PC(程序计数器)
      • NPC(NextPC计算单元)
      • GPR(通用寄存器组,包含32个寄存器)
      • ALU(算术逻辑单元)
      • EXT(扩展单元)
      • IM(指令存储器-只读)
      • DM(数据存储器-可读可写)
      • IM规格:容量为4KB(32bit*1024字)
      • DM规格:容量为4KB(32bit*1024字)
    • 参考的数据通路架构图:
    • 指令处理流程
      • 取指令(IF):根据程序计数器PC中的指令地址,从指令存储器中取出一条指令,同时PC根据指令字长度自动递增产生下一条指令所需要的指令地址,但遇到“地址转移”指令时,则控制器把“转移地址”送入PC。

      • 指令译码(ID):对取指令操作中得到的指令进行分析并译码,确定这条指令需要完成的操作,具体方式根据自己的设定而定

      • 指令执行(EXE):根据指令译码得到的操作控制信号,具体地执行指令动作,然后转移到结果写回状态。

      • 存储器访问(MEM):所有需要访问存储器的操作都将在这个步骤中执行,该步骤给出存储器的数据地址,把数据写入到存储器中数据地址所指定的存储单元或者从存储器中得到数据地址单元中的数据。

      • 结果写回(WB):指令执行的结果或者访问存储器中得到的数据写回相应的目的寄存器中。

    • code.txt中存储的是指令码。
      • 测试时,code.txt的格式为每条指令占用1行,指令以十六进制文本码形式存储。
      • 请使用verilog建模指令存储器IM时,以读取code.txt的方式载入指令,可以自行学习 $readmemh指令。
      • 调试时你可以使用Mars工具将汇编程序编译成机器码导入code.txt中。请注意Mars工具的内存设置请依据如下

    Mars可以将你自己写的测试汇编代码转换成机器码,这样就可以生成你自己想要的而测试样例,如果没有使用过可以搜索一下相关博客啥的,Mars.jar我也同样上传到github中了~

    在这里插入图片描述

    三、模块设计

    PC

    PC需要对reset进行判断,如果不需要重置,那么只用把PC置为下一条指令即可

    module PC(Clk,Reset,Result,Address);  
        input Clk;//时钟
        input Reset;//是否重置地址。0-初始化PC,否则接受新地址       
        input[31:0] Result;
        output reg[31:0] Address;
    
        initial begin
            Address  <= 0;
        end
        
        always @(posedge Clk or negedge Reset)  
        begin  
        if (!Reset) //如果为0则初始化PC,否则接受新地址
            begin  
                Address <= 0;  
            end  
        else   
            begin
                Address =  Result;  
            end  
        end  
    endmodule
    

    PCAdd4

    PCAdd4只需要对PC+4就行,按照之前讲的超前进位加法器写了一个cal32用来进行32位加法,代码放在GitHub上了~

    module PCAdd4(PC_o,PCadd4);
        input [31:0] PC_o;//偏移量
        output [31:0] PCadd4;//新指令地址
        CLA_32 cla32(PC_o,4,0, PCadd4, Cout);
    endmodule
    

    ALU

    ALU用来进行各种运算,需要设置一个多路选择器判断ALU B端的输入是来自寄存器堆还是来自扩展单元,同时当运算结果为0是,将控制信号ZERO置为1

    module ALU( ReadData1, ReadData2,ALUOp,result,zero);
            input [31:0] ReadData1;
            input [31:0] ReadData2;
            input [2:0] ALUOp;
            output reg[31:0] result;
            output reg zero;
      
        always@(ReadData1 or ReadData2 or ALUOp) 
        begin
    
            case(ALUOp)
                3'b000: result = ReadData1 + ReadData2;
                3'b001: result = ReadData1 - ReadData2;
                3'b010: result = ReadData2 & ReadData1;
                3'b011: result = ReadData1 | ReadData2;
                3'b100: result = ReadData2<<16;
            endcase
            zero = (result == 0) ? 1 : 0;
        end 
    
    endmodule
    

    CONUNIT

    控制单元控制各种信号的值,控制信号有

    • Regrt:判断寄存器堆的写回地址
    • Se:控制扩展单元是零扩展还是符号扩展
    • Wreg:判断是否需要写回寄存器堆
    • Aluqb:控制ALU的B端输入是来自寄存器堆还是扩展单元
    • Aluc[2:0]:控制ALU进行运算的类型
    • Wmem:判断是否需要对dm进行写操作,只有sw会用到
    • Pcsrc[2:0]:判断下一条指令的形式
    • Reg2reg:判断写回寄存器堆的数据来源,是从ALU来还是从dm来,只有lw会用到

    对于不同的命令取值如下:
    在这里插入图片描述

    以上控制信号需要一个5位二选一多路选择器,两个个32位二选一多路选择器,一个32位五选一多路选择器,具体实现在MUX.v中介绍

    module CONUNIT(Op,Func,Z,Regrt,Se,Wreg,Aluqb,Aluc,Wmem,Pcsrc,Reg2reg);
        input[5:0]Op,Func;
        input Z;
        output Regrt,Se,Wreg,Aluqb,Wmem,Reg2reg;
        output[2:0]Pcsrc;
        output [2:0]Aluc;
    
        wire R_type=~|Op;
        wire I_add=R_type&Func[5]&~Func[4]&~Func[3]&~Func[2]&~Func[1]&~Func[0];
        wire I_sub=R_type&Func[5]&~Func[4]&~Func[3]&~Func[2]&Func[1]&~Func[0];
        wire I_and=R_type&Func[5]&~Func[4]&~Func[3]&Func[2]&~Func[1]&~Func[0];
        wire I_or=R_type&Func[5]&~Func[4]&~Func[3]&Func[2]&~Func[1]&Func[0];
        wire I_jr=R_type&~Func[5]&~Func[4]&Func[3]&~Func[2]&~Func[1]&~Func[0];
    
        wire I_addi=~Op[5]&~Op[4]&Op[3]&~Op[2]&~Op[1]&~Op[0];
        wire I_andi=~Op[5]&~Op[4]&Op[3]&Op[2]&~Op[1]&~Op[0];
        wire I_ori=~Op[5]&~Op[4]&Op[3]&Op[2]&~Op[1]&Op[0];
        wire I_lw=Op[5]&~Op[4]&~Op[3]&~Op[2]&Op[1]&Op[0];
        wire I_sw=Op[5]&~Op[4]&Op[3]&~Op[2]&Op[1]&Op[0];
        wire I_beq=~Op[5]&~Op[4]&~Op[3]&Op[2]&~Op[1]&~Op[0];
        wire I_bne=~Op[5]&~Op[4]&~Op[3]&Op[2]&~Op[1]&Op[0];
        wire I_J=~Op[5]&~Op[4]&~Op[3]&~Op[2]&Op[1]&~Op[0];
        wire I_lui=~Op[5]&~Op[4]&Op[3]&Op[2]&Op[1]&Op[0];
        wire I_jal=~Op[5]&~Op[4]&~Op[3]&~Op[2]&Op[1]&Op[0];
    
        assign Regrt=I_addi|I_andi|I_ori|I_lw|I_sw|I_beq|I_bne|I_J|I_lui|I_jal;
        assign Se=I_addi|I_lw|I_sw|I_beq|I_bne|I_lui;
        assign Wreg=I_add|I_sub|I_and|I_or|I_addi|I_andi|I_ori|I_lw|I_lui|I_jal;
        assign Aluqb=I_add|I_sub|I_and|I_or|I_beq|I_bne|I_J|I_jal|I_jr;
        assign Aluc[2]=I_lui;
        assign Aluc[1]=I_and|I_or|I_andi|I_ori;
        assign Aluc[0]=I_sub|I_or|I_ori|I_beq|I_bne;
        assign Wmem=I_sw;  
        assign Pcsrc[2]=I_jal|I_jr;
        assign Pcsrc[1]=I_beq&Z|I_bne&~Z|I_J;
        assign Pcsrc[0]=I_J|I_jr;
        assign Reg2reg=I_add|I_sub|I_and|I_or|I_addi|I_andi|I_ori|I_sw|I_beq|I_bne|I_J|I_lui|I_jal|I_jr;
    endmodule    
    

    dm_4k

    只有lw,sw会用到,分别用来存数据和读数据

    module dm_4k(Addr,Din,We,Clk,Dout);
        input[31:0]Addr,Din;
        input Clk,We;
        output[31:0]Dout;
        reg[31:0]Ram[1024:0];
    
        assign Dout=Ram[Addr[6:2]];
        
        always@(posedge Clk)begin
            if(We)
                Ram[Addr[6:2]]<=Din;
        end
    
        integer i;
        initial begin
            for(i=0;i<32;i=i+1)
                Ram[i]=0;
        end
    endmodule
    

    im_4k

    从code.txt读取指令码

    module im_4k(Addr,Inst);//指令存储器
    input[31:0]Addr;
    reg [31:0]Rom[1024:0];
    
    output[31:0]Inst;
    
        initial 
        begin
            $readmemh("C:\\Users\\Y\\Desktop\\code.txt", Rom);
        end
        integer i;
        initial begin
            $display("start simulation");
            for (i=0;i<20;i=i+1)
                $display("%h %h", i,Rom[i]);
        end
        
        assign Inst=Rom[Addr[6:2]];
    
    endmodule
    

    MUX

    分别实现了5位二选一多路选择器,32位二选一多路选择器,32位五选一多路选择器,每一个选择器都有信号S,根据信号S可以决定输出

    module MUX2X5(A0,A1,S,Y);
        input [4:0] A0,A1;
        input S;
        output [4:0] Y;
    
        function [4:0] select;
            input [4:0] A0,A1;
            input S;
            case(S)
                0:select=A0;
                1:select=A1;
            endcase
        endfunction
    
        assign Y=select(A0,A1,S);
    endmodule
    
    module MUX2X32(A0,A1,S,Y);
        input [31:0] A0,A1;
        input S;
        output [31:0] Y;
    
        function [31:0] select;
            input [31:0] A0,A1;
            input S;
            case(S)
                0:select=A0;
                1:select=A1;
            endcase
        endfunction
    
        assign Y=select(A0,A1,S);
    endmodule
    
    module MUX5X32 (A0, A1, A2, A3, A4, S, Y);
        input [31:0] A0, A1, A2, A3, A4;
        input [2:0] S;
        output [31:0] Y;
    
        function [31:0] select;
            input [31:0] A0, A1, A2, A3, A4;
            input [2:0] S;
            case(S)
                3'b000: select = A0;
                3'b001: select = A1;
                3'b010: select = A2;
                3'b011: select = A3;
                3'b100: select = A3;
                3'b101: select = A4;
            endcase
        endfunction
    
        assign Y = select (A0, A1, A2, A3, A4, S);
    endmodule
    

    RegisterFile

    寄存器堆需要找到存在寄存器中的值,还需要往寄存器堆中写入值

    module RegisterFile(ReadReg1,ReadReg2,WriteData,WriteReg,RegWrite,CLK,Reset,ReadData1,ReadData2,Pcsrc,PcAdd4);
        input [4:0] ReadReg1;//rs
        input [4:0] ReadReg2;//rt或者立即数
        input [31:0] WriteData;//写入的数据
        input [4:0] WriteReg;//写入地址
        input RegWrite; //写信号
        input CLK;
        input Reset;
        output reg[31:0] ReadData1;
        output reg[31:0] ReadData2;
        input [2:0] Pcsrc;
        input [31:0] PcAdd4;
        
    
        initial begin
           ReadData1 <=0;
           ReadData2 <=0; 
        end
    
        reg [31:0] regFile[0:31];
        integer i;
        initial begin
            for (i=0;i<32;i=i+1)
                regFile[i]<=0;
        end
            
        always@(ReadReg1 or ReadReg2)
        begin
            ReadData1 = regFile[ReadReg1];
            ReadData2 = regFile[ReadReg2];
            //$display("regfile %d %d\n", ReadReg1, ReadReg2);
            
        end
         
        always@(negedge CLK )
        begin
         //$display("lala");
            if(RegWrite && WriteReg)
            begin
                regFile[WriteReg] = WriteData;
                //$display("%d %d",WriteReg, WriteData);
            end
        end
    
        always@(negedge CLK)
        begin
            //$display("lala");
            if(Pcsrc == 3'b100 && RegWrite )
            begin
            //$display("%h",PcAdd4);
                regFile[31] = PcAdd4;
            end
        end
    endmodule
    
    
    

    SignExtend

    进行扩展操作,零扩展或者符号扩展

    module SignExtend (X, Se, Y);
        input [15:0] X;
        input Se;
        output [31:0] Y;
        wire [31:0] E0, E1;
        wire [15:0] e = {16{X[15]}};
        parameter z = 16'b0;
        assign E0 = {z, X};
        assign E1 = {e, X};
        MUX2X32 i(E0, E1, Se, Y);
    endmodule
    

    shifter

    进行移位操作,包括将立即数左移两位,还有取PC+4前4位+address26位+两个0

    module SHIFTER_COMBINATION(X,PCADD4,Sh);
        input [26:0] X;
        input [31:0] PCADD4;
        output [31:0] Sh;
        parameter z=2'b00;
        assign Sh={PCADD4[31:28],X[26:0],z};
    endmodule
    
    module SHIFTER32_L2(X,Sh);
        input [31:0] X;
        output [31:0] Sh;
        parameter z=2'b00;
        assign Sh={X[29:0],z};
    endmodule
    

    SingleCycleCPU

    将所有的模块合起来

    module MAIN(Clk,Reset,Addr,Inst,Qa,Qb,ALU_R,NEXTADDR,D);
      input Clk,Reset;
      output [31:0] Inst,NEXTADDR,ALU_R,Qb,Qa,Addr,D;
    
    
    
      wire [31:0]Result,PCadd4,EXTIMM,InstL2,EXTIMML2,D,Y,Dout,mux4x32_2,R;
      wire Z,Regrt,Se,Wreg,Aluqb,Reg2reg,Cout,Wmem;
      wire [2:0]Pcsrc;
      wire [2:0]Aluc;
      wire [4:0]Wr;
    
      PC pc(Clk,Reset,Result,Addr);
      PCAdd4 pcadd4(Addr,PCadd4);
      im_4k instmem(Addr,Inst);
    
      CONUNIT conunit(Inst[31:26],Inst[5:0],Z,Regrt,Se,Wreg,Aluqb,Aluc,Wmem,Pcsrc,Reg2reg);
      MUX2X5 mux2x5(Inst[15:11],Inst[20:16],Regrt,Wr);
    
      SHIFTER_COMBINATION shifter1(Inst[26:0],PCadd4,InstL2);//J指令的跳转地址
    
      RegisterFile regfile(Inst[25:21],Inst[20:16],D,Wr,Wreg,Clk,Reset,Qa,Qb,Pcsrc,PCadd4);
    
      ALU alu(Qa,Y,Aluc,R,Z);
      dm_4k datamem(R,Qb,Wmem,Clk,Dout);
      MUX2X32 mux2x322(Dout,R,Reg2reg,D);//写寄存器堆的来源,是ALU 还是 DM
      SignExtend ext16t32(Inst[15:0],Se,EXTIMM);//扩展 0还是符号
      MUX2X32 mux2x321(EXTIMM,Qb,Aluqb,Y);//选择ALU B端的来源
      SHIFTER32_L2 shifter2(EXTIMM,EXTIMML2);
      CLA_32 cla_32(PCadd4,EXTIMML2,0,mux4x32_2, Cout);//beq bne的跳转至零
    
    
      MUX5X32 mux5x32(PCadd4,0,mux4x32_2,InstL2,Qa,Pcsrc,Result);//选择跳转的地址
    
      assign NEXTADDR=Result;
      assign ALU_R=R;
    
      integer i;
      initial begin
              $display("start simulation");
              //for (i=0;i<3;i=i+1)
                //  $display("%h %h", i,instmem.Rom[i]);
              //$display("%h %h",regfile.ReadReg1,regfile.ReadReg2);
              //$display("%h",pc.Address);
              //$display("%h",instmem.Addr);
          end
    
    endmodule
    

    mips

    最后的模拟仿真文件,包括clk(不断进行翻转)和reset(最开始进行初始化之后就一直不需要初始化了)

    module mips;
    wire [31:0] Addr,Inst,Qa,Qb,ALU_R,NEXTADDR;
    
        reg CLK;
        reg Reset;
        MAIN uut(
        .Clk(CLK),
        .Reset(Reset),
        .Addr(Addr),
        .Inst(Inst),
        .Qa(Qa),
        .Qb(Qb),
        .ALU_R(ALU_R),
        .NEXTADDR(NEXTADDR),
        .D(D)
        );
    
        initial begin
            CLK = 0;
            Reset = 0;
            
            CLK = !CLK;  // 下降沿,使PC先清零
            Reset = 1;  // 清除保持信号
            forever #20
            begin 
                 CLK = !CLK;
            end
        end
    endmodule
    

    四、控制器的设计

    考虑各种指令的流程
    无

    Regrt:所有的l,j型指令会写回到rt

    Se:参考mips手册即可

    Wreg:除了bne,beq,j,jr都需要写回寄存器堆

    Aluqb:对于需要进行立即数扩展的指令就需要从扩展单元输入

    Aluc:按自己的想法设计就好,我设计的方法如下
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QF60j6Dw-1589006437756)(C:\Users\Y\AppData\Roaming\Typora\typora-user-images\image-20191128164621412.png)]

    Wmem:只有sw会用到

    Pcsrc:也是根据自己的想法设计

    Reg2reg:除了lw之外都是直接从ALU写回寄存器堆

    五、结果验证

    验证的汇编程序

    首先通过addi给$1赋值,之后测试了addu,subu,ori,lw,sw,beq,lui,jal,jr等指令

    addi $1,$0,8 #$1=8
    ori $2,$0,12 #$2=12
    addu $3,$1,$2 #$3=20
    subu $4,$2,$1 #$4=4
    and $5,$1,$2
    or $6,$1,$2
    lui $7 100 #$8=100<<64
    bne $1,$2,p1
    p1:
    beq $1,$2,out
    j p3
    p3:
    sw $2 10($8)
    lw $4 10($8)
    beq $2,$4,p4
    p4:
    andi $9,$2,9
    
    loop:
    jal minus
    bne $1 $2 loop
    j out
    minus:
    addi $1 $1 1
    jr $ra
    
    out:
    
    

    模拟结果

    在这里插入图片描述

    我的验证方法

    • 查看I_addu等信号来判断执行的是哪一条指令
    • 查看Regrt等信号是否正确
    • 查看寄存器堆的读写情况可以很好地判断进行的操作是否正确
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TyppMd4c-1589006437771)(C:\Users\Y\AppData\Roaming\Typora\typora-user-images\image-20191128202442910.png)]
      通过检查,全部指令正确,尤其是针对jal和jr,在一个循环中使用了函数调用,最后循环四次之后退出,如下图,同样正确
      在这里插入图片描述
      至此,实验全部结束

    六、实验总结

    1. 出现过很多bug不太明白错在哪里,善于利用$display能够进行调试
    2. 当指令数比较少的时候可以人工进行排查然后写excel表格,但当指令数达到几十条之后可能就需要通过代码来生成各种控制型号的值
    3. 在进行仿真的时候可以一条条地进行模拟,慢慢地完成
    4. 在进行bne指令的时候,不知道为什么根据手册上的形如 bne $1 $2 2 的指令的时候会报错,一定要跳转到一个label才行
    5. 通过这次试验也算是搞清楚了整个cpu的工作流程,期待接下来的多周期流水线实验
    6. 有一个问题尚未解决,就是在im_4k中用readmemh读取code.txt的时候采用相对路径不知道为什么读不进去,就只好改成绝对路径

    在这里插入图片描述

    在所有独立完成的大作业中这个的复杂程度应该算得上数一数二的了,所以想要写篇博客记录一下,之后也会更新支持50条指令的流水线CPU,也算留个纪念hhh,如有疏漏之处,欢迎指正,有问题也欢迎大家一起交流~

    展开全文
  • 处理器设计的五个步骤如下,请正确排序。 1 连接组件建立数据通路 2 为数据通路选择合适的组件 3 集成控制信号,形成完整的控制逻辑 4 分析指令系统,得出对数据通路的需求 5 分析每条指令的实现,以确定控制...

    记录第一次学习的习题,具体的分析与复习,另写文章记录。

    1. 第 1 个问题

    处理器设计的五个步骤如下,请正确排序。

    1 连接组件建立数据通路

    2 为数据通路选择合适的组件

    3 集成控制信号,形成完整的控制逻辑

    4 分析指令系统,得出对数据通路的需求

    5 分析每条指令的实现,以确定控制信号

    答案样例格式:12345

    正确回答 

    42153

     

    2. 第 2 个问题

    课程中提到的MIPS-lite指令子集(addu,subu,ori,lw,sw,beq)对ALU的需求有哪些?

    逻辑或

    正确 

    左移

    未选择的是正确的 

    逻辑与

    未选择的是正确的 

    逻辑非

    未选择的是正确的 

    加法

    正确 

    除法

    未选择的是正确的 

    相等

    正确 

    乘法

    未选择的是正确的 

    减法

    正确 

    右移

    未选择的是正确的 

     

    3. 第 3 个问题

    下列关于MIPS-lite指令子集对数据通路的需求描述正确的是?

    add指令与ori指令对寄存器堆的写操作需求不一样

    正确 

    lw指令需要符号扩展部件

    正确 

    lw指令与sw指令都需要数据存储器

    正确 

    ori指令需要符号扩展部件

    未选择的是正确的 

    sub指令需要符号扩展部件

    未选择的是正确的 

    add指令需要零扩展部件

    未选择的是正确的 

     

    4. 第 4 个问题

    下列关于运算指令的控制信号描述正确的是?

    add指令与ori指令的寄存器堆控制信号RegDst不同

    正确 

    add指令与ori指令的ALU源操作数控制信号ALUSrc不同

    正确 

    ori指令的扩展部件控制信号ExtOp不唯一

    未选择的是正确的 

    add指令的扩展部件控制信号ExtOp不唯一

    正确 

    add指令与ori指令的数据存储器控制信号MemWr可以不相同

    未选择的是正确的 

    add指令与ori指令的ALU运算类型控制信号ALUctr不同

    正确 

     

    5. 第 5 个问题

    下列关于访存指令的控制信号描述正确的是?

    lw指令与sw指令的数据存储器控制信号MemWr可以不相同

    未选择的是正确的 

    lw指令与sw指令的寄存器堆控制信号RegDst一定相同

    未选择的是正确的 

    lw指令与sw指令的ALU运算类型控制信号ALUctr相同

    正确 

    lw指令与sw指令的扩展部件控制信号ExtOp可以不相同

    未选择的是正确的 

    lw指令与sw指令的控制信号MemtoReg可以不相同

    正确 

     

    6. 第 6 个问题

    下列关于beq指令的执行描述正确的是?

    beq指令与add指令的ALU运算类型控制信号ALUctr相同

    未选择的是正确的 

    若ALU计算结果为零,则beq指令不需要执行PC+4操作

    未选择的是正确的 

    beq指令的寄存器堆控制信号RegDst是不唯一的

    正确 

    beq指令的扩展部件控制信号ExtOp一定为sign

    未选择的是正确的 

    beq指令与lw指令的数据存储器控制信号MemWr是相同的

    正确 

     

    7. 第 7 个问题

    在单周期处理器上执行add指令,使用到了下列哪些部件?

    数据存储器

    未选择的是正确的 

    寄存器堆

    正确 

    ALU

    正确 

    扩展部件(零扩展或符号扩展)

    未选择的是正确的 

     

    8. 第 8 个问题

    在单周期处理器上执行ori指令,使用到了下列哪些部件?

    ALU

    正确 

    扩展部件(零扩展或符号扩展)

    正确 

    寄存器堆

    正确 

    数据存储器

    未选择的是正确的 

     

    9. 第 9 个问题

    假设单周期处理器五个阶段的延迟分别为200ps(取指)、50ps(读寄存器)、200ps(ALU操作)、300ps(访存)、100ps(写寄存器),则lw指令的总延迟为多少ps?(答案直接填数字,不用带单位)

    正确回答 

    850

     

    10. 第 10 个问题

    假设单周期处理器五个阶段的延迟分别为200ps(取指)、50ps(读寄存器)、200ps(ALU操作)、300ps(访存)、100ps(写寄存器),则beq指令的总延迟为多少ps?(答案直接填数字,不用带单位)

    正确回答 

    450

     

    11. 第 11 个问题

    假设一条指令的32位编码从高到低依次为Ins<31>, Ins<30>, ……, Ins<0>,则产生MemWr控制信号需要用到指令编码中的多少位?

    1位

    12位

    32位

    6位

    正确 

     

    12. 第 12 个问题

    假设一条指令的32位编码从高到低依次为Ins<31>, Ins<30>, ……, Ins<0>,则产生ALUctr[0]控制信号需要用到指令编码中的多少位?

    6位

    12位

    正确 

    14位

    26位

    32位

    7位

    展开全文
  • 基于FPGA的MIPS单周期处理器的实现.pdf
  • Logisim完成单周期处理器开发 实验报告 学 号_17110113_ 姓 名_王禹心_ 指导教师_朱文军_ 提交日期_2019.5.28_ 成绩评价表 报告内容 报告结构 报告最终成绩 丰富正确 基本正确 有一些问题 问题很大 完全符合要求 ...
  • 单周期处理器设计

    2014-05-26 08:49:33
    进一步理解单周期处理器以及多周期处理器的工作原理和设计思路 实验要求: 设计和实现一个单周期处理器(60%) 可执行至少7条MIPS指令,add、sub、ori、lw、sw、beq、j 编写测试程序的二进制代码,测试实现的电路 ...
  • MIPS单周期处理器设计

    千次阅读 2017-11-29 19:14:56
    http://blog.csdn.net/zhaokx3/article/details/51493842
  • 电路模拟logisim进行mips单周期CPU开发,支持的指令集MIPS-Lite:addu,subu,ori,lw,sw,beq,lui,j,sb
  • 设计能够实现R型、I型带立即数运算指令及LW、SW的单周期处理器,并使用以下指令进行测试。
  • 半加器 半加器电路是指对两个输入数据位相加,输出一个结果位和进位,没有进位输入的加法器电路。 是实现两个一位二进制数的加法运算电路。 全加器 full adder 用门电路实现两个二进制数相加并求出和的组合线路,...
  • 5 单周期处理器题库

    千次阅读 2019-02-17 11:17:25
    1、处理器设计的五个步骤如下,请正确排序。 1 连接组件建立数据通路 2 为数据通路选择合适的组件 3 集成控制信号,形成完整的控制逻辑 4 分析指令系统,得出对数据通路的需求 5 分析每条指令的实现,以确定...
  • verilog工程代码
  • 【计算机组成原理】单周期处理器

    千次阅读 2016-08-08 22:52:03
    单周期处理器
  • 一个基于三元哈佛体系结构且具有类似RISC的ISA的32位MIPS简单单周期处理器。 该项目在开罗大学工程学,电子与电气通信学院完成(EECE-2017)
  • logisim平台下实现的单周期处理器,能够完美实现基本指令操作,内含7段数码管设计,操作方便直观。 1.处理器应支持的指令集MIPS-Lite:addu,subu,ori,lw,sw,beq,lui,j。 a)addu,subu可以不支持实现溢出。 2....
  • 单周期CPU8指令实现

    2020-12-07 12:46:03
    【压缩包中含有完整代码】 计组实验课的Verilog代码实现单周期8指令CPU Ps:使用前先阅读readme 文件

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 109,217
精华内容 43,686
关键字:

单周期处理器