杭电计算机组成原理实验RISC-V 实验 取指令及指令译码实验

这里写目录标题

一、实验目的与要求

1、 实验目的:

a) 掌握指令存储器、PC与IR的设计方法

b) 掌握CPU取指令操作与指令译码的方法和过程,掌握指令译码器的设计方法

c) 理解RISC-V立即数的生成与扩展方法,掌握立即数拼接与扩展器的设计

2、 实验要求:

首先设计一个64 X 32位的只读存储器作为指令存储器;然后设计程序计数器PC和指令存储器IR,实现取指令操作,设计一个指令译码器和一个立即数拼接与扩展器,完成指令译码操作。

二、实验设计与程序代码

1、 模块设计说明

(描述整个实验的设计方案,分几个模块,各模块的功能,各模块之间的连接关系,可附图)
杭电计算机组成原理实验RISC-V 实验 取指令及指令译码实验

2、 实验程序源代码及注释等
(实验各个模块的代码,包含功能注释)

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    00:13:16 05/25/2021 
// Design Name: 
// Module Name:    main 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module main(
	input Ir_Write,
	input PC_Write,
	input clk_im,
	input clk_n,
	input clk_25M,
	output [4:0] rs1,rs2,rd,
	output [3:0] AN,
	output [7:0] seg,
	output [6:0] opcode,
	output [2:0] funct3,
	output [6:0] funct7
    );
	wire [31:0] IR;
	wire [31:0] inst;
	wire [31:0] imm32;
	wire [31:0] PC;
	Get_Order myGet_Order(Ir_Write,PC_Write,IR,clk_im,clk_n,PC,inst);
	IDI myIDI(inst,rs1,rs2,rd,imm32,opcode,funct3,funct7);
	ShowNum myShowNum(clk_25M,imm32,seg,AN);//这个模块主要是相关数据显示模块
	IM myIM(clk_im,PC[7:2],IR);
	
	
endmodule





module Get_Order(
	input IR_Write,
	input PC_Write,
	input [31:0] IR,
	input clk_im,
	input clk_n,
	output reg [31:0] PC,
	output reg [31:0] inst
	);

	
	initial
	begin
		PC=0;
	end
	always@(posedge clk_im or posedge clk_n)
	begin
		if(IR_Write==1)
		begin
			inst<=IR;
			PC<=PC+4;
		end
		else if(clk_n==1)
		begin
			PC<=0;
		end
	end
	


endmodule



module IDI(
	input [31:0] inst,
	output reg [4:0] rs1,rs2,rd,
	output reg [31:0] imm32,
	output reg [6:0] opcode,
	output reg [2:0] funct3,
	output reg [6:0] funct7
	);

	reg [5:0] I_fmt;
	
	always@(*)
	begin
		opcode=inst[6:0];
		rs1=inst[19:15];
		rs2=inst[24:20];
		rd=inst[11:7];
		funct3=inst[14:12];
		funct7=inst[31:25];
		
		
		case(opcode)
			7'b0010011: I_fmt=6'b1000000;//I1
			7'b0000011: I_fmt=6'b1000000;//I2
			7'b0100011: I_fmt=6'b0100000;//S
			7'b1100011: I_fmt=6'b0010000;//B
			7'b0110111: I_fmt=6'b0001000;//U
			7'b0010111:	I_fmt=6'b0001000;//U
			7'b1101111: I_fmt=6'b0000100;//J1
			7'b1100111: I_fmt=6'b0000100;//J2
			7'b0110011: I_fmt=6'b0000010;//R
			default: 
				I_fmt=0;
		endcase
		case(I_fmt)
			6'b0000010: imm32=0;
			6'b1000000: imm32={{20{inst[31]}},inst[31:20]};//I1.I2
			6'b1000000: imm32={{20{inst[31]}},inst[31:25],inst[11:7]};//S
			6'b0010000: imm32={{20{inst[31]}},inst[7],inst[30:25],inst[11:8],1'b0};//B
			6'b0001000: imm32={inst[31:12],{12{1'b0}}};//U
			6'b0000100: imm32={{12{inst[31]}},inst[19:12],inst[20],inst[30:21],1'b0};//J1,I2
			default: 
				imm32=0;
		endcase
		
		
		
	end


