⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 instruction_decode.v

📁 流水线CPU的Verilog代码.rar
💻 V
字号:
`timescale 1ns/10ps

module instruction_decode(clk, reset, instruction, execution_destination, memory_destination, write_back_destination, write_back_bus, branch_bus, instruction_decode_bus);
	input clk;
	input reset;
	input[31:0] instruction;
	input[4:0] execution_destination, memory_destination, write_back_destination;
	input[37:0] write_back_bus;
	output[33:0] branch_bus;
	output[107:0] instruction_decode_bus;
	
	reg[31:0] ir;
	wire write_back_bus_valid;
	wire[4:0] write_back_bus_destination;
	wire[31:0] write_back_bus_value;
	
	wire[31:0] rg_rs1;
	wire[31:0] rg_rs2;
	reg branch_bus_valid;
	reg branch_bus_taken;
	reg [31:0]  branch_bus_offset;  //in fact the offset will be at most 28 bits
	reg instruction_decode_bus_valid;
	reg[5:0] instruction_decode_bus_operation;
	reg[4:0] instruction_decode_bus_destination;
	reg[31:0] instruction_decode_bus_valueA;
	reg[31:0] instruction_decode_bus_valueB;
	reg[31:0] instruction_decode_bus_store_value;
	
	assign write_back_bus_valid = write_back_bus[37];   //index needed
	assign write_back_bus_destination = write_back_bus[36:34]; //index needed
	assign write_back_bus_value = write_back_bus[31:0];
	
	wire stall = ((instruction[5:0] == 6'b100000 || instruction[5:0] == 6'b100010 || instruction[5:0] == 6'b100100 || instruction[5:0] == 6'b100101 || 
		instruction[5:0] == 6'b101010 || instruction[31:26] == 6'b101011 || instruction[31:26] == 6'b000100 || instruction[31:26] == 6'b000101) //add sub and or slt sw bne beq
									  && (instruction[20:16] == execution_destination && execution_destination != 0 ||
										  instruction[20:16] == memory_destination && memory_destination != 0 ||
										  instruction[20:16] == write_back_destination && write_back_destination != 0 ||
										  instruction[25:21] == execution_destination && execution_destination != 0 ||
										  instruction[25:21] == memory_destination && memory_destination != 0 ||
										  instruction[25:21] == write_back_destination && write_back_destination != 0) ||  
	   (instruction[31:26] == 6'b100011) && (instruction[25:21] == execution_destination && execution_destination != 0 ||      //lw
										  instruction[25:21] == memory_destination && memory_destination != 0 ||
										  instruction[25:21] == write_back_destination && write_back_destination != 0) ||
	   (instruction[31:26] == 6'b001000 || instruction[31:26] == 6'b001100 || instruction[31:26] == 6'b001101)                      //addi andi ori
	   								  && (instruction[25:21] == execution_destination && execution_destination != 0 ||      
										  instruction[25:21] == memory_destination && memory_destination != 0 ||
										  instruction[25:21] == write_back_destination && write_back_destination != 0) ||
	   (instruction[31:26] == 6'b000010)) ? 1'b0 : 1'b1;  //JUMP
	   
	wire write_back_enable = write_back_bus_valid ? 1'b1 : 1'b0;
	wire [4:0] write_back_addr = write_back_bus_destination;
	wire [31:0] write_back_value = write_back_bus_value;
	
	register_file registers(.clk(clk), .addr1(instruction[25:21]), .out1(rg_rs1), .addr2(instruction[20:16]), .out2(rg_rs2), .write_enable(write_back_enable), .write_addr(write_back_addr), .write_value(write_back_value));

	always @(posedge clk)
	begin
		if(reset)
			begin
				instruction_decode_bus_valid <= 0;
				instruction_decode_bus_destination <= 5'b00000;
				branch_bus_valid <= 0;				
			end
		else
			begin
				ir = instruction;
				if(stall)   //stall the pipeline
					begin
						instruction_decode_bus_valid <= 0;
						instruction_decode_bus_operation <= 6'b000000;
						instruction_decode_bus_destination <= 5'b00000;
					end
				else      //issue the instruction
					begin
						branch_bus_valid <= 0;
						
						instruction_decode_bus_operation <= (ir[31:26] == 6'b000000) ? ir[5:0] : ir[31:26];
						
						if(ir[5:0] == 6'b000000) 
							 instruction_decode_bus_valid <= 0;
						else if(ir[5:0] == 6'b100000 || ir[5:0] == 6'b100010 || ir[5:0] == 6'b100100 || ir[5:0] == 6'b100101 || ir[5:0] == 6'b101010) //add sub and or slt
							 instruction_decode_bus_destination <= ir[15:11];
						else if(ir[31:26] == 6'b100011 || ir[31:26] == 6'b001000 || ir[31:26] == 6'b001100 || ir[31:26] == 6'b001101 )  //lw addi andi ori
							 instruction_decode_bus_destination <= ir[20:16];
						
						
						
						if(instruction[5:0] == 6'b100000 || instruction[5:0] == 6'b100010 || instruction[5:0] == 6'b100100 || instruction[5:0] == 6'b100101 || instruction[5:0] == 6'b101010) //add sub and or slt
							begin
								instruction_decode_bus_valueA <= rg_rs1;
								instruction_decode_bus_valueB <= rg_rs2;
								instruction_decode_bus_store_value <= 0;
								instruction_decode_bus_valid <= 1;
							end
						else if(instruction[31:26] == 6'b100011 || instruction[31:26] == 6'b001000 || instruction[31:26] == 6'b001100 || instruction[31:26] == 6'b001101 )  //lw addi andi ori
							begin
								instruction_decode_bus_valueA <= rg_rs1;
								instruction_decode_bus_valueB <= ir[15] ? (32'hffff0000 + ir[15:0]) : (32'h00000000 + ir[15:0]); //ir[15:0]: offset or immediate, signed integer, sign extending
								instruction_decode_bus_valid <= 1;
							end
						else if(instruction[31:26] == 6'b101011) //sw
							begin
								instruction_decode_bus_valueA <= rg_rs1;
								instruction_decode_bus_valueB <= ir[15] ? (32'hffff0000 + ir[15:0]) : (32'h00000000 + ir[15:0]); //ir[15:0]: offset, signed integer, sign extending
								instruction_decode_bus_store_value <= rg_rs2;
								instruction_decode_bus_valid <= 1'b1;
							end
						else if(instruction[31:26] == 6'b000100) //bne
							begin
								branch_bus_valid <= (rg_rs1 != rg_rs2) ? 1'b1 : 1'b0;
								branch_bus_taken <= branch_bus_valid;
								branch_bus_offset <= branch_bus_taken ? (ir[15:0] * 4) : 1'b0;
								instruction_decode_bus_valid <= 1'b0;
							end
						else if(instruction[31:26] == 6'b000101)  //beq
							begin
								branch_bus_valid <= (rg_rs1 == rg_rs2) ? 1'b1 : 1'b0;
								branch_bus_taken <= branch_bus_valid;
								branch_bus_offset <= branch_bus_taken ? (ir[15:0] * 4) : 1'b0;
								instruction_decode_bus_valid <= 1'b0;
							end
						else if(instruction[31:26] == 6'b000010)  //j
							begin
								branch_bus_valid <= 1'b1;
								branch_bus_taken <= 1'b1;
								branch_bus_offset <= ir[25:0] * 4;
								instruction_decode_bus_valid <= 1'b0;
							end						
						
						
						
						
						
					end
			end			
	end
	
//	always @(negedge clk)
//		begin
//			if(!stall)
//				begin
//					branch_bus_valid = 0;
//					if(instruction[5:0] == 000000)
//						instruction_decode_bus_valid = 0;
//					else if(instruction[5:0] == 100000 || instruction[5:0] == 100010 || instruction[5:0] == 100100 || instruction[5:0] == 100101 || instruction[5:0] == 101010) //add sub and or slt
//						begin
//							instruction_decode_bus_valueA = rg_rs1;
//							instruction_decode_bus_valueB = rg_rs2;
//							instruction_decode_bus_store_value = 0;
//							instruction_decode_bus_valid = 1;
//						end
//					else if(instruction[31:26] == 100011 || instruction[31:26] == 001000 || instruction[31:26] == 001100 || instruction[31:26] == 001101 )  //lw addi andi ori
//						begin
//							instruction_decode_bus_valueA = rg_rs1;
//							instruction_decode_bus_valueB = ir[15] ? (32'hffff0000 + ir[15:0]) : (32'h00000000 + ir[15:0]); //ir[15:0]: offset or immediate, signed integer, sign extending
//							instruction_decode_bus_valid = 1;
//						end
//					else if(instruction[31:26] == 101011) //sw
//						begin
//							instruction_decode_bus_valueA = rg_rs1;
//							instruction_decode_bus_valueB = ir[15] ? (32'hffff0000 + ir[15:0]) : (32'h00000000 + ir[15:0]); //ir[15:0]: offset, signed integer, sign extending
//							instruction_decode_bus_store_value = rg_rs2;
//							instruction_decode_bus_valid = 1;
//						end
//					else if(instruction[31:26] == 000100) //bne
//						begin
//							branch_bus_valid = (rg_rs1 != rg_rs2) ? 1 : 0;
//							branch_bus_taken = branch_bus_valid;
//							branch_bus_offset = branch_bus_taken ? (ir[15:0] * 4) : 0;
//							instruction_decode_bus_valid = 0;
//						end
//					else if(instruction[31:26] == 000101)  //beq
//						begin
//							branch_bus_valid = (rg_rs1 == rg_rs2) ? 1 : 0;
//							branch_bus_taken = branch_bus_valid;
//							branch_bus_offset = branch_bus_taken ? (ir[15:0] * 4) : 0;
//							instruction_decode_bus_valid = 0;
//						end
//					else if(instruction[31:26] == 000010)  //j
//						begin
//							branch_bus_valid = 1;
//							branch_bus_taken = 1;
//							branch_bus_offset = ir[25:0] * 4;
//							instruction_decode_bus_valid = 0;
//						end
//				end			
//		end
	
	assign branch_bus[33] = branch_bus_valid;
	assign branch_bus[32] = branch_bus_taken;
	assign branch_bus[31:0] = branch_bus_offset;
	
	assign instruction_decode_bus[107] = instruction_decode_bus_valid;
	assign instruction_decode_bus[106:101] = instruction_decode_bus_operation;
	assign instruction_decode_bus[100:96] = instruction_decode_bus_destination;
	assign instruction_decode_bus[95:64] = instruction_decode_bus_valueA;
	assign instruction_decode_bus[63:32] = instruction_decode_bus_valueB;
	assign instruction_decode_bus[31:0] = instruction_decode_bus_store_value;
	


endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -