同样是RISC-V处理器,一字之差导致代码量也多了很多。流水线处理器的模块实在是太多了,处理一条指令都得要五个阶段模块,而且阶段之间还得要过渡的模块,重定向,阻塞和清除的逻辑也有点不太好懂。特别涉及的变量更是让人眼花缭乱,花了大概两天把大致逻辑架构实现了,后面三天时间全在调试检查每个模块有没有缺少的变量或是写错名字的变量,只能说尽力了。话不多说,涉及的模块代码如下:

mux2.sv:一个2:1的选择器模块

`timescale 1ns / 1ps

module mux2(input logic[31:0]d0,
             input logic[31:0]d1,
             input logic s,
             output logic[31:0]y);
	assign y = s?d1:d0;
endmodule

pc_change.sv:用于调整PC变化的模块

`timescale 1ns / 1ps

module pc_change(input logic clk,
                input logic stall_F,
                input logic reset,
                input logic [31:0]d,
                output logic [31:0]q);
	
	always_ff@(posedge clk,posedge reset)
		if (reset)
			q <= 0;
		else if(stall_F)
			q <= q;
	    else
	        q <= d;
endmodule

instr_mem.sv:指令存储器模块

`timescale 1ns / 1ps

module instr_mem(input logic[5:0] a,
                 output logic[31:0]rd);
/*
logic[31:0]RAM[63:0];
initial
	$readmemh("C:\Users\DELL\Desktop\单周期RISC-V处理器设计\memfile.dat",RAM);
*/
// 不要声明很大的数组,FPGA板子放不下

//基本测试:用于跑simulation

logic[31:0]RAM[0:18] = { // 注意!指令存储器容量最多只有64个字!
32'h00500113,
32'h00c00193,
32'hff718393,
32'h0023e233,
32'h0041f2b3,
32'h004282b3,
32'h02728663,
32'h0041a233,
32'h00020463,
32'h00000293,
32'h0023a233,
32'h005203b3,
32'h402383b3,
32'h0471a223,
32'h05002103,
32'h008000ef,
32'h00100113,
32'h04202a23,
32'hfe000ee3	// beq $0,$0,self,跳转到自己,终止执行后续指令
};

//求1到100和的测试:用于跑板子
/*
logic[31:0]RAM[0:11] = { // 注意!指令存储器容量最多只有64个字!
32'h000003b7,
32'h00038393,
32'h00000437,
32'h06340413,
32'h000004b7,
32'h00048493,
32'h00944863,
32'h00148493,
32'h009383b3,
32'hff5ff0ef,
32'h04702a23,
32'hfe000ee3    // beq $0,$0,self,跳转到自己,终止执行后续指令
};
*/
assign rd = RAM[a]; // 注意!指令存储器容量最多只有64个字!
endmodule

control.sv:控制器,根据输入的机器码决定一系列控制信号模块

`timescale 1ns / 1ps

module control(input logic [6:0]opcode,
                  input logic [6:0]funct7,
                  input logic [2:0]funct3,
                  output logic [2:0]immpro_D,
                  output logic isonlyimm_D,
                  output logic memtoreg_D,
                  output logic memwrite_D,
                  output logic branch_beq_D,
                  output logic branch_bne_D,
                  output logic branch_blt_D,
                  output logic alusrc_D,
                  output logic regwrite_D,
                  output logic jump_D,
                  output logic [3:0]alucontrol_D
                );
	logic [15:0]controls;
	always_comb
		case(opcode)
			7'b0110011://处理R指令
                case(funct7)
                     7'b0000000:
                         case(funct3)
                             3'b000:controls=16'b1_0_0_0_0_0_0_0_0010_000_0;//add
                             3'b001:controls=16'b1_0_0_0_0_0_0_0_0100_000_0;//sll
                             3'b010:controls=16'b1_0_0_0_0_0_0_0_0111_000_0;//slt
                             3'b100:controls=16'b1_0_0_0_0_0_0_0_0101_000_0;//xor
                             3'b101:controls=16'b1_0_0_0_0_0_0_0_0011_000_0;//srl
                             3'b110:controls=16'b1_0_0_0_0_0_0_0_0001_000_0;//or
                             3'b111:controls=16'b1_0_0_0_0_0_0_0_0000_000_0;//and
                             default:controls=16'b0_0_0_0_0_0_0_0_0000_000_0;
                         endcase
                     7'b0100000:
                         case(funct3)
                             3'b000:controls=16'b1_0_0_0_0_0_0_0_0110_000_0;//sub
                             3'b101:controls=16'b1_0_0_0_0_0_0_0_1000_000_0;//sra
                             default:controls=16'b0_0_0_0_0_0_0_0_0000_000_0;
                         endcase
                     default:controls=16'b0_0_0_0_0_0_0_0_0000_000_0;
                 endcase
             7'b0010011://第一类I指令
                 case(funct3)
                     3'b000:controls=16'b1_1_0_0_0_0_0_0_0010_001_0;//addi
                     3'b110:controls=16'b1_1_0_0_0_0_0_0_0001_001_0;//ori
                     3'b111:controls=16'b1_1_0_0_0_0_0_0_0000_001_0;//andi
                     default:controls=16'b0_0_0_0_0_0_0_0_0000_000_0;
                 endcase
             7'b0000011://lw指令
                controls=16'b1_1_0_0_0_0_1_0_0010_001_0;//lw
             7'b0100011://sw指令
                controls=16'b0_1_0_0_0_1_0_0_0010_010_0;//sw
             7'b1100111://jalr指令
                controls=16'b1_1_0_0_0_0_0_1_0010_001_0;//jalr
             7'b1100011://B指令
                case(funct3)
                    3'b000:controls=16'b0_0_1_0_0_0_0_0_0110_011_0;//beq
                    3'b001:controls=16'b0_0_0_1_0_0_0_0_0110_011_0;//bne
                    3'b100:controls=16'b0_0_0_0_1_0_0_0_0110_011_0;//blt
                    default:controls=16'b0_0_0_0_0_0_0_0_0000_000_0;
                endcase
             7'b1101111://J指令
                controls=16'b0_0_0_0_0_0_0_1_0010_101_0;//jal
             7'b0110111:
                controls=16'b1_1_0_0_0_0_0_0_0010_100_1;//lui
             default:controls=16'b0_0_0_0_0_0_0_0_0000_000_0;
         endcase 
         
    assign {regwrite_D,alusrc_D,branch_beq_D,branch_bne_D,branch_blt_D,
    memwrite_D,memtoreg_D,jump_D,alucontrol_D,immpro_D,isonlyimm_D} = controls; 
      		         
endmodule

 immprocess.sv:立即数处理模块