endmodule


module ShowNum(//数码管模块用于显示数据
	input clk_25M,
	input [31:0] F,
	output reg [7:0]seg,
	output reg [3:0]AN
	);
	parameter count=10000;
	reg [31:0] clk_num;
	reg [3:0] digit;
	reg [2:0] which;
	
	initial
	begin
		clk_num=0;
		which=0;
		digit=0;
	end
	
	always@(posedge clk_25M)
	begin
		if(clk_num<count)
		begin clk_num<=clk_num+1;end
		else
		begin 
			clk_num<=0;
			which<=which+3'b001;
			case(which)
				0: begin digit<=F[3:0];end
				1: begin digit<=F[7:4];end
				2: begin digit<=F[11:8];end
				3: begin digit<=F[15:12];end
				4: begin digit<=F[19:16];end
				5: begin digit<=F[23:20];end
				6: begin digit<=F[27:24];end
				7: begin digit<=F[31:28];end
			endcase
		end
	end

	
	always@(digit,which)
	begin
		case(which)
			1: begin AN=4'b1111;end
			2: begin AN=4'b1110;end
			3: begin AN=4'b1101;end
			4: begin AN=4'b1100;end
			5: begin AN=4'b1011;end
			6: begin AN=4'b1010;end
			7: begin AN=4'b1001;end
			0: begin AN=4'b1000;end
			default:AN=4'bzzzz;
		endcase
		case(digit)
				0:seg[7:0]=8'b00000011;
				1:seg[7:0]=8'b10011111;
				2:seg[7:0]=8'b00100101;
				3:seg[7:0]=8'b00001101;
				4:seg[7:0]=8'b10011001;
				5:seg[7:0]=8'b01001001;
				6:seg[7:0]=8'b01000001;
				7:seg[7:0]=8'b00011111;
				8:seg[7:0]=8'b00000001;
				9:seg[7:0]=8'b00001001;	
				10:seg[7:0]=8'b00010001;
				11:seg[7:0]=8'b11000001;
				12:seg[7:0]=8'b01100011;
				13:seg[7:0]=8'b10000101;
				14:seg[7:0]=8'b01100001;
				15:seg[7:0]=8'b01110001;
				default:seg[7:0]=8'b11111111;
		endcase
	end
endmodule

三、实验仿真

1、 仿真代码

(含仿真源代码、仿真验证方案)

