RISC-V_Verilog/rtl/decoder.v

252 lines
9.3 KiB
Coq
Raw Permalink Normal View History

module decoder (input [31:0] instruction,
2023-10-23 02:24:09 +00:00
output reg [31:0] imm,
2023-10-23 02:37:10 +00:00
output reg reg_we,
2023-10-23 02:24:09 +00:00
output reg [1:0] reg_sel_data_in,
output reg [4:0] reg_sel_out_a, reg_sel_out_b, reg_sel_in,
output reg alu_src,
output reg [3:0] alu_func,
2023-10-21 13:57:58 +00:00
output reg mem_we,
output reg [1:0] mem_func_in,
output reg [2:0] mem_func_out,
2023-10-23 02:47:43 +00:00
output reg [1:0] pc_is_branch,
output reg pc_is_jmp, alu_not);
2023-10-21 13:57:58 +00:00
2023-10-23 01:10:49 +00:00
`include "op_code.vh"
`include "alu_func.vh"
`include "mem_func.vh"
2023-10-23 01:10:49 +00:00
2023-10-24 10:39:42 +00:00
function [3:0] get_alu_func(input [2:0] func, input arithmetic);
2023-10-21 13:57:58 +00:00
begin
2023-10-24 10:39:42 +00:00
case (func)
3'b000 : get_alu_func = arithmetic ? SUB : ADD;
3'b001 : get_alu_func = SLL;
3'b010 : get_alu_func = SLT;
3'b011 : get_alu_func = SLTU;
3'b100 : get_alu_func = XOR;
3'b101 : get_alu_func = arithmetic ? SRA : SRL;
3'b110 : get_alu_func = OR;
3'b111 : get_alu_func = AND;
2023-10-23 02:24:09 +00:00
default : get_alu_func= 4'b0000;
2023-10-21 13:57:58 +00:00
endcase
end
endfunction
2023-10-24 10:39:42 +00:00
function [3:0] get_alu_func_imm(input [2:0] func, input arithmetic);
2023-10-21 13:57:58 +00:00
begin
2023-10-24 10:39:42 +00:00
case (func)
3'b000 : get_alu_func_imm = ADD;
3'b001 : get_alu_func_imm = SLL;
3'b010 : get_alu_func_imm = SLT;
3'b011 : get_alu_func_imm = SLTU;
3'b100 : get_alu_func_imm = XOR;
3'b101 : get_alu_func_imm = arithmetic ? SRA : SRL;
3'b110 : get_alu_func_imm = OR;
3'b111 : get_alu_func_imm = AND;
2023-10-23 02:24:09 +00:00
default : get_alu_func_imm = 4'b0000;
2023-10-21 13:57:58 +00:00
endcase
end
endfunction
2023-10-24 10:39:42 +00:00
function [3:0] branch_func(input [2:0] func);
2023-10-21 13:57:58 +00:00
begin
2023-10-24 10:39:42 +00:00
case (func)
2023-10-26 08:43:00 +00:00
3'b000 : branch_func = SUB;
3'b001 : branch_func = SUB;
3'b100 : branch_func = SLT;
3'b101 : branch_func = SLT;
3'b110 : branch_func = SLTU;
3'b111 : branch_func = SLTU;
2023-10-24 10:39:42 +00:00
default : branch_func = 4'b0000;
2023-10-21 13:57:58 +00:00
endcase
end
endfunction
2023-10-24 10:39:42 +00:00
function branch_not(input [2:0] func);
2023-10-21 13:57:58 +00:00
begin
2023-10-24 10:39:42 +00:00
case (func)
2023-10-21 13:57:58 +00:00
3'b000 : branch_not = 1;
3'b001 : branch_not = 0;
3'b100 : branch_not = 0;
3'b101 : branch_not = 1;
2023-10-26 08:43:00 +00:00
3'b110 : branch_not = 0;
3'b111 : branch_not = 1;
2023-10-21 13:57:58 +00:00
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-23 02:24:09 +00:00
imm = 0;
reg_we = 1;
reg_sel_data_in = 2'b00;
reg_sel_out_a = instruction[19:15];
reg_sel_out_b = instruction[24:20];
reg_sel_in = instruction[11:7];
alu_src = 0;
alu_func = get_alu_func(instruction[14:12], instruction[30]);
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b00;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
OP_IMM : begin // OP-IMM - Addi, ...
2023-10-23 02:24:09 +00:00
imm[11:0] = instruction[31:20];
imm[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 20'b00000000000000000000 : 20'b11111111111111111111;
2023-10-23 02:24:09 +00:00
reg_we = 1;
reg_sel_data_in = 2'b00;
reg_sel_out_a = instruction[19:15];
reg_sel_out_b = 5'b00000;
reg_sel_in = instruction[11:7];
alu_src = 1;
alu_func = get_alu_func_imm(instruction[14:12], instruction[30]);
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b00;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
LOAD : begin // LOAD - Lw, ...
2023-10-23 02:24:09 +00:00
imm[11:0] = instruction[31:20];
imm[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 20'b00000000000000000000 : 20'b11111111111111111111;
2023-10-23 02:24:09 +00:00
reg_we = 1;
reg_sel_data_in = 2'b01;
reg_sel_out_a = instruction[19:15];
reg_sel_out_b = 5'b00000;
reg_sel_in = instruction[11:7];
alu_src = 1;
alu_func = 3'b000;
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = instruction[14:12];
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b00;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
STORE : begin // STORE - Sw, ...
2023-10-23 02:24:09 +00:00
imm[11:0] = {instruction[31:25], instruction[11:7]};
imm[31:12] = (instruction[31] == 0) ? 20'b00000000000000000000 : 20'b11111111111111111111;
2023-10-23 02:24:09 +00:00
reg_we = 0;
reg_sel_data_in = 2'b00;
reg_sel_out_a = instruction[19:15];
reg_sel_out_b = instruction[24:20];
reg_sel_in = 5'b00000;
alu_src = 1;
alu_func = 3'b000;
2023-10-21 13:57:58 +00:00
mem_we = 1;
mem_func_in = instruction[13:12];
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b00;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
BRANCH : begin // BRANCH - Beq, ...
2023-11-20 13:21:41 +00:00
imm[11:0] = {instruction[7], instruction[30:25], instruction[11:8], 1'b0};
imm[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 20'b00000000000000000000 : 20'b11111111111111111111;
2023-10-23 02:24:09 +00:00
reg_we = 0;
reg_sel_data_in = 2'b00;
reg_sel_out_a = instruction[19:15];
reg_sel_out_b = instruction[24:20];
reg_sel_in = 5'b00000;
alu_src = 0;
2023-10-24 10:39:42 +00:00
alu_func = branch_func(instruction[14:12]);
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b00;
pc_is_jmp = 1;
2023-10-21 13:57:58 +00:00
alu_not = branch_not(instruction[14:12]);
end
2023-10-23 01:10:49 +00:00
JAL : begin // JUMP - Jal
2023-11-20 13:21:41 +00:00
imm[19:0] = {instruction[31], instruction[19:12], instruction[20], instruction[30:25], instruction[24:21], 1'b0};
2023-10-23 02:24:09 +00:00
imm[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111;
reg_we = 1;
reg_sel_data_in = 2'b10;
reg_sel_out_a = 5'b00000;
reg_sel_out_b = 5'b00000;
reg_sel_in = instruction[11:7];
alu_src = 0;
alu_func = 3'b000;
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b01;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
JALR : begin // JUMP REG - Jalr
2023-10-23 02:24:09 +00:00
imm[11:0] = instruction[31:20];
imm[31:12] = (instruction[31] == 0) ? 20'b00000000000000000000 : 20'b11111111111111111111;
2023-10-23 02:24:09 +00:00
reg_we = 1;
reg_sel_data_in = 2'b10;
reg_sel_out_a = instruction[19:15];
reg_sel_out_b = 5'b00000;
reg_sel_in = instruction[11:7];
alu_src = 0;
alu_func = 3'b000;
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b10;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
LUI : begin // LUI - lui
2023-10-23 02:24:09 +00:00
imm = {instruction[31:12] << 12, 12'b000000000000};
reg_we = 1;
reg_sel_data_in = 2'b00;
reg_sel_out_a = 5'b00000;
reg_sel_out_b = 5'b00000;
reg_sel_in = instruction[11:7];
alu_src = 1;
alu_func = 3'b000;
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b00;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
2023-10-23 01:10:49 +00:00
AUIPC : begin // AUIPC - auipc
2023-10-23 02:24:09 +00:00
imm = {instruction[31:12] << 12, 12'b000000000000};
reg_we = 1;
reg_sel_data_in = 2'b11;
reg_sel_out_a = 5'b00000;
reg_sel_out_b = 5'b00000;
reg_sel_in = instruction[11:7];
alu_src = 1;
alu_func = 3'b000;
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b00;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
default : begin // NOP
2023-10-23 02:24:09 +00:00
imm = 32'b0;
reg_we = 0;
reg_sel_data_in = 2'b00;
reg_sel_out_a = 5'b00000;
reg_sel_out_b = 5'b00000;
reg_sel_in = 5'b00000;
alu_src = 0;
alu_func = 3'b000;
2023-10-21 13:57:58 +00:00
mem_we = 0;
mem_func_in = 2'b00;
mem_func_out = 3'b000;
2023-10-23 02:47:43 +00:00
pc_is_branch = 2'b00;
pc_is_jmp = 0;
2023-10-21 13:57:58 +00:00
alu_not = 0;
end
endcase
end
endmodule