`timescale 1ns / 1ps

module immprocess(input logic[31:0]instr,
                  input logic[2:0]immpro,
                  output logic[31:0]y);
	always_comb
	   case(immpro)
	       3'b001:y={{20{instr[31]}},instr[31:20]};
	       3'b010:y={{20{instr[31]}},instr[31:25],instr[11:7]};
	       3'b011:y={{19{instr[31]}},instr[31],instr[7],instr[30:25],instr[11:8],1'b0};
	       3'b100:y={instr[31:12],12'b0};
	       3'b101:y={{11{instr[31]}},instr[31],instr[19:12],instr[20],instr[30:21],1'b0};
	       default:y=32'b0;
	   endcase
endmodule

 register_file.sv:寄存器文件模块

`timescale 1ns / 1ps

module register_file(input logic clk,
                    input logic we3,
                    input logic reset,
                    input logic[4:0] ra1,
                    input logic[4:0] ra2,
                    input logic[4:0] wa3,
                    input logic[31:0]wd3,
                    output logic[31:0]rd1,
                    output logic[31:0]rd2,
                    output logic[31:0]rf[31:0]);
	
	//logic[31:0]rf[31:0];
	//three ported register file
	// read two ports combinationally
	// write third port on rising edge of clk
	// register 0 hardwired to0
	// note:for pipelined processor,write third port on falling edge of clk
	always_ff@(posedge clk,posedge reset)begin
		if (we3)
			rf[wa3] <= wd3;
	    else if(reset) begin
	        rf[0]=32'b0;rf[1]=32'b0;
	        rf[2]=32'b0;rf[3]=32'b0;
	        rf[4]=32'b0;rf[5]=32'b0;
	        rf[6]=32'b0;rf[7]=32'b0;
	        rf[8]=32'b0;rf[9]=32'b0;
	        rf[10]=32'b0;rf[11]=32'b0;
	        rf[12]=32'b0;rf[13]=32'b0;
	        rf[14]=32'b0;rf[15]=32'b0;
	        rf[16]=32'b0;rf[17]=32'b0;
	        rf[18]=32'b0;rf[19]=32'b0;
	        rf[20]=32'b0;rf[21]=32'b0;
	        rf[22]=32'b0;rf[23]=32'b0;
	        rf[24]=32'b0;rf[25]=32'b0;
	        rf[26]=32'b0;rf[27]=32'b0;
	        rf[28]=32'b0;rf[29]=32'b0;
	        rf[30]=32'b0;rf[31]=32'b0;end
	   end
	             
	assign rd1 = (ra1!= 0)?rf[ra1]:0;
	assign rd2 = (ra2!= 0)?rf[ra2]:0;
endmodule

 mux4.sv:一个4:1的选择器模块

`timescale 1ns / 1ps

module mux4(input logic[31:0]d0,
             input logic[31:0]d1,
             input logic[31:0]d2,
             input logic[31:0]d3,
             input logic [1:0]s,
             output logic [31:0]y);
             
	always_comb
	   case(s)
	       2'b00:y=d0;
	       2'b01:y=d1;
	       2'b10:y=d2;
	       2'b11:y=d3;
	       default:y=32'b0;
	   endcase
	   
endmodule

 pro_beq_signal.sv:处理汇编指令中beq的跳转信号模块

`timescale 1ns / 1ps


module pro_beq_signal(input logic[31:0] res1_D,
                      input logic[31:0] res2_D,
                      input logic branch_beq,
                      output logic pcsrc_beq
    );
    logic beq_D;
                 
    assign beq_D=(res1_D==res2_D);
    assign pcsrc_beq=beq_D & branch_beq;
                 
    
endmodule

 pro_bne_signal.sv:处理汇编指令中bne的跳转信号模块

`timescale 1ns / 1ps


module pro_bne_signal(input logic[31:0] res1_D,
                      input logic[31:0] res2_D,
                      input logic branch_bne,
                      output logic pcsrc_bne
    );
    logic bne_D;
                            
    assign bne_D=(res1_D!=res2_D);
    assign pcsrc_bne=bne_D & branch_bne;
                 
    
endmodule

 pro_blt_signal.sv:处理汇编指令中blt的跳转信号模块

`timescale 1ns / 1ps

module pro_blt_signal(input logic[31:0] res1_D,
                      input logic[31:0] res2_D,
                      input logic branch_blt,
                      output logic pcsrc_blt
    );
    logic blt_D;
                 
    assign blt_D=(res1_D<res2_D);
    assign pcsrc_blt=blt_D & branch_blt;
                 
    
endmodule

 ALU.sv:根据alucontrol的信号决定ALU进行何种运算的模块

`timescale 1ns / 1ps

module ALU(input logic [31:0] srca,
           input logic [31:0] srcb,
           input logic [3:0] alucontrol,
           output logic [31:0] aluout
         );
	always_comb
		case (alucontrol)
			4'b0010: aluout  = srca + srcb;
			4'b0110: aluout  = srca - srcb;
			4'b0000: aluout  = srca & srcb;
			4'b0001: aluout  = srca | srcb;
			4'b0111: aluout  = (srca < srcb) ? 32'd1 : 32'd0;
			4'b0011: aluout  = srca >> srcb;
			4'b0100: aluout  = srca << srcb;
			4'b0101: aluout  = srca ^ srcb;
			4'b1000: aluout  = srca >>> srcb;
			default: aluout = 32'b0;
		endcase

endmodule

 data_mem.sv:数据存储器模块

`timescale 1ns / 1ps

module data_mem(input logic clk,
                input logic we,
                input logic reset,
                input logic[31:0]a,
                input logic[31:0]wd,
                output logic[31:0]rd);
	
	// 不要声明很大的数组,FPGA板子放不下
	logic[31:0]RAM[63:0];	// 注意!数据存储器容量最多只有64个字!
	assign rd = RAM[a[7:2]]; // word aligned
	
	always_ff@(posedge clk)begin
		if (we)
			RAM[a[7:2]] <= wd;
	    else if(reset)begin
	       for(integer i=0;i<64;i++)
	           RAM[i]=32'b0;
	       end
	    end	    
endmodule

 fetch.sv:取指阶段的模块

`timescale 1ns / 1ps

module fetch(input logic clk,
             input logic reset,
             input logic stall_F,
             input logic branch_or_jump,
             input logic[31:0] pcbranch_D,
             output logic[31:0] pc_F,
             output logic[31:0] instr_F
    );
    
    logic [31:0]pcplus4,pcnext;
    assign pcplus4=pc_F+32'b100;
    
    mux2 pc_next(
                 .d0(pcplus4),
                 .d1(pcbranch_D),
                 .s(branch_or_jump),
                 .y(pcnext)
    );
    
    pc_change change(
                    .clk(clk),
                    .reset(reset),
                    .stall_F(stall_F),
                    .d(pcnext),
                    .q(pc_F)
    );
    
    instr_mem im(
                  .a(pc_F[7:2]),
                  .rd(instr_F)
    );
    
    
endmodule

fetch_to_decode.sv:取指到译码阶段的过渡模块

`timescale 1ns / 1ps

