三级流水线2级

ctrl

module ctrl(
	input wire [31:0]jump_addr_i,
	input wire    	 jump_en_i,
	input wire   	 hold_flag_ex_i,
	
	output reg [31:0]jump_addr_o,
	output reg    	 jump_en_o,
	output reg   	 hold_flag_o	
);

	always @(*)begin
		jump_addr_o = jump_addr_i;
		jump_en_o   = jump_en_i; 
		if( jump_en_i || hold_flag_ex_i)begin 
			hold_flag_o = 1'b1;
		end
		else begin
			hold_flag_o = 1'b0;
		end
	end




endmodule

defines

// I type inst
`define INST_TYPE_I 7'b0010011
`define INST_ADDI   3'b000
`define INST_SLTI   3'b010
`define INST_SLTIU  3'b011
`define INST_XORI   3'b100
`define INST_ORI    3'b110
`define INST_ANDI   3'b111
`define INST_SLLI   3'b001
`define INST_SRI    3'b101

// L type inst
`define INST_TYPE_L 7'b0000011
`define INST_LB     3'b000
`define INST_LH     3'b001
`define INST_LW     3'b010
`define INST_LBU    3'b100
`define INST_LHU    3'b101

// S type inst
`define INST_TYPE_S 7'b0100011
`define INST_SB     3'b000
`define INST_SH     3'b001
`define INST_SW     3'b010

// R and M type inst
`define INST_TYPE_R_M 7'b0110011
// R type inst
`define INST_ADD_SUB 3'b000
`define INST_SLL    3'b001
`define INST_SLT    3'b010
`define INST_SLTU   3'b011
`define INST_XOR    3'b100
`define INST_SR     3'b101
`define INST_OR     3'b110
`define INST_AND    3'b111
// M type inst
`define INST_MUL    3'b000
`define INST_MULH   3'b001
`define INST_MULHSU 3'b010
`define INST_MULHU  3'b011
`define INST_DIV    3'b100
`define INST_DIVU   3'b101
`define INST_REM    3'b110
`define INST_REMU   3'b111

// J type inst
`define INST_JAL    7'b1101111
`define INST_JALR   7'b1100111

`define INST_LUI    7'b0110111
`define INST_AUIPC  7'b0010111
`define INST_NOP    32'h00000013
`define INST_NOP_OP 7'b0000001
`define INST_MRET   32'h30200073
`define INST_RET    32'h00008067

`define INST_FENCE  7'b0001111
`define INST_ECALL  32'h73
`define INST_EBREAK 32'h00100073

// J type inst
`define INST_TYPE_B 7'b1100011
`define INST_BEQ    3'b000
`define INST_BNE    3'b001
`define INST_BLT    3'b100
`define INST_BGE    3'b101
`define INST_BLTU   3'b110
`define INST_BGEU   3'b111

dff-set

module dff_set #(
	parameter DW  = 32
)
(
	input wire clk,
	input wire rst,
	input wire hold_flag_i,
	input wire [DW-1:0]  set_data, 
	input wire [DW-1:0]  data_i, 
	output reg [DW-1:0]  data_o	
);
	always @(posedge clk)begin
		if(rst == 1'b0 || hold_flag_i == 1'b1)
			data_o <= set_data;
		else
			data_o <= data_i;
	end	

endmodule

ex

