RISC-V_Verilog/rtl/decoder.v

241 lines
8.8 KiB
Coq
Raw Normal View History

module decoder (input [31:0] instruction,
2023-10-21 13:57:58 +00:00
output reg [31:0] immediate,
2023-10-23 00:50:51 +00:00
output reg we_reg, adder_pc,
2023-10-21 13:57:58 +00:00
output reg [1:0] input_reg,
output reg [4:0] select_a, select_b, select_d,
output reg source_alu,
output reg [3:0] op_code_alu,
output reg mem_we,
output reg [1:0] jmp_pc,
output reg b_pc, alu_not);
2023-10-23 01:10:49 +00:00
`include "op_code.vh"
2023-10-21 13:57:58 +00:00
function [3:0] get_op_code_alu(input [2:0] op_code, input arithmetic);
begin
case (op_code)
3'b000 : get_op_code_alu = arithmetic ? 4'b0001 : 4'b0000;
2023-10-21 13:57:58 +00:00
3'b001 : get_op_code_alu = 4'b0010;
3'b010 : get_op_code_alu = 4'b0011;
3'b011 : get_op_code_alu = 4'b0011;
3'b100 : get_op_code_alu = 4'b0100;
3'b101 : get_op_code_alu = arithmetic ? 4'b0111 : 4'b0101;
2023-10-21 13:57:58 +00:00
3'b110 : get_op_code_alu = 4'b1000;
3'b111 : get_op_code_alu = 4'b1010;
3'b111 : get_op_code_alu = 4'b1011;
default : get_op_code_alu= 4'b0000;
endcase
end
endfunction
function [3:0] get_op_code_alu_imm(input [2:0] op_code, input arithmetic);
begin
case (op_code)
3'b000 : get_op_code_alu_imm = 4'b0000;
3'b001 : get_op_code_alu_imm = 4'b0010;
3'b010 : get_op_code_alu_imm = 4'b0011;
3'b011 : get_op_code_alu_imm = 4'b0100;
3'b100 : get_op_code_alu_imm = 4'b0101;
3'b101 : get_op_code_alu_imm = arithmetic ? 4'b1000 : 4'b0111;
2023-10-21 13:57:58 +00:00
3'b110 : get_op_code_alu_imm = 4'b1001;
3'b111 : get_op_code_alu_imm = 4'b1010;
3'b111 : get_op_code_alu_imm = 4'b1011;
default : get_op_code_alu_imm = 4'b0000;
endcase
end
endfunction
function [3:0] branch_op_code(input [2:0] op_code);
begin
case (op_code)
3'b000 : branch_op_code = 4'b0001;
3'b001 : branch_op_code = 4'b0001;
3'b010 : branch_op_code = 4'b0011;
3'b011 : branch_op_code = 4'b0011;
3'b100 : branch_op_code = 4'b0011;
3'b101 : branch_op_code = 4'b0011;
default : branch_op_code = 4'b0000;
endcase
end
endfunction
function branch_not(input [2:0] op_code);
begin
case (op_code)
3'b000 : branch_not = 1;
3'b001 : branch_not = 0;
3'b010 : branch_not = 0;
3'b011 : branch_not = 1;
3'b100 : branch_not = 0;
3'b101 : branch_not = 1;
default : branch_not = 0;
endcase
end
endfunction
// TODO - Manage ALU OP CODE and IMM Extension
always @(*) begin
2023-10-21 13:57:58 +00:00
case (instruction[6:2])
2023-10-23 01:10:49 +00:00
OP : begin // OP - Add, ...
2023-10-21 13:57:58 +00:00
immediate = 0;
we_reg = 1;
adder_pc = 0;
input_reg = 2'b01;
select_a = instruction[19:15];
select_b = instruction[24:20];
select_d = instruction[11:7];
source_alu = 0;
op_code_alu = get_op_code_alu(instruction[14:12], instruction[30]);
mem_we = 0;
jmp_pc = 2'b00;
b_pc = 0;
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
OP_IMM : begin // OP-IMM - Addi, ...
immediate[11:0] = instruction[31:20];
immediate[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
2023-10-21 13:57:58 +00:00
we_reg = 1;
adder_pc = 0;
input_reg = 2'b01;
select_a = instruction[19:15];
select_b = 5'b00000;
select_d = instruction[11:7];
source_alu = 1;
op_code_alu = get_op_code_alu_imm(instruction[14:12], instruction[30]);
mem_we = 0;
jmp_pc = 2'b00;
b_pc = 0;
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
LOAD : begin // LOAD - Lw, ...
immediate[11:0] = instruction[31:20];
immediate[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
2023-10-21 13:57:58 +00:00
we_reg = 1;
adder_pc = 0;
input_reg = 2'b10;
select_a = instruction[19:15];
select_b = 5'b00000;
select_d = instruction[11:7];
source_alu = 1;
op_code_alu = 3'b000;
mem_we = 0;
jmp_pc = 2'b00;
b_pc = 0;
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
STORE : begin // STORE - Sw, ...
immediate[11:0] = {instruction[31:25], instruction[11:7]};
immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
2023-10-21 13:57:58 +00:00
we_reg = 0;
adder_pc = 0;
input_reg = 2'b01;
select_a = instruction[19:15];
select_b = instruction[24:20];
select_d = 5'b00000;
source_alu = 1;
op_code_alu = 3'b000;
mem_we = 1;
jmp_pc = 2'b00;
b_pc = 0;
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
BRANCH : begin // BRANCH - Beq, ...
immediate[11:0] = {instruction[31:25], instruction[11:7]};
immediate[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
2023-10-21 13:57:58 +00:00
we_reg = 0;
adder_pc = 0;
input_reg = 2'b01;
select_a = instruction[19:15];
select_b = instruction[24:20];
select_d = 5'b00000;
source_alu = 0;
op_code_alu = branch_op_code(instruction[14:12]);
mem_we = 0;
jmp_pc = 2'b00;
b_pc = 1;
alu_not = branch_not(instruction[14:12]);
end
2023-10-23 01:10:49 +00:00
JAL : begin // JUMP - Jal
immediate[19:0] = instruction[31:12];
immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111;
2023-10-21 13:57:58 +00:00
we_reg = 1;
adder_pc = 0;
input_reg = 2'b00;
select_a = 5'b00000;
select_b = 5'b00000;
select_d = instruction[11:7];
source_alu = 0;
op_code_alu = 3'b000;
mem_we = 0;
jmp_pc = 2'b01;
b_pc = 0;
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
JALR : begin // JUMP REG - Jalr
immediate[11:0] = instruction[31:20];
immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
2023-10-21 13:57:58 +00:00
we_reg = 1;
adder_pc = 0;
input_reg = 2'b00;
select_a = instruction[19:15];
select_b = 5'b00000;
select_d = instruction[11:7];
source_alu = 0;
op_code_alu = 3'b000;
mem_we = 0;
jmp_pc = 2'b10;
b_pc = 0;
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
LUI : begin // LUI - lui
immediate = {instruction[31:12] << 12, 12'b000000000000};
2023-10-21 13:57:58 +00:00
we_reg = 1;
adder_pc = 0;
input_reg = 2'b01;
select_a = 5'b00000;
select_b = 5'b00000;
select_d = instruction[11:7];
source_alu = 1;
op_code_alu = 3'b000;
mem_we = 0;
jmp_pc = 2'b00;
b_pc = 0;
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
AUIPC : begin // AUIPC - auipc
immediate = {instruction[31:12] << 12, 12'b000000000000};
2023-10-21 13:57:58 +00:00
we_reg = 1;
adder_pc = 1;
input_reg = 2'b00;
select_a = 5'b00000;
select_b = 5'b00000;
select_d = instruction[11:7];
2023-10-23 00:50:51 +00:00
source_alu = 1;
2023-10-21 13:57:58 +00:00
op_code_alu = 3'b000;
mem_we = 0;
jmp_pc = 2'b00;
b_pc = 0;
alu_not = 0;
end
default : begin // NOP
immediate = 32'b0;
we_reg = 0;
adder_pc = 0;
input_reg = 2'b00;
select_a = 5'b00000;
select_b = 5'b00000;
select_d = 5'b00000;
source_alu = 0;
op_code_alu = 3'b000;
mem_we = 0;
jmp_pc = 2'b00;
b_pc = 0;
alu_not = 0;
end
endcase
end
endmodule