module fetch_to_decode(input logic clk,
                       input logic branch_or_jump,
                       input logic reset,
                       input logic stall_D,
                       input logic[31:0] pc_F,
                       input logic[31:0] instr_F,
                       output logic[31:0] pc_D,
                       output logic[31:0] instr_D
    );
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset) begin
            pc_D<=32'b0;
            instr_D<=32'b0;end
        else if(stall_D) begin
            pc_D<=pc_D;
            instr_D<=instr_D;end
        else if(branch_or_jump) begin
            pc_D<=32'b0;
            instr_D<=32'b0;end
        else begin
            pc_D<=pc_F;
            instr_D<=instr_F;end
    end
endmodule

decode.sv:译码阶段的模块 

`timescale 1ns / 1ps

module decode(input logic [31:0] instr_D,
              input logic [31:0] pc_D,
              input logic clk,
              input logic reset,
              input logic regwrite_W,
              input logic [4:0]rd_W,
              input logic [31:0]result_W,
              input logic [31:0]ALUOut_E,
              input logic [31:0]ALUOut_M,
              input logic [1:0]ForwardAD,
              input logic [1:0]ForwardBD,
              output logic isonlyimm_D,
              output logic memtoreg_D,
              output logic memwrite_D,
              output logic alusrc_D,
              output logic regwrite_D,
              output logic branch_or_jump,
              output logic is_stall,
              output logic [3:0]alucontrol_D,
              output logic [31:0]imm_D,
              output logic [31:0]res1_D,
              output logic [31:0]res2_D,
              output logic [4:0]rs1_D,
              output logic [4:0]rs2_D,
              output logic [4:0]rd_D,
              output logic[31:0]rf[31:0],
              output logic[31:0]pcbranch_D
); 
    logic [2:0]immpro_D;
    logic branch_beq_D,branch_bne_D,branch_blt_D,jump_D;
    logic pcsrc_bne,pcsrc_blt,pcsrc_beq;
    logic [31:0]rd1_D,rd2_D;
    
    control c(
		.opcode(instr_D[6:0]),
		.funct7(instr_D[31:25]),
		.funct3(instr_D[14:12]),
		.immpro_D(immpro_D),
		.isonlyimm_D(isonlyimm_D),
		.memtoreg_D(memtoreg_D),
		.memwrite_D(memwrite_D),
        .branch_beq_D(branch_beq_D),
        .branch_bne_D(branch_bne_D),
		.alusrc_D(alusrc_D),
		.regwrite_D(regwrite_D),
		.jump_D(jump_D),
		.alucontrol_D(alucontrol_D),
		.branch_blt_D(branch_blt_D)
	);
    
    immprocess immp(.instr(instr_D),
                    .immpro(immpro_D),
                    .y(imm_D)
    );
    
    register_file rfile(
        .clk(clk),
        .reset(reset),
        .we3(regwrite_W),
        .ra1(instr_D[19:15]),
        .ra2(instr_D[24:20]),
        .wa3(rd_W),
        .wd3(result_W),
        .rd1(rd1_D),
        .rd2(rd2_D),
        .rf(rf)
    );
    
    mux4 sel_1(
              .d0(rd1_D),
              .d1(ALUOut_M),
              .d2(result_W),
              .d3(ALUOut_E),
              .s(ForwardAD), 
              .y(res1_D)  
    );
    
    mux4 sel_2(
              .d0(rd2_D),
              .d1(ALUOut_M),
              .d2(result_W),
              .d3(ALUOut_E),
              .s(ForwardBD), 
              .y(res2_D)  
    );
    
    pro_beq_signal beq_D(.res1_D(res1_D),
                         .res2_D(res2_D),
                         .branch_beq(branch_beq_D),
                         .pcsrc_beq(pcsrc_beq)
    );
    
    pro_bne_signal bne_D(.res1_D(res1_D),
                         .res2_D(res2_D),
                         .branch_bne(branch_bne_D),
                         .pcsrc_bne(pcsrc_bne)
    );
    
    pro_blt_signal blt_D(.res1_D(res1_D),
                         .res2_D(res2_D),
                         .branch_blt(branch_blt_D),
                         .pcsrc_blt(pcsrc_blt)
    );
    
    assign rs1_D=instr_D[19:15];
    assign rs2_D=instr_D[24:20];
    assign rd_D=instr_D[11:7];
    assign pcbranch_D=imm_D+pc_D;
    assign is_stall=branch_blt_D | branch_beq_D | branch_bne_D;
    assign branch_or_jump=pcsrc_beq | pcsrc_bne | pcsrc_blt | jump_D;
        
endmodule

decode_to_execute.sv:译码到执行阶段的过渡模块

`timescale 1ns / 1ps

module decode_to_execute(input logic clk,
                         input logic reset,
                         input logic flush_E,
                         input logic isonlyimm_D,
                         input logic memtoreg_D,
                         input logic memwrite_D,
                         input logic alusrc_D,
                         input logic regwrite_D,
                         input logic [3:0]alucontrol_D,
                         input logic [31:0]imm_D,
                         input logic [31:0]res1_D,
                         input logic [31:0]res2_D,
                         input logic [4:0]rs1_D,
                         input logic [4:0]rs2_D,
                         input logic [4:0]rd_D,
                         output logic isonlyimm_E,
                         output logic memtoreg_E,
                         output logic memwrite_E,
                         output logic alusrc_E,
                         output logic regwrite_E,
                         output logic [3:0]alucontrol_E,
                         output logic [31:0]imm_E,
                         output logic [31:0]res1_E,
                         output logic [31:0]res2_E,
                         output logic [4:0]rs1_E,
                         output logic [4:0]rs2_E,
                         output logic [4:0]rd_E
    );
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset | flush_E) begin
            isonlyimm_E<=1'b0;
            memwrite_E<=1'b0;
            memtoreg_E<=1'b0;
            alusrc_E<=1'b0;
            regwrite_E<=1'b0;end
        else begin
            isonlyimm_E<=isonlyimm_D;
            memwrite_E<=memwrite_D;
            memtoreg_E<=memtoreg_D;
            alusrc_E<=alusrc_D;
            regwrite_E<=regwrite_D;end
    end
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset | flush_E) begin
            imm_E<=32'b0;
            res1_E<=32'b0;
            res2_E<=32'b0;end
        else begin
            imm_E<=imm_D;
            res1_E<=res1_D;
            res2_E<=res2_D;;end
    end 
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset | flush_E) begin
            rs1_E<=5'b0;
            rs2_E<=5'b0;
            rd_E<=5'b0;end
        else begin
            rs1_E<=rs1_D;
            rs2_E<=rs2_D;
            rd_E<=rd_D;end
    end
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset | flush_E) alucontrol_E<=4'b0;
        else alucontrol_E<=alucontrol_D;
    end
                   