`include "defines.v"

module ex(
	//from id_ex
	input wire[31:0] inst_i,	
	input wire[31:0] inst_addr_i,
	input wire[31:0] op1_i,
	input wire[31:0] op2_i,
	input wire[4:0]  rd_addr_i,
	input wire 		 rd_wen_i,
	input wire[31:0] base_addr_i,
	input wire[31:0] addr_offset_i,	
	//to regs
	output reg[4:0] rd_addr_o,
	output reg[31:0]rd_data_o,
	output reg 	    rd_wen_o,
	
	//to ctrl
	output reg[31:0]jump_addr_o,
	output reg   	jump_en_o,
	output reg  	hold_flag_o
);

	wire[6:0] opcode; 
	wire[4:0] rd; 
	wire[2:0] func3; 
	wire[4:0] rs1;
	wire[4:0] rs2;
	wire[6:0] func7;
	wire[11:0]imm;
	wire[4:0] shamt;
	
	assign opcode = inst_i[6:0];
	assign rd 	  = inst_i[11:7];
	assign func3  = inst_i[14:12];
	assign rs1 	  = inst_i[19:15];
	assign rs2 	  = inst_i[24:20];
	assign func7  = inst_i[31:25];
	assign imm    = inst_i[31:20];
	assign shamt  = inst_i[24:20];
	
	
	// branch
	//wire[31:0] jump_imm = {{19{inst_i[31]}},inst_i[31],inst_i[7],inst_i[30:25],inst_i[11:8],1'b0}; //改 21+6+4+1
	wire  	   op1_i_equal_op2_i;
	wire       op1_i_less_op2_i_signed;
	wire       op1_i_less_op2_i_unsigned;
	
	assign	   op1_i_less_op2_i_signed = ($signed(op1_i) < $signed(op2_i))?1'b1:1'b0;
	assign	   op1_i_less_op2_i_unsigned = (op1_i < op2_i)?1'b1:1'b0;
	assign	   op1_i_equal_op2_i = (op1_i == op2_i)?1'b1:1'b0;
	

	//ALU
	wire[31:0] op1_i_add_op2_i;										
	wire[31:0] op1_i_and_op2_i;
	wire[31:0] op1_i_xor_op2_i;
	wire[31:0] op1_i_or_op2_i;
	wire[31:0] op1_i_shift_letf_op2_i;
	wire[31:0] op1_i_shift_right_op2_i;
	wire[31:0] base_addr_add_addr_offset;
	
	assign op1_i_add_op2_i           = op1_i + op2_i;				// 加法器
	assign op1_i_and_op2_i           = op1_i & op2_i;			    // 与
	assign op1_i_xor_op2_i           = op1_i ^ op2_i;			    // 异或
	assign op1_i_or_op2_i 			 = op1_i | op2_i;			    // 或
	assign op1_i_shift_letf_op2_i 	 = op1_i << op2_i;			    // 左移
	assign op1_i_shift_right_op2_i 	 = op1_i >> op2_i;			    // 右移
	assign base_addr_add_addr_offset = base_addr_i + addr_offset_i; // 计算地址单元
	
	// tpye I
	wire[31:0] SRA_mask;
	assign 	   SRA_mask = (32'hffff_ffff) >> op2_i[4:0];
	
	
	
	
	always @(*)begin
		
		case(opcode)		
			`INST_TYPE_I:begin
				jump_addr_o = 32'b0;
				jump_en_o	= 1'b0;
				hold_flag_o = 1'b0;			
				case(func3)				
					`INST_ADDI:begin
						rd_data_o = op1_i_add_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end
					`INST_SLTI:begin
						rd_data_o = {31'b0,op1_i_less_op2_i_signed};
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end					
					`INST_SLTIU:begin
						rd_data_o = {31'b0,op1_i_less_op2_i_unsigned};
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end					
					`INST_XORI:begin
						rd_data_o = op1_i_xor_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end					
					`INST_ORI:begin
						rd_data_o = op1_i_or_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end					
					`INST_ANDI:begin
						rd_data_o = op1_i_add_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end	
					`INST_SLLI:begin
						rd_data_o = op1_i_shift_letf_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;					
					end
					`INST_SRI:begin
						if(func7[5] == 1'b1) begin //SRAI
							rd_data_o = ((op1_i_shift_right_op2_i) & SRA_mask) | ({32{op1_i[31]}} & (~SRA_mask));
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;							
						end
						else begin //SRLI
							rd_data_o = op1_i_shift_right_op2_i;
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;							
						end
					end					
					default:begin
						rd_data_o = 32'b0;
						rd_addr_o = 5'b0;
						rd_wen_o  = 1'b0;
					end						
				endcase
			end	
			
			`INST_TYPE_R_M:begin
				jump_addr_o = 32'b0;
				jump_en_o	= 1'b0;
				hold_flag_o = 1'b0;			
				case(func3)				
					`INST_ADD_SUB:begin
						if(func7[5] == 1'b0)begin//add
							rd_data_o = op1_i_add_op2_i;
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;
						end
						else begin
							rd_data_o = op1_i - op2_i;
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1; 								
						end
					end
					`INST_SLL:begin
						rd_data_o = op1_i_shift_letf_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end
					`INST_SLT:begin
						rd_data_o = {31'b0,op1_i_less_op2_i_signed};
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end
					`INST_SLTU:begin
						rd_data_o = {31'b0,op1_i_less_op2_i_unsigned};
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end
					`INST_XOR:begin
						rd_data_o = op1_i_xor_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end	
					`INST_OR:begin
						rd_data_o = op1_i_or_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end
					`INST_AND:begin
						rd_data_o = op1_i_and_op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end	
					`INST_SR:begin
						if(func7[5] == 1'b1) begin //SRA
							rd_data_o = ((op1_i_shift_right_op2_i) & SRA_mask) | ({32{op1_i[31]}} & (~SRA_mask));
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;							
						end
						else begin //SRL
							rd_data_o = op1_i_shift_right_op2_i;
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;							
						end	
					end						
					default:begin
						rd_data_o = 32'b0;
						rd_addr_o = 5'b0;
						rd_wen_o  = 1'b0;					
					end
				endcase
			end	
			
			`INST_TYPE_B:begin
				rd_data_o = 32'b0; 
				rd_addr_o = 5'b0;
				rd_wen_o  = 1'b0;			
				case(func3)
					`INST_BEQ:begin
						jump_addr_o = base_addr_add_addr_offset ; 
						jump_en_o	= op1_i_equal_op2_i;
						hold_flag_o = 1'b0;					
					end					
					`INST_BNE:begin
						jump_addr_o = base_addr_add_addr_offset;
						jump_en_o	= ~op1_i_equal_op2_i;
						hold_flag_o = 1'b0;					
					end	
					`INST_BLT:begin
						jump_addr_o = base_addr_add_addr_offset;
						jump_en_o	= op1_i_less_op2_i_signed;
						hold_flag_o = 1'b0;					
					end	
					`INST_BGE:begin
						jump_addr_o = base_addr_add_addr_offset;
						jump_en_o	= ~op1_i_less_op2_i_signed;
						hold_flag_o = 1'b0;					
					end
					`INST_BLTU:begin
						jump_addr_o = base_addr_add_addr_offset;
						jump_en_o	= op1_i_less_op2_i_unsigned;
						hold_flag_o = 1'b0;					
					end
					`INST_BGEU:begin
						jump_addr_o = base_addr_add_addr_offset;
						jump_en_o	= ~op1_i_less_op2_i_unsigned;
						hold_flag_o = 1'b0;					
					end					
					default:begin
						jump_addr_o = 32'b0;
						jump_en_o	= 1'b0;
						hold_flag_o = 1'b0;					
					end
				endcase
			end
			`INST_JAL:begin
				rd_data_o = op1_i_add_op2_i;
				rd_addr_o = rd_addr_i;
				rd_wen_o  = 1'b1;
				jump_addr_o = base_addr_add_addr_offset;
				jump_en_o	= 1'b1;
				hold_flag_o = 1'b0;				
			end
			`INST_JALR:begin
				rd_data_o = op1_i_add_op2_i;
				rd_addr_o = rd_addr_i;
				rd_wen_o  = 1'b1;
				jump_addr_o = base_addr_add_addr_offset;
				jump_en_o	= 1'b1;
				hold_flag_o = 1'b0;				
			end				
			`INST_LUI:begin
				rd_data_o = op1_i;
				rd_addr_o = rd_addr_i;
				rd_wen_o  = 1'b1;
				jump_addr_o = 32'b0;
				jump_en_o	= 1'b0;
				hold_flag_o = 1'b0;			
			end	
			`INST_AUIPC:begin
				rd_data_o = op1_i_add_op2_i;
				rd_addr_o = rd_addr_i;
				rd_wen_o  = 1'b1;
				jump_addr_o = 32'b0;
				jump_en_o	= 1'b0;
				hold_flag_o = 1'b0;				
			end
			default:begin
				rd_data_o = 32'b0;
				rd_addr_o = 5'b0;
				rd_wen_o  = 1'b0;
				jump_addr_o = 32'b0;
				jump_en_o	= 1'b0;
				hold_flag_o = 1'b0;				
			end
		endcase
	end

	
	
	
endmodule

 id


`include "defines.v"

module id(
	//from if_id
	input wire[31:0] inst_i			,
	input wire[31:0] inst_addr_i	,
		
	// to regs 
	output reg[4:0] rs1_addr_o		,
	output reg[4:0] rs2_addr_o		,
	// from regs
	input wire[31:0] rs1_data_i		,
	input wire[31:0] rs2_data_i		,
	
	//to id_ex
	output reg[31:0] inst_o			,
	output reg[31:0] inst_addr_o	,
	output reg[31:0] op1_o			,	
	output reg[31:0] op2_o			,
	output reg[4:0]  rd_addr_o		,	
	output reg 		 reg_wen		,
	output reg[31:0] base_addr_o	,
	output reg[31:0] addr_offset_o		
);

	wire[6:0] opcode; 
	wire[4:0] rd; 
	wire[2:0] func3; 
	wire[4:0] rs1;
	wire[4:0] rs2;
	wire[6:0] func7;
	wire[11:0]imm;
	wire[4:0] shamt;
	
	assign opcode = inst_i[6:0];
	assign rd 	  = inst_i[11:7];
	assign func3  = inst_i[14:12];
	assign rs1 	  = inst_i[19:15];
	assign rs2 	  = inst_i[24:20];
	assign func7  = inst_i[31:25];
	assign imm    = inst_i[31:20];
	assign shamt  = inst_i[24:20];
	

	
	
	
	always @(*)begin
		inst_o  	= inst_i;
		inst_addr_o = inst_addr_i;  
		
		case(opcode)
			`INST_TYPE_I:begin
				base_addr_o		= 32'b0;
				addr_offset_o	= 32'b0;		
				case(func3)
					`INST_ADDI,`INST_SLTI,`INST_SLTIU,`INST_XORI,`INST_ORI,`INST_ANDI:begin
						rs1_addr_o = rs1;
						rs2_addr_o = 5'b0;
						op1_o 	   = rs1_data_i;
						op2_o      = {{20{imm[11]}},imm};
						rd_addr_o  = rd;
						reg_wen    = 1'b1;
					end
					`INST_SLLI,`INST_SRI:begin
						rs1_addr_o = rs1;
						rs2_addr_o = 5'b0;
						op1_o 	   = rs1_data_i;
						op2_o      = {27'b0,shamt};
						rd_addr_o  = rd;
						reg_wen    = 1'b1;					
					end
					default:begin
						rs1_addr_o = 5'b0;
						rs2_addr_o = 5'b0;
						op1_o 	   = 32'b0;
						op2_o      = 32'b0;
						rd_addr_o  = 5'b0;
						reg_wen    = 1'b0;						
					end
				endcase	
			end
			`INST_TYPE_R_M:begin
				base_addr_o		= 32'b0;
				addr_offset_o	= 32'b0;			
				case(func3)
					`INST_ADD_SUB,`INST_SLT,`INST_SLTU,`INST_XOR,`INST_OR,`INST_AND:begin
						rs1_addr_o = rs1;
						rs2_addr_o = rs2;
						op1_o 	   = rs1_data_i;
						op2_o      = rs2_data_i;
						rd_addr_o  = rd;
						reg_wen    = 1'b1;
					end
					`INST_SLL,`INST_SR:begin
						rs1_addr_o = rs1;
						rs2_addr_o = rs2;
						op1_o 	   = rs1_data_i;
						op2_o      = {27'b0,rs2_data_i[4:0]};
						rd_addr_o  = rd;
						reg_wen    = 1'b1;					
					end
					default:begin
						rs1_addr_o = 5'b0;
						rs2_addr_o = 5'b0;
						op1_o 	   = 32'b0;
						op2_o      = 32'b0;
						rd_addr_o  = 5'b0;
						reg_wen    = 1'b0;						
					end
				endcase				
			end
			`INST_TYPE_B:begin
				case(func3)
					`INST_BNE,`INST_BEQ,`INST_BLT,`INST_BGE,`INST_BLTU,`INST_BGEU:begin
						rs1_addr_o = rs1;
						rs2_addr_o = rs2;
						op1_o 	   = rs1_data_i;
						op2_o      = rs2_data_i;
						rd_addr_o  = 5'b0;
						reg_wen    = 1'b0;
						base_addr_o		= inst_addr_i;
						addr_offset_o	= {{19{inst_i[31]}},inst_i[31],inst_i[7],inst_i[30:25],inst_i[11:8],1'b0};						
					end	
					default:begin
						rs1_addr_o = 5'b0;
						rs2_addr_o = 5'b0;
						op1_o 	   = 32'b0;
						op2_o      = 32'b0;
						rd_addr_o  = 5'b0;
						reg_wen    = 1'b0;
						base_addr_o		= 32'b0;
						addr_offset_o	= 32'b0;						
					end
				endcase
			end
			`INST_JAL:begin
				rs1_addr_o = 5'b0;
				rs2_addr_o = 5'b0;
				op1_o 	   = inst_addr_i;
				op2_o      = 32'h4;
				rd_addr_o  = rd;
				reg_wen    = 1'b1;
				base_addr_o		= inst_addr_i;
				addr_offset_o	= {{12{inst_i[31]}}, inst_i[19:12], inst_i[20], inst_i[30:21], 1'b0};				
			end
			`INST_LUI:begin
				rs1_addr_o = 5'b0;
				rs2_addr_o = 5'b0;
				op1_o 	   = {inst_i[31:12],12'b0};
				op2_o      = 32'b0;
				rd_addr_o  = rd;
				reg_wen    = 1'b1;
				base_addr_o		= 32'b0;
				addr_offset_o	= 32'b0;				
			end	
			`INST_JALR:begin
				rs1_addr_o = rs1;
				rs2_addr_o = 5'b0;
				op1_o 	   = inst_addr_i;
				op2_o      = 32'h4;
				rd_addr_o  = rd;
				reg_wen    = 1'b1;	
				base_addr_o		= rs1_data_i;
				addr_offset_o	= {{20{imm[11]}},imm};				
			end
			`INST_AUIPC:begin
				rs1_addr_o = 5'b0;
				rs2_addr_o = 5'b0;
				op1_o 	   = {inst_i[31:12],12'b0};
				op2_o      = inst_addr_i;
				rd_addr_o  = rd;
				reg_wen    = 1'b1;	
				base_addr_o		= 32'b0;
				addr_offset_o	= 32'b0;				
			end
			default:begin
				rs1_addr_o = 5'b0;
				rs2_addr_o = 5'b0;
				op1_o 	   = 32'b0;
				op2_o      = 32'b0;
				rd_addr_o  = 5'b0;
				reg_wen    = 1'b0;	
				base_addr_o		= 32'b0;
				addr_offset_o	= 32'b0;				
			end
		endcase
	end

	


endmodule

 id_ex

`include "defines.v"

module id_ex(
	input wire clk					,
	input wire rst					,
	//from ctrl
	input wire hold_flag_i			,
	//from id
	input wire[31:0] inst_i			,
	input wire[31:0] inst_addr_i	,
	input wire[31:0] op1_i			,	
	input wire[31:0] op2_i			,
	input wire[4:0]  rd_addr_i		,	
	input wire 		 reg_wen_i		,
	input wire[31:0] base_addr_i	,
	input wire[31:0] addr_offset_i	,	
	//to ex
	output wire[31:0] inst_o		,
	output wire[31:0] inst_addr_o	,
	output wire[31:0] op1_o			,	
	output wire[31:0] op2_o			,
	output wire[4:0]  rd_addr_o		,	
	output wire 	  reg_wen_o		,	
	output wire[31:0] base_addr_o	,
	output wire[31:0] addr_offset_o		
);

	dff_set #(32) dff1(clk,rst,hold_flag_i,`INST_NOP,inst_i,inst_o);
	
	dff_set #(32) dff2(clk,rst,hold_flag_i,32'b0,inst_addr_i,inst_addr_o);
	
	dff_set #(32) dff3(clk,rst,hold_flag_i,32'b0,op1_i,op1_o);
	
	dff_set #(32) dff4(clk,rst,hold_flag_i,32'b0,op2_i,op2_o);
	
	dff_set #(5) dff5(clk,rst,hold_flag_i,5'b0,rd_addr_i,rd_addr_o);
	
	dff_set #(1) dff6(clk,rst,hold_flag_i,1'b0,reg_wen_i,reg_wen_o);
	
	dff_set #(32) dff7(clk,rst,hold_flag_i,32'b0,base_addr_i,base_addr_o);
	
	dff_set #(32) dff8(clk,rst,hold_flag_i,32'b0,addr_offset_i,addr_offset_o);





endmodule

if_id

`include "defines.v"

module if_id(
	input wire clk,
	input wire rst,
	input wire hold_flag_i,
	input wire [31:0]  inst_i, 
	input wire [31:0]  inst_addr_i,
	output wire[31:0]  inst_addr_o, 
	output wire[31:0]  inst_o
);

	dff_set #(32) dff1(clk,rst,hold_flag_i,`INST_NOP,inst_i,inst_o);
	
	dff_set #(32) dff2(clk,rst,hold_flag_i,32'b0,inst_addr_i,inst_addr_o);



endmodule

if

module ifetch(
	//from pc
	input  wire[31:0] pc_addr_i,
	//from rom 
	input  wire[31:0] rom_inst_i,
	//to rom
	output wire[31:0] if2rom_addr_o, 
	// to if_id
	output wire[31:0] inst_addr_o, 
	output wire[31:0] inst_o
	);


	assign if2rom_addr_o = pc_addr_i;
	
	assign inst_addr_o  = pc_addr_i;
	
	assign inst_o = rom_inst_i;



endmodule

open_risc_v

module open_risc_v(
	input  wire 		  clk   		,
	input  wire 		  rst		    , 
	input  wire [31:0]    inst_i		,
	output wire [31:0]    inst_addr_o
);
	//pc to if
	wire[31:0] pc_reg_pc_o;
	
	//if to if_id
	wire[31:0] if_inst_addr_o;
	wire[31:0] if_inst_o;	
	
	// if_id to id
	wire[31:0] if_id_inst_addr_o;
	wire[31:0] if_id_inst_o;	
	
	//ex to regs
	wire[4:0]  ex_rd_addr_o;
	wire[31:0] ex_rd_data_o;
	wire       ex_reg_wen_o;

	//id to regs
	wire[4:0] id_rs1_addr_o;
	wire[4:0] id_rs2_addr_o;
	
	//id to id_ex
	wire[31:0] id_inst_o;
	wire[31:0] id_inst_addr_o;
	wire[31:0] id_op1_o;
	wire[31:0] id_op2_o;
	wire[4:0]  id_rd_addr_o;
	wire       id_reg_wen;
	wire[31:0] id_base_addr_o;	
	wire[31:0] id_addr_offset_o;	

	//regs to id
	wire[31:0] regs_reg1_rdata_o;
	wire[31:0] regs_reg2_rdata_o;
	
	
	//id_ex to ex
	wire[31:0] id_ex_inst_o;
	wire[31:0] id_ex_inst_addr_o;
	wire[31:0] id_ex_op1_o;
	wire[31:0] id_ex_op2_o;
	wire[4:0]  id_ex_rd_addr_o;
	wire       id_ex_reg_wen;
	wire[31:0] id_ex_base_addr_o;	
	wire[31:0] id_ex_addr_offset_o;
	
	//ex  to ctrl
	wire[31:0] ex_jump_addr_o;
	wire  	   ex_jump_en_o;
	wire 	   ex_hold_flag_o;
	//ctrl to pc_reg
	wire[31:0] ctrl_jump_addr_o;
	wire  	   ctrl_jump_en_o;
	//ctrl to if_id id_ex
	wire 	   ctrl_hold_flag_o;		
	
	
	pc_reg pc_reg_inst(
		.clk			(clk),
		.rst			(rst),
		.jump_addr_i	(ctrl_jump_addr_o), //&
		.jump_en		(ctrl_jump_en_o),		
		.pc_o   		(pc_reg_pc_o)
	);
	
	
	ifetch ifetch_inst(
		.pc_addr_i		(pc_reg_pc_o),
		.rom_inst_i		(inst_i),
		.if2rom_addr_o	(inst_addr_o), 
		.inst_addr_o	(if_inst_addr_o), 
		.inst_o         (if_inst_o)
	);


	if_id if_id_inst(
		.clk			(clk		      ),
		.rst			(rst		      ),
		.hold_flag_i	(ctrl_hold_flag_o ),
		.inst_i			(if_inst_o        ),  
		.inst_addr_i	(if_inst_addr_o   ),  
		.inst_addr_o	(if_id_inst_addr_o), 
		.inst_o         (if_id_inst_o	  )
	);
	

	
	id id_inst(
		.inst_i			(if_id_inst_o		),
		.inst_addr_i	(if_id_inst_addr_o	),
		.rs1_addr_o		(id_rs1_addr_o		),
		.rs2_addr_o		(id_rs2_addr_o		),
		.rs1_data_i		(regs_reg1_rdata_o	),
		.rs2_data_i		(regs_reg2_rdata_o	),
		.inst_o			(id_inst_o			),
		.inst_addr_o	(id_inst_addr_o		),	
		.op1_o			(id_op1_o			),	
		.op2_o			(id_op2_o			),
		.rd_addr_o		(id_rd_addr_o		),	
		.reg_wen        (id_reg_wen			),
		.base_addr_o	(id_base_addr_o		),
		.addr_offset_o	(id_addr_offset_o	)	
		);


	
	regs regs_inst(
		.clk			(clk					),
		.rst			(rst					),
		.reg1_raddr_i	(id_rs1_addr_o			),
		.reg2_raddr_i	(id_rs2_addr_o			), 
		.reg1_rdata_o	(regs_reg1_rdata_o		),
		.reg2_rdata_o	(regs_reg2_rdata_o		),
		.reg_waddr_i	(ex_rd_addr_o			),
		.reg_wdata_i	(ex_rd_data_o			),
		.reg_wen        (ex_reg_wen_o			)
	);
	

	id_ex id_ex_inst(
		.clk			(clk					),
		.rst			(rst					),
		.hold_flag_i	(ctrl_hold_flag_o 		),
		.inst_i			(id_inst_o				),
		.inst_addr_i	(id_inst_addr_o			),
		.op1_i			(id_op1_o				),
		.op2_i			(id_op2_o				),
		.rd_addr_i		(id_rd_addr_o			),
		.reg_wen_i		(id_reg_wen				),
		.base_addr_i	(id_base_addr_o			),
		.addr_offset_i	(id_addr_offset_o		),		
		.inst_o			(id_ex_inst_o			),
		.inst_addr_o    (id_ex_inst_addr_o		),
		.op1_o			(id_ex_op1_o			),
		.op2_o			(id_ex_op2_o			),
		.rd_addr_o		(id_ex_rd_addr_o		),
		.reg_wen_o		(id_ex_reg_wen			),
		.base_addr_o	(id_ex_base_addr_o		),
		.addr_offset_o	(id_ex_addr_offset_o	)		
		);
	


	ex ex_inst(
		.inst_i			(id_ex_inst_o			),	
		.inst_addr_i	(id_ex_inst_addr_o		),
		.op1_i			(id_ex_op1_o			),
		.op2_i			(id_ex_op2_o			),
		.rd_addr_i		(id_ex_rd_addr_o		),
		.rd_wen_i		(id_ex_reg_wen			),
		.base_addr_i	(id_ex_base_addr_o		),
		.addr_offset_i	(id_ex_addr_offset_o	),		
		.rd_addr_o		(ex_rd_addr_o			),
		.rd_data_o		(ex_rd_data_o			),	
		.rd_wen_o       (ex_reg_wen_o			),
		.jump_addr_o	(ex_jump_addr_o			),		
		.jump_en_o		(ex_jump_en_o			),		
		.hold_flag_o	(ex_hold_flag_o			)		
		
	);
	
	
	
	
	ctrl ctrl_inst(
		.jump_addr_i	(ex_jump_addr_o),
		.jump_en_i		(ex_jump_en_o),
		.hold_flag_ex_i	(ex_hold_flag_o),
		.jump_addr_o	(ctrl_jump_addr_o),
		.jump_en_o		(ctrl_jump_en_o),
		.hold_flag_o	(ctrl_hold_flag_o)	
	);

endmodule

pc_reg

module pc_reg(
	input wire 		 clk,
	input wire 		 rst,
	input wire[31:0] jump_addr_i,
	input wire 		 jump_en,
	output reg[31:0] pc_o
);

	always @(posedge clk) begin
		if(rst == 1'b0)
			pc_o <= 32'b0;
		else if(jump_en)
			pc_o <= jump_addr_i;
		else
			pc_o <= pc_o + 3'd4;
	end

endmodule

regs

module regs(
	input wire clk,
	input wire rst,
	//from id
	input wire[4:0] reg1_raddr_i,
	input wire[4:0] reg2_raddr_i,
	
	//to id
	output reg[31:0] reg1_rdata_o,
	output reg[31:0] reg2_rdata_o,
	
	//from ex
	input wire[4:0] reg_waddr_i,
	input wire[31:0]reg_wdata_i,
	input 			reg_wen

);
	reg[31:0] regs[0:31];
	integer i;

	always @(*)begin
		if(rst == 1'b0)
			reg1_rdata_o = 32'b0;
		else if(reg1_raddr_i == 5'b0)
			reg1_rdata_o = 32'b0;
		else if(reg_wen && reg1_raddr_i == reg_waddr_i)
			reg1_rdata_o = reg_wdata_i;
		else
			reg1_rdata_o = regs[reg1_raddr_i];
	end
	
	always @(*)begin
		if(rst == 1'b0)
			reg2_rdata_o = 32'b0;
		else if(reg2_raddr_i == 5'b0)
			reg2_rdata_o = 32'b0;
		else if(reg_wen && reg2_raddr_i == reg_waddr_i)
			reg2_rdata_o = reg_wdata_i;
		else
			reg2_rdata_o = regs[reg2_raddr_i];
	end

	always @(posedge clk)begin
		if(rst == 1'b0) begin
			for(i=0;i<31;i=i+1)begin
				regs[i] <= 32'b0;
			end
		end	
		else if(reg_wen && reg_waddr_i != 5'b0)begin
			regs[reg_waddr_i] <= reg_wdata_i;
		end	
	end

endmodule

rom

module rom(
	input wire[31:0] inst_addr_i,
	output reg[31:0] inst_o
);

	reg[31:0] rom_mem[0:4095];  //4096 个 32b的 空间 
	
	always @(*)begin
		inst_o = rom_mem[inst_addr_i>>2];
	end

endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值