📄 instruction_decode.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 + -