endmodule

execute.sv:执行阶段的模块

`timescale 1ns / 1ps

module execute(input logic alusrc_E,
               input logic [3:0]alucontrol_E,
               input logic [31:0]imm_E,
               input logic [31:0]imm_M,
               input logic [31:0]res1_E,
               input logic [31:0]res2_E,
               input logic [1:0]ForwardAE,
               input logic [1:0]ForwardBE,
               input logic [31:0]result_W,
               input logic [31:0]ALUOut_M,
               output logic [31:0]ALUOut_E,
               output logic [31:0]writedata_E              
    );
    
    logic [31:0]srcA_E,srcB_E;
    
    mux4 srca_E(
                .d0(res1_E),
                .d1(result_W),
                .d2(ALUOut_M),
                .d3(imm_M),
                .s(ForwardAE),
                .y(srcA_E)
    );
    
    mux4 srcb_E_mid(
                    .d0(res2_E),
                    .d1(result_W),
                    .d2(ALUOut_M),
                    .d3(imm_M),
                    .s(ForwardBE),
                    .y(writedata_E)
    );
    
    mux2 srcb_E(
                .d0(writedata_E),
                .d1(imm_E),
                .s(alusrc_E),
                .y(srcB_E)
    );
    
    ALU alu(
            .srca(srcA_E),
            .srcb(srcB_E),
            .alucontrol(alucontrol_E),
            .aluout(ALUOut_E)
    );
    
    
endmodule

execute_to_memory.sv:执行到访存阶段的过渡模块

`timescale 1ns / 1ps

module execute_to_memory(input logic clk,
                         input logic reset,
                         input logic isonlyimm_E,
                         input logic memtoreg_E,
                         input logic memwrite_E,
                         input logic regwrite_E,
                         input logic [31:0]imm_E,
                         input logic [4:0]rd_E,
                         input logic [31:0]ALUOut_E,
                         input logic [31:0]writedata_E,
                         output logic isonlyimm_M,
                         output logic memtoreg_M,
                         output logic memwrite_M,
                         output logic regwrite_M,
                         output logic [31:0]imm_M,
                         output logic [4:0]rd_M,
                         output logic [31:0]ALUOut_M,
                         output logic [31:0]writedata_M
    );
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset) begin
            isonlyimm_M<=1'b0;
            memwrite_M<=1'b0;
            memtoreg_M<=1'b0;
            regwrite_M<=1'b0;end
        else begin
            isonlyimm_M<=isonlyimm_E;
            memwrite_M<=memwrite_E;
            memtoreg_M<=memtoreg_E;
            regwrite_M<=regwrite_E;end
    end
    
     always_ff@(posedge clk,posedge reset)begin
        if(reset) begin
            imm_M<=32'b0;
            ALUOut_M<=32'b0;
            writedata_M<=32'b0;end
        else begin
            imm_M<=imm_E;
            ALUOut_M<=ALUOut_E;
            writedata_M<=writedata_E;;end
    end 
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset) rd_M<=5'b0;
        else rd_M<=rd_E;
    end
endmodule

memory.sv:访存阶段的模块

`timescale 1ns / 1ps

module memory(input logic clk,
              input logic reset,
              input logic[31:0] ALUOut_M,
              input logic[31:0] writedata_M,
              input logic memwrite_M,
              output logic[31:0] readdata_M
    );
    
    data_mem dmem (
                    .a(ALUOut_M),
                    .reset(reset),
                    .we(memwrite_M),
                    .wd(writedata_M),
                    .clk(clk),
                    .rd(readdata_M)
    );
    
    
endmodule

 memory_to_writeback.sv:访存到写回阶段的过渡模块

`timescale 1ns / 1ps

module memory_to_writeback(input logic clk,
                           input logic reset,
                           input logic[31:0] readdata_M,
                           input logic[31:0] ALUOut_M,
                           input logic[31:0] imm_M,
                           input logic[4:0] rd_M,
                           input logic regwrite_M,
                           input logic memtoreg_M,
                           input logic isonlyimm_M,
                           output logic[31:0] readdata_W,
                           output logic[31:0] ALUOut_W,
                           output logic[31:0] imm_W,
                           output logic[4:0] rd_W,
                           output logic regwrite_W,
                           output logic memtoreg_W,
                           output logic isonlyimm_W
    );
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset) begin
            isonlyimm_W<=1'b0;
            memtoreg_W<=1'b0;
            regwrite_W<=1'b0;end
        else begin
            isonlyimm_W<=isonlyimm_M;
            memtoreg_W<=memtoreg_M;
            regwrite_W<=regwrite_M;end
    end
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset) begin
            imm_W<=32'b0;
            ALUOut_W<=32'b0;
            readdata_W<=32'b0;end
        else begin
            imm_W<=imm_M;
            ALUOut_W<=ALUOut_M;
            readdata_W<=readdata_M;end
    end 
    
    always_ff@(posedge clk,posedge reset)begin
        if(reset) rd_W<=5'b0;
        else rd_W<=rd_M;
    end
    
endmodule

writeback.sv:写回阶段的模块

`timescale 1ns / 1ps

module writeback(input logic memtoreg_W,
                 input logic isonlyimm_W,
                 input logic[31:0] readdata_W,
                 input logic[31:0] ALUOut_W,
                 input logic[31:0] imm_W,
                 output logic[31:0] result_W
    );
    
    logic[31:0] res_mid;
    
    mux2 r_mid(
                .d0(ALUOut_W),
                .d1(readdata_W),
                .s(memtoreg_W),
                .y(res_mid)
    );
    
    mux2 r_real(
                .d0(res_mid),
                .d1(imm_W),
                .s(isonlyimm_W),
                .y(result_W)
    );
    
endmodule

Forward.sv:重定向模块

`timescale 1ns / 1ps

