我是靠谱客的博主 殷勤樱桃,最近开发中收集的这篇文章主要介绍杭电计算机组成原理课程设计-实验期末考试,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

实验期末考试

      • 考试题目
      • 代码
      • 测试用例

考试题目

在这里插入图片描述

代码

注: 下列所示代码与题目可能有些出入,xor,sub等功能在作者之前的文章中均已经实现,可见之前文章 R-I CPU设计实验。本代码主要侧重 lw_inc 功能的实现,主要通过修改REG模块,在其中加入一个控制信号以实现rs加1的功能。

module R_I_CPU(
	clk,rst,clk_m,
    Inst_code,PC,
    opcode,rs,rt,rd,shamt,func,imm,offset,
	ALU_F,ZF,OF,ALU_OP,
	rd_rt_s,imm_s,rt_imm_s,alu_mem_s,
	 ALU_B,R_Data_A,W_Addr,W_Data,imm_kz,R_Data_B,M_R_Data,Write_Reg,Mem_Write,Mem_Addr,
	 rs_shamt,ALU_A,rs_1
    );
 	input clk;//时钟
    input rst;//清零
	input clk_m;
	output reg [31:0]PC;//地址
    wire [31:0]PC_new;
    output [31:0]Inst_code;//取出的指令
    output [5:0]opcode,func;//指令分段
    output [4:0]rs,rt,rd,shamt;//指令分段
	output [15:0]imm,offset;//指令分段
	wire [25:0]address;//指令分段
    output [31:0] ALU_F;//ALU结果
	output reg [2:0] ALU_OP;//ALU_OP
	output ZF,OF;
	output reg Write_Reg;
	output reg Mem_Write;
	output [31:0]R_Data_A;
	output  [31:0]ALU_A;
	output [31:0]R_Data_B;
	output [31:0]M_R_Data;
	output [7:0]Mem_Addr;
	output reg rd_rt_s;
	output reg imm_s;
	output reg rt_imm_s;
	output reg alu_mem_s;
	output reg rs_1;
	output [4:0]W_Addr;
	output [31:0]ALU_B;
	output [31:0]W_Data;
	output reg [31:0]imm_kz;
		
	initial PC = 32'h00000000;
	assign PC_new = PC + 4;
	 
	wire [31:0]shamt_kz;
	output reg rs_shamt;
	assign shamt_kz={{27{1'b0}},shamt};
	  
ROM_B ROM1 (
  .clka(clk), // input clka
  .addra(PC[7:2]), // input [5 : 0] addra
  .douta(Inst_code) // output [31 : 0] douta
);
	
	always @(negedge clk or posedge rst)
  begin
	if (rst)
		PC = 32'h00000000; //PC复位;
	else
		PC = PC_new; //PC更新为PC+4;
  end;

	assign opcode =  Inst_code[31:26];
	assign rs =  Inst_code[25:21];
	assign rt =  Inst_code[20:16];
	assign rd=  Inst_code[15:11];
	assign shamt = Inst_code[10:6];
	assign func =  Inst_code[5:0];
	assign imm= Inst_code[15:0];
	assign offset= Inst_code[15:0];
	assign address = Inst_code[25:0];

	 always @(*)
		begin
		ALU_OP = 3'b001;	//默认做或
		rd_rt_s = 1'b0;		//默认写入rd指明的寄存器
		imm_s = 1'b0;		//默认对立即数/偏移量进行0扩展
		rt_imm_s = 1'b0;	//默认读出rt寄存器的数据送ALU_B
		alu_mem_s = 1'b0;	//默认ALU运算结果写入目的寄存器		
		Write_Reg = 1'b1;	//默认写寄存器      
        Mem_Write = 1'b0;	//默认不写存储器	
		rs_shamt=1'b0;         //默认不使用shamt
		rs_1=1'b0;
    if (opcode==6'b000000)    //R指令
     begin
		case (func) 
		6'b100101:begin ALU_OP=3'b001;end
	   6'b000000:begin ALU_OP=3'b111;rs_shamt=1'b1; end
		endcase
    end
	 else
		begin
		case(opcode)
		6'b001000:begin rd_rt_s=1;imm_s=1;rt_imm_s=1;ALU_OP=100;end  //addi
		6'b101011:begin imm_s=1;rt_imm_s=1;ALU_OP=100;Write_Reg=0;Mem_Write=1; end  //sw
		6'b001010:begin rd_rt_s=1;imm_s=1;rt_imm_s=1;alu_mem_s=1;ALU_OP=100;rs_1=1'b1; end  //lw
		endcase
		end
	end;
	 
	always @(*)
		begin
		if(imm_s==1'b0)
			begin
			imm_kz={{16{1'b0}},imm};
			end
		if(imm_s==1'b1)
			begin
			case(imm[15])
			1'b1:imm_kz={{16{1'b1}},imm};
			1'b0:imm_kz={{16{1'b0}},imm};
			endcase
		end
	end;
	
REGS REGS_1(R_Data_A,R_Data_B,W_Data,rs,rt,W_Addr,Write_Reg,rst,~clk,rs_1);
	 ALU ALU_1(ALU_OP,ALU_A,ALU_B,ALU_F,ZF,OF);
	 	 RAM_B RAM1 (
  .clka(clk_m), // input clka
  .wea(Mem_Write), // input [0 : 0] wea
  .addra(Mem_Addr[7:2]), // input [5 : 0] addra
  .dina(R_Data_B), // input [31 : 0] dina
  .douta(M_R_Data) // output [31 : 0] douta
);
	assign ALU_A = (rs_shamt)?shamt_kz:R_Data_A;
    assign W_Addr=(rd_rt_s)?rt:rd;
	 assign ALU_B=(rt_imm_s)?imm_kz:R_Data_B;
    assign Mem_Addr=ALU_F[7:0];
    assign W_Data=(alu_mem_s)?M_R_Data:ALU_F;
endmodule

module REGS(R_Data_A,R_Data_B,W_Data,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk,rs_1);
	input clk;//写入时钟信号
    input rst;//清零信号
    input Write_Reg;//写控制信号
    input [4:0]R_Addr_A;//A端口读寄存器地址
    input [4:0]R_Addr_B;//B端口读寄存器地址
    input [4:0]W_Addr;//写寄存器地址
    input [31:0]W_Data;//写入数据
	input rs_1; //rs自增信号
	output [31:0]R_Data_A;//A端口读出数据
    output [31:0]R_Data_B;//B端口读出数据
	 
	 integer i;
	 reg [31:0] REG_Files[0:31];  
    initial
        for(i=0;i<32;i=i+1) REG_Files[i]<=0;
    always@(posedge clk or posedge rst)
    begin
        if(rst)
                for(i=0;i<32;i=i+1) REG_Files[i]<=0;
        else
				begin
                if(Write_Reg&&W_Addr!=32'd0) REG_Files[W_Addr]<=W_Data;
					 if(rs_1) REG_Files[R_Addr_A]<=REG_Files[R_Addr_A]+1;
					 end
    end
    assign R_Data_A=REG_Files[R_Addr_A];
    assign R_Data_B=REG_Files[R_Addr_B];

endmodule

module ALU(ALU_OP,A,B,F,ZF,OF);
	  input  [2:0] ALU_OP;
	  input  [31:0] A;
	  input  [31:0] B;
	  output [31:0] F;
	  output  ZF;
	  output  OF;
	  reg [31:0] F;
	  reg    C,ZF;
	  
	 always@(*)
	  begin
		C=0;
		case(ALU_OP)
			3'b000:begin F=A&B; end
			3'b001:begin F=A|B; end
			3'b010:begin F=A^B; end
			3'b011:begin F=~(A|B); end 
			3'b100:begin {C,F}=A+B; end 
			3'b101:begin {C,F}=A-B; end 
			3'b110:begin F=A<B; end
			3'b111:begin F=B<<A; end
		endcase
		ZF = F==0;
		end
		assign OF = ((ALU_OP==3'b100)||(ALU_OP==3'b101))&&(A[31] ^ B[31] ^ F[31] ^ C); 
endmodule

测试用例

	always #13 clk_m=~clk_m;
	always #47 clk=~clk;

	initial begin
	
		clk = 0;
		clk_m = 0;
		rst = 1;
		#3;
      rst=0;
	
	end
endmodule

最后

以上就是殷勤樱桃为你收集整理的杭电计算机组成原理课程设计-实验期末考试的全部内容,希望文章能够帮你解决杭电计算机组成原理课程设计-实验期末考试所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部