`timescale 1ns / 1ps


// Company: 
// Engineer:
//
// Create Date:   00:21:34 06/03/2021
// Design Name:   main
// Module Name:   D:/ShuZiDianLu/example/PCIR/test.v
// Project Name:  PCIR
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: main
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 


module test;

	// Inputs
	reg Ir_Write;
	reg PC_Write;
	reg clk_im;
	reg clk_n;
	reg clk_25M;

	// Outputs
	wire [4:0] rs1;
	wire [4:0] rs2;
	wire [4:0] rd;
	wire [3:0] AN;
	wire [7:0] seg;
	wire [6:0] opcode;
	wire [2:0] funct3;
	wire [6:0] funct7;

	// Instantiate the Unit Under Test (UUT)
	main uut (
		.Ir_Write(Ir_Write), 
		.PC_Write(PC_Write), 
		.clk_im(clk_im), 
		.clk_n(clk_n), 
		.clk_25M(clk_25M), 
		.rs1(rs1), 
		.rs2(rs2), 
		.rd(rd), 
		.AN(AN), 
		.seg(seg), 
		.opcode(opcode), 
		.funct3(funct3), 
		.funct7(funct7)
	);

	initial begin
		// Initialize Inputs
		Ir_Write = 0;
		PC_Write = 0;
		clk_im = 0;
		clk_n = 0;
		clk_25M = 0;

		// Wait 100 ns for global reset to finish
		#100;
        
		// Add stimulus here
		Ir_Write=1;
		PC_Write=1;
		#100
		clk_im = 1;
		#20
		clk_im = 0;
		#100
		clk_im = 1;
		#20
		clk_im = 0;
		#100
		clk_im = 1;
		#20
		clk_im = 0;
		#100
		clk_im = 1;
		#20
		clk_im = 0;
		#100
		clk_im = 1;
		#20
		clk_im = 0;
		#100
		clk_im = 1;
		#20
		clk_im = 0;
		#100
		clk_im = 1;
		#20
		clk_im = 0;
		#100
		clk_im = 1;
		#20
		clk_im = 0;
	end
	
	initial begin
		forever #1 clk_25M=~clk_25M;	
	end
      
endmodule

2、 仿真波形
(运行仿真时,波形截图)
杭电计算机组成原理实验RISC-V 实验 取指令及指令译码实验

3、 仿真结果分析
(对仿真波形进行分析)
符合要求

四、电路图
(开发工具中显示的电路模块图)
杭电计算机组成原理实验RISC-V 实验 取指令及指令译码实验

五、引脚配置
(引脚约束文件的内容,描述主要配置情况)

NET "AN[3]" LOC = L21;
NET "AN[2]" LOC = M22;
NET "AN[1]" LOC = M21;
NET "AN[0]" LOC = N22;
NET "seg[7]" LOC = H19;
NET "seg[6]" LOC = G20;
NET "seg[5]" LOC = J22;
NET "seg[4]" LOC = K22;
NET "seg[3]" LOC = K21;
NET "seg[2]" LOC = H20;
NET "seg[0]" LOC = J21;
NET "seg[1]" LOC = H22;


NET "AN[3]" IOSTANDARD = LVCMOS18;
NET "AN[2]" IOSTANDARD = LVCMOS18;
NET "AN[1]" IOSTANDARD = LVCMOS18;
NET "AN[0]" IOSTANDARD = LVCMOS18;
NET "funct3[2]" IOSTANDARD = LVCMOS18;
NET "funct3[1]" IOSTANDARD = LVCMOS18;
NET "funct3[0]" IOSTANDARD = LVCMOS18;
NET "funct7[6]" IOSTANDARD = LVCMOS18;
NET "funct7[5]" IOSTANDARD = LVCMOS18;
NET "funct7[4]" IOSTANDARD = LVCMOS18;
NET "funct7[3]" IOSTANDARD = LVCMOS18;
NET "funct7[2]" IOSTANDARD = LVCMOS18;
NET "funct7[1]" IOSTANDARD = LVCMOS18;
NET "funct7[0]" IOSTANDARD = LVCMOS18;
NET "opcode[6]" IOSTANDARD = LVCMOS18;
NET "opcode[5]" IOSTANDARD = LVCMOS18;
NET "opcode[4]" IOSTANDARD = LVCMOS18;
NET "opcode[3]" IOSTANDARD = LVCMOS18;
NET "opcode[2]" IOSTANDARD = LVCMOS18;
NET "opcode[1]" IOSTANDARD = LVCMOS18;
NET "opcode[0]" IOSTANDARD = LVCMOS18;
NET "rd[4]" IOSTANDARD = LVCMOS18;
NET "rd[3]" IOSTANDARD = LVCMOS18;
NET "rd[2]" IOSTANDARD = LVCMOS18;
NET "rd[1]" IOSTANDARD = LVCMOS18;
NET "rd[0]" IOSTANDARD = LVCMOS18;
NET "rs1[4]" IOSTANDARD = LVCMOS18;
NET "rs1[3]" IOSTANDARD = LVCMOS18;
NET "rs1[2]" IOSTANDARD = LVCMOS18;
NET "rs1[1]" IOSTANDARD = LVCMOS18;
NET "rs1[0]" IOSTANDARD = LVCMOS18;
NET "rs2[4]" IOSTANDARD = LVCMOS18;
NET "rs2[3]" IOSTANDARD = LVCMOS18;
NET "rs2[2]" IOSTANDARD = LVCMOS18;
NET "rs2[1]" IOSTANDARD = LVCMOS18;
NET "rs2[0]" IOSTANDARD = LVCMOS18;
NET "seg[7]" IOSTANDARD = LVCMOS18;
NET "seg[6]" IOSTANDARD = LVCMOS18;
NET "seg[5]" IOSTANDARD = LVCMOS18;
NET "seg[4]" IOSTANDARD = LVCMOS18;
NET "seg[3]" IOSTANDARD = LVCMOS18;
NET "seg[2]" IOSTANDARD = LVCMOS18;
NET "seg[1]" IOSTANDARD = LVCMOS18;
NET "seg[0]" IOSTANDARD = LVCMOS18;
NET "clk_im" IOSTANDARD = LVCMOS18;
NET "clk_n" IOSTANDARD = LVCMOS18;
NET "clk_25M" IOSTANDARD = LVCMOS18;
NET "Ir_Write" IOSTANDARD = LVCMOS18;
NET "PC_Write" IOSTANDARD = LVCMOS18;


NET "clk_25M" LOC = H4;
NET "clk_im" LOC = R4;
NET "clk_n" LOC = AA4;
NET "Ir_Write" LOC = T3;
NET "PC_Write" LOC = U3;


NET "clk_25M" PULLDOWN;
NET "clk_im" PULLDOWN;
NET "Ir_Write" PULLDOWN;
NET "clk_n" PULLDOWN;
NET "PC_Write" PULLDOWN;

#PlanAhead Generated physical constraints 

NET "opcode[0]" LOC = J4;
NET "opcode[1]" LOC = L4;
NET "opcode[2]" LOC = N4;
NET "opcode[3]" LOC = H3;
NET "opcode[4]" LOC = K3;
NET "opcode[5]" LOC = M3;
NET "opcode[6]" LOC = N3;
NET "rd[0]" LOC = B2;
NET "rd[1]" LOC = B1;
NET "rd[2]" LOC = D1;
NET "rd[3]" LOC = E2;
NET "rd[4]" LOC = F1;
NET "funct3[0]" LOC = G2;
NET "funct3[1]" LOC = H2;
NET "funct3[2]" LOC = J1;
NET "rs1[0]" LOC = K1;
NET "rs1[1]" LOC = G4;
NET "rs1[3]" LOC = G3;
NET "rs1[4]" LOC = L3;
NET "rs1[2]" LOC = K4;
NET "rs2[0]" LOC = A1;
NET "rs2[1]" LOC = D2;
NET "rs2[2]" LOC = E1;
NET "rs2[3]" LOC = G1;
NET "rs2[4]" LOC = J2;
NET "funct7[0]" LOC = L1;
NET "funct7[1]" LOC = M2;
NET "funct7[2]" LOC = M1;
NET "funct7[3]" LOC = N2;
NET "funct7[4]" LOC = P1;
NET "funct7[5]" LOC = P2;
NET "funct7[6]" LOC = R1;

六、思考与探索

1、 实验结果记录:

(实验操作的过程及结果记录)
实验6实验结果记录表
PC IR COE文件中指令代码 汇编指令 立即数imm32 解析字段是否正确
00000000 000002b3 000002b3 add 00000000 对
00000004 00000333 00000333 add 00000000 对
00000008 00a00393 00a00393 li 0000000A 对
000000C 04032e03 04032e03 lw 00000040 对
00000010 01c282b3 01c282b3 add 00000000 对
00000014 00430313 00430313 addi 00000004 对

2、 实验结论:

(分析实验结果,给出实验结论)
实验符合要求

3、 问题与解决方案:

(整个实验过程中发生了什么问题?你是如何解决的。)
问题存在但已经解决

4、 思考题:

a) 先读的是0号单元的数据,因为是先取数据再PC+4

b) 可以

c) 可能出现抖动,所以需要按的更慢点

d) 学习了很多,获得了很多

上一篇:浅谈JavaScript闭包


下一篇:校门外的树(离散化)