module Forward(input logic[4:0] rd_M,
               input logic[4:0] rd_W,
               input logic[4:0] rd_E,
               input logic[4:0] rs1_E,
               input logic[4:0] rs1_D,
               input logic[4:0] rs2_E,
               input logic[4:0] rs2_D,
               input logic regwrite_E,
               input logic regwrite_M,
               input logic regwrite_W,
               input logic isonlyimm_M,
               output logic[1:0] ForwardAD,
               output logic[1:0] ForwardBD,
               output logic[1:0] ForwardAE,
               output logic[1:0] ForwardBE
    );
    
    always_comb begin
        if(rd_M!=5'b0 & rs1_E==rd_M & regwrite_M & isonlyimm_M) ForwardAE=2'b11;
        else if(rd_M!=5'b0 & rs1_E==rd_M & regwrite_M & ~isonlyimm_M) ForwardAE=2'b10;
        else if(rd_W!=5'b0 & rs1_E==rd_W & regwrite_W) ForwardAE=2'b01;
        else ForwardAE=2'b00;end
    
    always_comb begin
        if(rd_M!=5'b0 & rs2_E==rd_M & regwrite_M & isonlyimm_M) ForwardBE=2'b11;
        else if(rd_M!=5'b0 & rs2_E==rd_M & regwrite_M & ~isonlyimm_M) ForwardBE=2'b10;
        else if(rd_W!=5'b0 & rs2_E==rd_W & regwrite_W) ForwardBE=2'b01;
        else ForwardBE=2'b00;end
    
    always_comb begin
        if(rd_E!=5'b0 & rs1_D==rd_E & regwrite_E)ForwardAD=2'b11;
        else if(rd_M!=5'b0 & rs1_D==rd_M & regwrite_M) ForwardAD=2'b01;
        else if(rd_W!=5'b0 & rs1_D==rd_W & regwrite_W)ForwardAD=2'b10;
        else ForwardAD=2'b00;end
        
    always_comb begin
        if(rd_E!=5'b0 & rs2_D==rd_E & regwrite_E)ForwardBD=2'b11;
        else if(rd_M!=5'b0 & rs2_D==rd_M & regwrite_M) ForwardBD=2'b01;
        else if(rd_W!=5'b0 & rs2_D==rd_W & regwrite_W)ForwardBD=2'b10;
        else ForwardBD=2'b00;end
                
endmodule

stall_flush.sv:阻塞与清除模块

`timescale 1ns / 1ps

module stall_flush(input logic[4:0] rd_E,
                   input logic[4:0] rd_M,
                   input logic[4:0] rs1_D,
                   input logic[4:0] rs2_D,
                   input logic regwrite_E,
                   input logic memtoreg_E,
                   input logic memtoreg_M,
                   input logic is_stall,
                   output logic stall_F,
                   output logic stall_D,
                   output logic flush_E
    );
    
    logic lwstall,branchstall_1,branchstall_2;
    
    assign lwstall=((rs1_D==rd_E) | (rs2_D==rd_E)) & memtoreg_E;
    assign branchstall_1=is_stall & regwrite_E & (rs1_D==rd_E | rs2_D==rd_E);
    assign branchstall_2=is_stall & memtoreg_M & (rs1_D==rd_M | rs2_D==rd_M);
    assign branchstall=branchstall_1 | branchstall_2;
    assign stall_F=lwstall | branchstall;
    assign stall_D=lwstall | branchstall;
    assign flush_E=lwstall | branchstall;
    
endmodule

以上是所必需的基本模块,下面的模块分别用于跑板子和跑simulation。

(一)跑simulation所需的模块:

top.sv:用于跑simulation的顶层模块

`timescale 1ns / 1ps

module top(input logic clk,
           input logic reset,
           output logic success_led,
           output logic fail_led,
           output logic[31:0] pc_D,
           output logic[31:0] pc_F,
           output logic[31:0] rf_7,
           output logic[31:0] rf_2,
           output logic [1:0]ForwardAD,
           output logic [1:0]ForwardBD,
           output logic [1:0]ForwardAE,
           output logic [1:0]ForwardBE,
           output logic stall_D,
           output logic flush_E,
           output logic stall_F
    );
    
    logic //stall_D,flush_E,stall_F,
          regwrite_D,regwrite_E,regwrite_M,regwrite_W,
          isonlyimm_D,isonlyimm_E,isonlyimm_M,isonlyimm_W,
          memtoreg_D,memtoreg_E,memtoreg_M,memtoreg_W,
          memwrite_D,memwrite_E,memwrite_M,
          alusrc_D,alusrc_E,is_stall,branch_or_jump;
          
    //logic [1:0]ForwardAE,ForwardBE,ForwardAD,ForwardBD;
        
    logic [3:0]alucontrol_D,alucontrol_E;
    
    logic [4:0]rs1_D,rs1_E,
               rs2_D,rs2_E,
               rd_D,rd_E,rd_M,rd_W;
               
    logic [31:0] instr_F,instr_D,pcbranch_D,//pc_D,//pc_F,
                 result_W,res1_D,res2_D,res1_E,res2_E,
                 ALUOut_E,ALUOut_M,ALUOut_W,
                 imm_D,imm_E,imm_M,imm_W,
                 readdata_M,readdata_W,writedata_M,writedata_E;
                 
    logic [31:0]rf[31:0];
    
    fetch fetch(
                .clk(clk),
                .reset(reset),
                .stall_F(stall_F),
                .branch_or_jump(branch_or_jump),
                .pcbranch_D(pcbranch_D),
                .pc_F(pc_F),
                .instr_F(instr_F)
    );
    
    fetch_to_decode fetch_to_decode(
                                    .clk(clk),
                                    .reset(reset),
                                    .branch_or_jump(branch_or_jump),
                                    .stall_D(stall_D),
                                    .pc_F(pc_F),
                                    .instr_F(instr_F),
                                    .pc_D(pc_D),
                                    .instr_D(instr_D)
    );
    
    decode decode(
                  .instr_D(instr_D),
                  .pc_D(pc_D),
                  .clk(clk),
                  .reset(reset),
                  .regwrite_W(regwrite_W),
                  .rd_W(rd_W),
                  .result_W(result_W),
                  .ALUOut_M(ALUOut_M),
                  .ALUOut_E(ALUOut_E),
                  .ForwardAD(ForwardAD),
                  .ForwardBD(ForwardBD),
                  .isonlyimm_D(isonlyimm_D),
                  .memtoreg_D(memtoreg_D),
                  .memwrite_D(memwrite_D),
                  .alusrc_D(alusrc_D),
                  .regwrite_D(regwrite_D),
                  .branch_or_jump(branch_or_jump),
                  .is_stall(is_stall),
                  .alucontrol_D(alucontrol_D),
                  .imm_D(imm_D),
                  .res1_D(res1_D),
                  .res2_D(res2_D),
                  .rs1_D(rs1_D),
                  .rs2_D(rs2_D),
                  .rd_D(rd_D),
                  .rf(rf),
                  .pcbranch_D(pcbranch_D)
     ); 
     
     decode_to_execute decode_to_execute(
                                         .clk(clk),
                                         .reset(reset),
                                         .flush_E(flush_E),
                                         .isonlyimm_D(isonlyimm_D),
                                         .memtoreg_D(memtoreg_D),
                                         .memwrite_D(memwrite_D),
                                         .alusrc_D(alusrc_D),
                                         .regwrite_D(regwrite_D),
                                         .alucontrol_D(alucontrol_D),
                                         .imm_D(imm_D),
                                         .res1_D(res1_D),
                                         .res2_D(res2_D),
                                         .rs1_D(rs1_D),
                                         .rs2_D(rs2_D),
                                         .rd_D(rd_D),
                                         .isonlyimm_E(isonlyimm_E),
                                         .memtoreg_E(memtoreg_E),
                                         .memwrite_E(memwrite_E),
                                         .alusrc_E(alusrc_E),
                                         .regwrite_E(regwrite_E),
                                         .alucontrol_E(alucontrol_E),
                                         .imm_E(imm_E),
                                         .res1_E(res1_E),
                                         .res2_E(res2_E),
                                         .rs1_E(rs1_E),
                                         .rs2_E(rs2_E),
                                         .rd_E(rd_E)
    );
    
    execute execute(
                    .alusrc_E(alusrc_E),
                    .alucontrol_E(alucontrol_E),
                    .imm_E(imm_E),
                    .imm_M(imm_M),
                    .res1_E(res1_E),
                    .res2_E(res2_E),
                    .ForwardAE(ForwardAE),
                    .ForwardBE(ForwardBE),
                    .result_W(result_W),
                    .ALUOut_M(ALUOut_M),
                    .ALUOut_E(ALUOut_E),
                    .writedata_E(writedata_E)              
    ); 
    
    execute_to_memory execute_to_memory(.clk(clk),
                                        .reset(reset),
                                        .isonlyimm_E(isonlyimm_E),
                                        .memtoreg_E(memtoreg_E),
                                        .memwrite_E(memwrite_E),
                                        .regwrite_E(regwrite_E),
                                        .imm_E(imm_E),
                                        .rd_E(rd_E),
                                        .ALUOut_E(ALUOut_E),
                                        .writedata_E(writedata_E),
                                        .isonlyimm_M(isonlyimm_M),
                                        .memtoreg_M(memtoreg_M),
                                        .memwrite_M(memwrite_M),
                                        .regwrite_M(regwrite_M),
                                        .imm_M(imm_M),
                                        .rd_M(rd_M),
                                        .ALUOut_M(ALUOut_M),
                                        .writedata_M(writedata_M)
    );
    
    memory memory(
                   .clk(clk),
                   .reset(reset),
                   .ALUOut_M(ALUOut_M),
                   .writedata_M(writedata_M),
                   .memwrite_M(memwrite_M),
                   .readdata_M(readdata_M)
    );
    
    memory_to_writeback memory_to_writeback(
                                            .clk(clk),
                                            .reset(reset),
                                            .readdata_M(readdata_M),
                                            .ALUOut_M(ALUOut_M),
                                            .imm_M(imm_M),
                                            .rd_M(rd_M),
                                            .regwrite_M(regwrite_M),
                                            .memtoreg_M(memtoreg_M),
                                            .isonlyimm_M(isonlyimm_M),
                                            .readdata_W(readdata_W),
                                            .ALUOut_W(ALUOut_W),
                                            .imm_W(imm_W),
                                            .rd_W(rd_W),
                                            .regwrite_W(regwrite_W),
                                            .memtoreg_W(memtoreg_W),
                                            .isonlyimm_W(isonlyimm_W)
    );
    
    writeback writeback(
                         .memtoreg_W(memtoreg_W),
                         .isonlyimm_W(isonlyimm_W),
                         .readdata_W(readdata_W),
                         .ALUOut_W(ALUOut_W),
                         .imm_W(imm_W),
                         .result_W(result_W)
    );
    
    Forward Forward(
                    .rd_M(rd_M),
                    .rd_W(rd_W),
                    .rd_E(rd_E),
                    .rs1_E(rs1_E),
                    .rs1_D(rs1_D),
                    .rs2_E(rs2_E),
                    .rs2_D(rs2_D),
                    .regwrite_M(regwrite_M),
                    .regwrite_E(regwrite_E),
                    .regwrite_W(regwrite_W),
                    .isonlyimm_M(isonlyimm_M),
                    .ForwardAD(ForwardAD),
                    .ForwardBD(ForwardBD),
                    .ForwardAE(ForwardAE),
                    .ForwardBE(ForwardBE)
    );
    
    stall_flush stall_flush(
                            .rd_E(rd_E),
                            .rd_M(rd_M),
                            .rs1_D(rs1_D),
                            .rs2_D(rs2_D),
                            .regwrite_E(regwrite_E),
                            .memtoreg_M(memtoreg_M),
                            .memtoreg_E(memtoreg_E),
                            .is_stall(is_stall),
                            .stall_F(stall_F),
                            .stall_D(stall_D),
                            .flush_E(flush_E)
    );
    
    assign rf_7=rf[7];
    assign rf_2=rf[2];
    // 加入两个led指示灯。
    //求和:当写入存储器地址84且7号寄存器数据是5050时,点亮success_led灯;如果第1次写入的地址不是80,点亮fail_led灯
	// 测试:当写入存储器地址84且2号寄存器数据是7时,点亮success_led灯;如果第1次写入的地址不是80,点亮fail_led灯
	always_ff @(posedge clk,posedge reset)
		if (reset)
		begin
			success_led <= 1'b0;
			fail_led <= 1'b0;
		end
		else if (memwrite_M == 1'b1)
		begin
			if (ALUOut_M == 84 & rf[2] == 7)
				success_led <= 1'b1;
			else if (ALUOut_M != 80)
				fail_led <= 1'b1;
		end
endmodule

testbench.sv:用于跑simulation的仿真波形图

`timescale 1ns / 1ps

module testbench();
	logic clk;
	logic reset;
	logic success_led;
	logic fail_led;
	logic [31:0]pc_D;
	logic [31:0]pc_F;
	logic [31:0]rf_7;
	logic [31:0]rf_2;
	logic [1:0]ForwardAD;
    logic [1:0]ForwardBD;
    logic [1:0]ForwardAE;
    logic [1:0]ForwardBE;
    logic stall_D;
    logic flush_E;
    logic stall_F;
	// instantiate device to be tested
	top dut(
		.clk(clk),
		.reset(reset),
		.success_led(success_led),
		.fail_led(fail_led),
		.pc_D(pc_D),
		.pc_F(pc_F),
		.rf_7(rf_7),
		.rf_2(rf_2),
		.ForwardAD(ForwardAD),
		.ForwardBD(ForwardBD),
		.ForwardAE(ForwardAE),
		.ForwardBE(ForwardBE),
		.stall_D(stall_D),
		.flush_E(flush_E),
		.stall_F(stall_F)
	);
	
	// initialize test
	initial
	begin
		reset = 1;
		#20;
		reset = 0;
	end
	
	// generate clock to sequence tests
	always
	begin
	clk = 1;
	#5;
	clk = 0;
	#5;
	end
	
	// check results
	always@(posedge clk)
	begin
		if (success_led)
		begin
			$display("Simulation succeeded");
		end
		if (fail_led)
		begin
			$display("Simulation failed");
		end
	end
endmodule

(二)跑板子所需的模块

display.sv:用于让板子显示最后求和得到的结果

`timescale 1ns / 1ps

module display(
        input clk,
        input [31:0]num,
        output logic [10:0] disp_7seg
    ); 
  logic [1:0] sel=0;
  logic [19:0]count=0;
  logic [3:0] num1,num2,num3,num4,disp_number;

  always@(posedge clk) 
    begin  
       sel<=sel+1; 
       if(sel==4) 
          sel<=0; 
    end 
      
  assign num1=num/1000%10;
  assign num2=num/100%10;
  assign num3=num/10%10;
  assign num4=num%10;
  
  always_comb
    case(disp_number)
        4'd0: disp_7seg[6:0] = 7'b0000001;
	    4'd1: disp_7seg[6:0] = 7'b1001111;
		4'd2: disp_7seg[6:0] = 7'b0010010;
		4'd3: disp_7seg[6:0] = 7'b0000110;
		4'd4: disp_7seg[6:0] = 7'b1001100;
		4'd5: disp_7seg[6:0] = 7'b0100100;
		4'd6: disp_7seg[6:0] = 7'b0100000;
		4'd7: disp_7seg[6:0] = 7'b0001111;
		4'd8: disp_7seg[6:0] = 7'b0000000;
		4'd9: disp_7seg[6:0] = 7'b0000100;
		default: disp_7seg[6:0] = 7'b1111111;
	endcase
	
  always_comb 
    case(sel) 
        0: begin disp_7seg[10:7] = 4'b1110; disp_number = num4; end
		1: begin disp_7seg[10:7] = 4'b1101; disp_number = num3; end
		2: begin disp_7seg[10:7] = 4'b1011; disp_number = num2; end
		3: begin disp_7seg[10:7] = 4'b0111; disp_number = num1; end 
		default:begin disp_7seg[10:7] = 4'b1111; disp_number = 4'd0; end 
    endcase 
        
endmodule 

display_top.sv:跑板子所需的顶层模块

`timescale 1ns / 1ps

module display_top(input logic clk,
                   input logic reset,
                   input logic s1,
                   input logic s2,
                   input logic s3,
                   input logic s4,
                   input logic s5,
                   output logic [10:0] disp_7seg
    );
    
    logic stall_D,flush_E,branch_or_jump,stall_F,
          regwrite_D,regwrite_E,regwrite_M,regwrite_W,
          isonlyimm_D,isonlyimm_E,isonlyimm_M,isonlyimm_W,
          memtoreg_D,memtoreg_E,memtoreg_M,memtoreg_W,
          memwrite_D,memwrite_E,memwrite_M,
          alusrc_D,alusrc_E,is_stall,s_clk,show_clk;
          
    logic [1:0]ForwardAE,ForwardBE,ForwardAD,ForwardBD;
        
    logic [3:0]alucontrol_D,alucontrol_E;
    
    logic [4:0]rs1_D,rs1_E,
               rs2_D,rs2_E,
               rd_D,rd_E,rd_M,rd_W;
               
    logic [31:0] instr_F,instr_D,pcbranch_D,pc_D,pc_F,
                 result_W,res1_D,res2_D,res1_E,res2_E,
                 ALUOut_E,ALUOut_M,ALUOut_W,
                 imm_D,imm_E,imm_M,imm_W,num,
                 readdata_M,readdata_W,writedata_M,writedata_E;
                 
    logic [31:0]rf[31:0];
    
    //生成0.005s周期的时钟
    integer total=5000000;
    integer count=0;
    always_ff@(posedge clk,posedge reset)begin
        if(reset) begin
            count<=0;
            s_clk<=1'b0;end
        else begin
            count<=count+1;
            if (count==total)begin
                s_clk<=~s_clk;
                count<=0;end
            end
        end
    
    //生成周期为0.00001s的时钟,用于数码管展示结果
    integer total_s=10000;
    integer count_s=0;
    always_ff@(posedge clk,posedge reset)begin
        if(reset) begin
            count_s<=0;
            show_clk<=1'b0;end
        else begin
            count_s<=count_s+1;
            if (count_s==total_s)begin
                show_clk<=~show_clk;
                count_s<=0;end
            end
        end
    
    fetch fetch(
                .clk(s_clk),
                .reset(reset),
                .stall_F(stall_F),
                .branch_or_jump(branch_or_jump),
                .pcbranch_D(pcbranch_D),
                .pc_F(pc_F),
                .instr_F(instr_F)
    );
    
    fetch_to_decode fetch_to_decode(
                                    .clk(s_clk),
                                    .reset(reset),
                                    .branch_or_jump(branch_or_jump),
                                    .stall_D(stall_D),
                                    .pc_F(pc_F),
                                    .instr_F(instr_F),
                                    .pc_D(pc_D),
                                    .instr_D(instr_D)
    );
    
    decode decode(
                  .instr_D(instr_D),
                  .pc_D(pc_D),
                  .clk(s_clk),
                  .reset(reset),
                  .regwrite_W(regwrite_W),
                  .rd_W(rd_W),
                  .result_W(result_W),
                  .ALUOut_M(ALUOut_M),
                  .ALUOut_E(ALUOut_E),
                  .ForwardAD(ForwardAD),
                  .ForwardBD(ForwardBD),
                  .isonlyimm_D(isonlyimm_D),
                  .memtoreg_D(memtoreg_D),
                  .memwrite_D(memwrite_D),
                  .alusrc_D(alusrc_D),
                  .regwrite_D(regwrite_D),
                  .branch_or_jump(branch_or_jump),
                  .is_stall(is_stall),
                  .alucontrol_D(alucontrol_D),
                  .imm_D(imm_D),
                  .res1_D(res1_D),
                  .res2_D(res2_D),
                  .rs1_D(rs1_D),
                  .rs2_D(rs2_D),
                  .rd_D(rd_D),
                  .rf(rf),
                  .pcbranch_D(pcbranch_D)
     ); 
     
     decode_to_execute decode_to_execute(
                                         .clk(s_clk),
                                         .reset(reset),
                                         .flush_E(flush_E),
                                         .isonlyimm_D(isonlyimm_D),
                                         .memtoreg_D(memtoreg_D),
                                         .memwrite_D(memwrite_D),
                                         .alusrc_D(alusrc_D),
                                         .regwrite_D(regwrite_D),
                                         .alucontrol_D(alucontrol_D),
                                         .imm_D(imm_D),
                                         .res1_D(res1_D),
                                         .res2_D(res2_D),
                                         .rs1_D(rs1_D),
                                         .rs2_D(rs2_D),
                                         .rd_D(rd_D),
                                         .isonlyimm_E(isonlyimm_E),
                                         .memtoreg_E(memtoreg_E),
                                         .memwrite_E(memwrite_E),
                                         .alusrc_E(alusrc_E),
                                         .regwrite_E(regwrite_E),
                                         .alucontrol_E(alucontrol_E),
                                         .imm_E(imm_E),
                                         .res1_E(res1_E),
                                         .res2_E(res2_E),
                                         .rs1_E(rs1_E),
                                         .rs2_E(rs2_E),
                                         .rd_E(rd_E)
    );
    
    execute execute(
                    .alusrc_E(alusrc_E),
                    .alucontrol_E(alucontrol_E),
                    .imm_E(imm_E),
                    .imm_M(imm_M),
                    .res1_E(res1_E),
                    .res2_E(res2_E),
                    .ForwardAE(ForwardAE),
                    .ForwardBE(ForwardBE),
                    .result_W(result_W),
                    .ALUOut_M(ALUOut_M),
                    .ALUOut_E(ALUOut_E),
                    .writedata_E(writedata_E)              
    ); 
    
    execute_to_memory execute_to_memory(.clk(s_clk),
                                        .reset(reset),
                                        .isonlyimm_E(isonlyimm_E),
                                        .memtoreg_E(memtoreg_E),
                                        .memwrite_E(memwrite_E),
                                        .regwrite_E(regwrite_E),
                                        .imm_E(imm_E),
                                        .rd_E(rd_E),
                                        .ALUOut_E(ALUOut_E),
                                        .writedata_E(writedata_E),
                                        .isonlyimm_M(isonlyimm_M),
                                        .memtoreg_M(memtoreg_M),
                                        .memwrite_M(memwrite_M),
                                        .regwrite_M(regwrite_M),
                                        .imm_M(imm_M),
                                        .rd_M(rd_M),
                                        .ALUOut_M(ALUOut_M),
                                        .writedata_M(writedata_M)
    );
    
    memory memory(
                   .clk(s_clk),
                   .reset(reset),
                   .ALUOut_M(ALUOut_M),
                   .writedata_M(writedata_M),
                   .memwrite_M(memwrite_M),
                   .readdata_M(readdata_M)
    );
    
    memory_to_writeback memory_to_writeback(
                                            .clk(s_clk),
                                            .reset(reset),
                                            .readdata_M(readdata_M),
                                            .ALUOut_M(ALUOut_M),
                                            .imm_M(imm_M),
                                            .rd_M(rd_M),
                                            .regwrite_M(regwrite_M),
                                            .memtoreg_M(memtoreg_M),
                                            .isonlyimm_M(isonlyimm_M),
                                            .readdata_W(readdata_W),
                                            .ALUOut_W(ALUOut_W),
                                            .imm_W(imm_W),
                                            .rd_W(rd_W),
                                            .regwrite_W(regwrite_W),
                                            .memtoreg_W(memtoreg_W),
                                            .isonlyimm_W(isonlyimm_W)
    );
    
    writeback writeback(
                         .memtoreg_W(memtoreg_W),
                         .isonlyimm_W(isonlyimm_W),
                         .readdata_W(readdata_W),
                         .ALUOut_W(ALUOut_W),
                         .imm_W(imm_W),
                         .result_W(result_W)
    );
    
    Forward Forward(
                    .rd_M(rd_M),
                    .rd_W(rd_W),
                    .rd_E(rd_E),
                    .rs1_E(rs1_E),
                    .rs1_D(rs1_D),
                    .rs2_E(rs2_E),
                    .rs2_D(rs2_D),
                    .regwrite_M(regwrite_M),
                    .regwrite_E(regwrite_E),
                    .regwrite_W(regwrite_W),
                    .isonlyimm_M(isonlyimm_M),
                    .ForwardAD(ForwardAD),
                    .ForwardBD(ForwardBD),
                    .ForwardAE(ForwardAE),
                    .ForwardBE(ForwardBE)
    );
    
    stall_flush stall_flush(
                            .rd_E(rd_E),
                            .rd_M(rd_M),
                            .rs1_D(rs1_D),
                            .rs2_D(rs2_D),
                            .regwrite_E(regwrite_E),
                            .memtoreg_M(memtoreg_M),
                            .memtoreg_E(memtoreg_E),
                            .is_stall(is_stall),
                            .stall_F(stall_F),
                            .stall_D(stall_D),
                            .flush_E(flush_E)
    );
    
    assign num=rf[{s1,s2,s3,s4,s5}];
    
    display display(
                    .clk(show_clk),
                    .num(num),
                    .disp_7seg(disp_7seg)
    );
    
endmodule
            
    

约束文件(可以根据自己需求自行修改调整):

set_property PACKAGE_PIN W5 [get_ports clk] 
set_property IOSTANDARD LVCMOS33 [get_ports clk] 
set_property PACKAGE_PIN V17 [get_ports reset] 
set_property IOSTANDARD LVCMOS33 [get_ports reset] 

set_property PACKAGE_PIN R2 [get_ports s1] 
set_property IOSTANDARD LVCMOS33 [get_ports s1] 
set_property PACKAGE_PIN T1 [get_ports s2] 
set_property IOSTANDARD LVCMOS33 [get_ports s2] 
set_property PACKAGE_PIN U1 [get_ports s3] 
set_property IOSTANDARD LVCMOS33 [get_ports s3] 
set_property PACKAGE_PIN W2 [get_ports s4] 
set_property IOSTANDARD LVCMOS33 [get_ports s4] 
set_property PACKAGE_PIN R3 [get_ports s5] 
set_property IOSTANDARD LVCMOS33 [get_ports s5] 

set_property PACKAGE_PIN W4 [get_ports {disp_7seg[10]}] 
set_property PACKAGE_PIN V4 [get_ports {disp_7seg[9]}] 
set_property PACKAGE_PIN U4 [get_ports {disp_7seg[8]}] 
set_property PACKAGE_PIN U2 [get_ports {disp_7seg[7]}] 
set_property PACKAGE_PIN W7 [get_ports {disp_7seg[6]}] 
set_property PACKAGE_PIN W6 [get_ports {disp_7seg[5]}] 
set_property PACKAGE_PIN U8 [get_ports {disp_7seg[4]}] 
set_property PACKAGE_PIN V8 [get_ports {disp_7seg[3]}] 
set_property PACKAGE_PIN U5 [get_ports {disp_7seg[2]}] 
set_property PACKAGE_PIN V5 [get_ports {disp_7seg[1]}] 
set_property PACKAGE_PIN U7 [get_ports {disp_7seg[0]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[10]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[9]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[8]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[6]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[5]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[4]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[3]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[1]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[2]}] 
set_property IOSTANDARD LVCMOS33 [get_ports {disp_7seg[0]}]

PS:(1)注意跑板子与跑仿真图之间切换时,instr_mem.sv中的测试指令集机器码也要切换;

         (2)跑板子时将跑仿真图所需的两个模块(top.sv与testbench.sv)disable掉,跑仿真图时同理;

         (3)板子最后实现了显示每一次迭代求和计算结果的功能。具体怎么显示可以参考display_top.sv的代码去在板子上操作出来(提示:最后的计算结果存储在7号寄存器中);

         (4)记得文件路径不要带中文,否则跑不了板子!!!(不再吃亏)

 

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