RISC-V base implementation #1

Merged
BriceBoisson merged 17 commits from risc-v into main 2023-10-24 12:20:46 +00:00
4 changed files with 169 additions and 173 deletions
Showing only changes of commit 44ac59210c - Show all commits

View File

@ -1,46 +1,46 @@
module decoder (input [31:0] instruction, module decoder (input [31:0] instruction,
output reg [31:0] immediate, output reg [31:0] imm,
output reg we_reg, adder_pc, output reg reg_we, adder_pc,
output reg [1:0] input_reg, output reg [1:0] reg_sel_data_in,
output reg [4:0] select_a, select_b, select_d, output reg [4:0] reg_sel_out_a, reg_sel_out_b, reg_sel_in,
output reg source_alu, output reg alu_src,
output reg [3:0] op_code_alu, output reg [3:0] alu_func,
output reg mem_we, output reg mem_we,
output reg [1:0] jmp_pc, output reg [1:0] jmp_pc,
output reg b_pc, alu_not); output reg b_pc, alu_not);
`include "op_code.vh" `include "op_code.vh"
function [3:0] get_op_code_alu(input [2:0] op_code, input arithmetic); function [3:0] get_alu_func(input [2:0] op_code, input arithmetic);
begin begin
case (op_code) case (op_code)
3'b000 : get_op_code_alu = arithmetic ? 4'b0001 : 4'b0000; 3'b000 : get_alu_func = arithmetic ? 4'b0001 : 4'b0000;
3'b001 : get_op_code_alu = 4'b0010; 3'b001 : get_alu_func = 4'b0010;
3'b010 : get_op_code_alu = 4'b0011; 3'b010 : get_alu_func = 4'b0011;
3'b011 : get_op_code_alu = 4'b0011; 3'b011 : get_alu_func = 4'b0011;
3'b100 : get_op_code_alu = 4'b0100; 3'b100 : get_alu_func = 4'b0100;
3'b101 : get_op_code_alu = arithmetic ? 4'b0111 : 4'b0101; 3'b101 : get_alu_func = arithmetic ? 4'b0111 : 4'b0101;
3'b110 : get_op_code_alu = 4'b1000; 3'b110 : get_alu_func = 4'b1000;
3'b111 : get_op_code_alu = 4'b1010; 3'b111 : get_alu_func = 4'b1010;
3'b111 : get_op_code_alu = 4'b1011; 3'b111 : get_alu_func = 4'b1011;
default : get_op_code_alu= 4'b0000; default : get_alu_func= 4'b0000;
endcase endcase
end end
endfunction endfunction
function [3:0] get_op_code_alu_imm(input [2:0] op_code, input arithmetic); function [3:0] get_alu_func_imm(input [2:0] op_code, input arithmetic);
begin begin
case (op_code) case (op_code)
3'b000 : get_op_code_alu_imm = 4'b0000; 3'b000 : get_alu_func_imm = 4'b0000;
3'b001 : get_op_code_alu_imm = 4'b0010; 3'b001 : get_alu_func_imm = 4'b0010;
3'b010 : get_op_code_alu_imm = 4'b0011; 3'b010 : get_alu_func_imm = 4'b0011;
3'b011 : get_op_code_alu_imm = 4'b0100; 3'b011 : get_alu_func_imm = 4'b0100;
3'b100 : get_op_code_alu_imm = 4'b0101; 3'b100 : get_alu_func_imm = 4'b0101;
3'b101 : get_op_code_alu_imm = arithmetic ? 4'b1000 : 4'b0111; 3'b101 : get_alu_func_imm = arithmetic ? 4'b1000 : 4'b0111;
3'b110 : get_op_code_alu_imm = 4'b1001; 3'b110 : get_alu_func_imm = 4'b1001;
3'b111 : get_op_code_alu_imm = 4'b1010; 3'b111 : get_alu_func_imm = 4'b1010;
3'b111 : get_op_code_alu_imm = 4'b1011; 3'b111 : get_alu_func_imm = 4'b1011;
default : get_op_code_alu_imm = 4'b0000; default : get_alu_func_imm = 4'b0000;
endcase endcase
end end
endfunction endfunction
@ -79,156 +79,156 @@ endfunction
always @(*) begin always @(*) begin
case (instruction[6:2]) case (instruction[6:2])
OP : begin // OP - Add, ... OP : begin // OP - Add, ...
immediate = 0; imm = 0;
we_reg = 1; reg_we = 1;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b01; reg_sel_data_in = 2'b00;
select_a = instruction[19:15]; reg_sel_out_a = instruction[19:15];
select_b = instruction[24:20]; reg_sel_out_b = instruction[24:20];
select_d = instruction[11:7]; reg_sel_in = instruction[11:7];
source_alu = 0; alu_src = 0;
op_code_alu = get_op_code_alu(instruction[14:12], instruction[30]); alu_func = get_alu_func(instruction[14:12], instruction[30]);
mem_we = 0; mem_we = 0;
jmp_pc = 2'b00; jmp_pc = 2'b00;
b_pc = 0; b_pc = 0;
alu_not = 0; alu_not = 0;
end end
OP_IMM : begin // OP-IMM - Addi, ... OP_IMM : begin // OP-IMM - Addi, ...
immediate[11:0] = instruction[31:20]; imm[11:0] = instruction[31:20];
immediate[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; imm[31:12] = (instruction[14:12] == 3'b011 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
we_reg = 1; reg_we = 1;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b01; reg_sel_data_in = 2'b00;
select_a = instruction[19:15]; reg_sel_out_a = instruction[19:15];
select_b = 5'b00000; reg_sel_out_b = 5'b00000;
select_d = instruction[11:7]; reg_sel_in = instruction[11:7];
source_alu = 1; alu_src = 1;
op_code_alu = get_op_code_alu_imm(instruction[14:12], instruction[30]); alu_func = get_alu_func_imm(instruction[14:12], instruction[30]);
mem_we = 0; mem_we = 0;
jmp_pc = 2'b00; jmp_pc = 2'b00;
b_pc = 0; b_pc = 0;
alu_not = 0; alu_not = 0;
end end
LOAD : begin // LOAD - Lw, ... LOAD : begin // LOAD - Lw, ...
immediate[11:0] = instruction[31:20]; imm[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; imm[31:12] = (instruction[14:12] == 3'b100 || instruction[14:12] == 3'b101 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
we_reg = 1; reg_we = 1;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b10; reg_sel_data_in = 2'b01;
select_a = instruction[19:15]; reg_sel_out_a = instruction[19:15];
select_b = 5'b00000; reg_sel_out_b = 5'b00000;
select_d = instruction[11:7]; reg_sel_in = instruction[11:7];
source_alu = 1; alu_src = 1;
op_code_alu = 3'b000; alu_func = 3'b000;
mem_we = 0; mem_we = 0;
jmp_pc = 2'b00; jmp_pc = 2'b00;
b_pc = 0; b_pc = 0;
alu_not = 0; alu_not = 0;
end end
STORE : begin // STORE - Sw, ... STORE : begin // STORE - Sw, ...
immediate[11:0] = {instruction[31:25], instruction[11:7]}; imm[11:0] = {instruction[31:25], instruction[11:7]};
immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; imm[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
we_reg = 0; reg_we = 0;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b01; reg_sel_data_in = 2'b00;
select_a = instruction[19:15]; reg_sel_out_a = instruction[19:15];
select_b = instruction[24:20]; reg_sel_out_b = instruction[24:20];
select_d = 5'b00000; reg_sel_in = 5'b00000;
source_alu = 1; alu_src = 1;
op_code_alu = 3'b000; alu_func = 3'b000;
mem_we = 1; mem_we = 1;
jmp_pc = 2'b00; jmp_pc = 2'b00;
b_pc = 0; b_pc = 0;
alu_not = 0; alu_not = 0;
end end
BRANCH : begin // BRANCH - Beq, ... BRANCH : begin // BRANCH - Beq, ...
immediate[11:0] = {instruction[31:25], instruction[11:7]}; imm[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; imm[31:12] = (instruction[14:12] == 3'b110 || instruction[14:12] == 3'b111 || instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
we_reg = 0; reg_we = 0;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b01; reg_sel_data_in = 2'b00;
select_a = instruction[19:15]; reg_sel_out_a = instruction[19:15];
select_b = instruction[24:20]; reg_sel_out_b = instruction[24:20];
select_d = 5'b00000; reg_sel_in = 5'b00000;
source_alu = 0; alu_src = 0;
op_code_alu = branch_op_code(instruction[14:12]); alu_func = branch_op_code(instruction[14:12]);
mem_we = 0; mem_we = 0;
jmp_pc = 2'b00; jmp_pc = 2'b00;
b_pc = 1; b_pc = 1;
alu_not = branch_not(instruction[14:12]); alu_not = branch_not(instruction[14:12]);
end end
JAL : begin // JUMP - Jal JAL : begin // JUMP - Jal
immediate[19:0] = instruction[31:12]; imm[19:0] = instruction[31:12];
immediate[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111; imm[31:20] = (instruction[31] == 0) ? 12'b000000000000 : 12'b111111111111;
we_reg = 1; reg_we = 1;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b00; reg_sel_data_in = 2'b10;
select_a = 5'b00000; reg_sel_out_a = 5'b00000;
select_b = 5'b00000; reg_sel_out_b = 5'b00000;
select_d = instruction[11:7]; reg_sel_in = instruction[11:7];
source_alu = 0; alu_src = 0;
op_code_alu = 3'b000; alu_func = 3'b000;
mem_we = 0; mem_we = 0;
jmp_pc = 2'b01; jmp_pc = 2'b01;
b_pc = 0; b_pc = 0;
alu_not = 0; alu_not = 0;
end end
JALR : begin // JUMP REG - Jalr JALR : begin // JUMP REG - Jalr
immediate[11:0] = instruction[31:20]; imm[11:0] = instruction[31:20];
immediate[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111; imm[31:12] = (instruction[31] == 0) ? 12'b00000000000000000000 : 12'b11111111111111111111;
we_reg = 1; reg_we = 1;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b00; reg_sel_data_in = 2'b10;
select_a = instruction[19:15]; reg_sel_out_a = instruction[19:15];
select_b = 5'b00000; reg_sel_out_b = 5'b00000;
select_d = instruction[11:7]; reg_sel_in = instruction[11:7];
source_alu = 0; alu_src = 0;
op_code_alu = 3'b000; alu_func = 3'b000;
mem_we = 0; mem_we = 0;
jmp_pc = 2'b10; jmp_pc = 2'b10;
b_pc = 0; b_pc = 0;
alu_not = 0; alu_not = 0;
end end
LUI : begin // LUI - lui LUI : begin // LUI - lui
immediate = {instruction[31:12] << 12, 12'b000000000000}; imm = {instruction[31:12] << 12, 12'b000000000000};
we_reg = 1; reg_we = 1;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b01; reg_sel_data_in = 2'b00;
select_a = 5'b00000; reg_sel_out_a = 5'b00000;
select_b = 5'b00000; reg_sel_out_b = 5'b00000;
select_d = instruction[11:7]; reg_sel_in = instruction[11:7];
source_alu = 1; alu_src = 1;
op_code_alu = 3'b000; alu_func = 3'b000;
mem_we = 0; mem_we = 0;
jmp_pc = 2'b00; jmp_pc = 2'b00;
b_pc = 0; b_pc = 0;
alu_not = 0; alu_not = 0;
end end
AUIPC : begin // AUIPC - auipc AUIPC : begin // AUIPC - auipc
immediate = {instruction[31:12] << 12, 12'b000000000000}; imm = {instruction[31:12] << 12, 12'b000000000000};
we_reg = 1; reg_we = 1;
adder_pc = 1; adder_pc = 1;
input_reg = 2'b00; reg_sel_data_in = 2'b11;
select_a = 5'b00000; reg_sel_out_a = 5'b00000;
select_b = 5'b00000; reg_sel_out_b = 5'b00000;
select_d = instruction[11:7]; reg_sel_in = instruction[11:7];
source_alu = 1; alu_src = 1;
op_code_alu = 3'b000; alu_func = 3'b000;
mem_we = 0; mem_we = 0;
jmp_pc = 2'b00; jmp_pc = 2'b00;
b_pc = 0; b_pc = 0;
alu_not = 0; alu_not = 0;
end end
default : begin // NOP default : begin // NOP
immediate = 32'b0; imm = 32'b0;
we_reg = 0; reg_we = 0;
adder_pc = 0; adder_pc = 0;
input_reg = 2'b00; reg_sel_data_in = 2'b00;
select_a = 5'b00000; reg_sel_out_a = 5'b00000;
select_b = 5'b00000; reg_sel_out_b = 5'b00000;
select_d = 5'b00000; reg_sel_in = 5'b00000;
source_alu = 0; alu_src = 0;
op_code_alu = 3'b000; alu_func = 3'b000;
mem_we = 0; mem_we = 0;
jmp_pc = 2'b00; jmp_pc = 2'b00;
b_pc = 0; b_pc = 0;

View File

@ -1,12 +1,12 @@
module program_counter (input clock, reset, module program_counter (input clock, reset,
input [31:0] new_pc, input [31:0] pc_new_addr,
output reg [31:0] pc); output reg [31:0] pc_addr);
always @ (posedge clock, posedge reset) begin always @ (posedge clock, posedge reset) begin
if (reset == 1'b1) if (reset == 1'b1)
pc <= 32'b0; pc_addr <= 32'b0;
else else
pc <= new_pc; pc_addr <= pc_new_addr;
end end
endmodule endmodule

View File

@ -1,6 +1,6 @@
module registers_bank (input clock, reset, we, module registers_bank (input clock, reset, we,
input [4:0] select_d, select_a, select_b, input [4:0] sel_in, sel_out_a, sel_out_b,
input [31:0] input_d, input [31:0] data_in,
output [31:0] output_a, output_b); output [31:0] output_a, output_b);
reg [31:0] registers[31:0]; reg [31:0] registers[31:0];
@ -32,10 +32,10 @@ module registers_bank (input clock, reset, we,
if (reset == 1) if (reset == 1)
registers[0] <= 32'b0; registers[0] <= 32'b0;
else if (we == 1) else if (we == 1)
registers[select_d] <= input_d; registers[sel_in] <= data_in;
end end
assign output_a = registers[select_a]; assign output_a = registers[sel_out_a];
assign output_b = registers[select_b]; assign output_b = registers[sel_out_b];
endmodule endmodule

View File

@ -1,25 +1,28 @@
module risc_v_cpu (input clock, reset, output [31:0] out); module risc_v_cpu (input clock, reset, output [31:0] out);
wire [31:0] in_b; wire [31:0] alu_in_b;
wire [31:0] alu_out; wire [31:0] alu_out;
wire alu_src, alu_not;
wire [3:0] alu_func;
wire reg_we, adder_pc;
wire [1:0] reg_sel_data_in;
wire [4:0] reg_sel_out_a, reg_sel_out_b, reg_sel_in;
wire [31:0] instruction; wire [31:0] instruction;
wire we_reg, adder_pc;
wire [1:0] input_reg;
wire [4:0] select_a, select_b, select_d;
wire source_alu;
wire [3:0] op_code_alu;
wire mem_we;
wire [1:0] jmp_pc;
wire b_pc, alu_not;
wire [31:0] input_d; wire mem_we;
wire [1:0] jmp_pc;
wire b_pc;
wire [31:0] reg_data_in;
wire [31:0] output_a, output_b; wire [31:0] output_a, output_b;
wire [31:0] immediate; wire [31:0] imm;
wire [31:0] pc; wire [31:0] pc_addr;
wire [31:0] new_pc; wire [31:0] pc_new_addr;
wire [1:0] pc_in; wire [1:0] pc_in;
@ -29,15 +32,15 @@ module risc_v_cpu (input clock, reset, output [31:0] out);
decoder decoder ( decoder decoder (
.instruction(instruction), .instruction(instruction),
.immediate(immediate), .imm(imm),
.we_reg(we_reg), .reg_we(reg_we),
.adder_pc(adder_pc), .adder_pc(adder_pc),
.input_reg(input_reg), .reg_sel_data_in(reg_sel_data_in),
.select_a(select_a), .reg_sel_out_a(reg_sel_out_a),
.select_b(select_b), .reg_sel_out_b(reg_sel_out_b),
.select_d(select_d), .reg_sel_in(reg_sel_in),
.source_alu(source_alu), .alu_src(alu_src),
.op_code_alu(op_code_alu), .alu_func(alu_func),
.mem_we(mem_we), .mem_we(mem_we),
.jmp_pc(jmp_pc), .jmp_pc(jmp_pc),
.b_pc(b_pc), .b_pc(b_pc),
@ -47,26 +50,26 @@ module risc_v_cpu (input clock, reset, output [31:0] out);
registers_bank registers_bank ( registers_bank registers_bank (
.clock(clock), .clock(clock),
.reset(reset), .reset(reset),
.we(we_reg), .we(reg_we),
.select_d(select_d), .sel_in(reg_sel_in),
.select_a(select_a), .sel_out_a(reg_sel_out_a),
.select_b(select_b), .sel_out_b(reg_sel_out_b),
.input_d(input_d), .data_in(reg_data_in),
.output_a(output_a), .output_a(output_a),
.output_b(output_b) .output_b(output_b)
); );
mux2_1 mux2_1_1 ( mux2_1 mux2_1_1 (
.A(output_b), .A(output_b),
.B(immediate), .B(imm),
.S(source_alu), .S(alu_src),
.O(in_b) .O(alu_in_b)
); );
alu alu ( alu alu (
.input_a(output_a), .input_a(output_a),
.input_b(in_b), .input_b(alu_in_b),
.op_code(op_code_alu), .op_code(alu_func),
.out(alu_out) .out(alu_out)
); );
@ -78,23 +81,23 @@ module risc_v_cpu (input clock, reset, output [31:0] out);
); );
mux4_1 mux4_1_1 ( mux4_1 mux4_1_1 (
.A(pc + 4), .A(pc_addr + 4),
.B(pc + immediate), .B(pc_addr + imm),
.C(alu_out), .C(alu_out),
.D(0), .D(0),
.S(pc_in), .S(pc_in),
.O(new_pc) .O(pc_new_addr)
); );
program_counter program_counter ( program_counter program_counter (
.clock(clock), .clock(clock),
.reset(reset), .reset(reset),
.new_pc(new_pc), .pc_new_addr(pc_new_addr),
.pc(pc) .pc_addr(pc_addr)
); );
instruction uut_instruction ( instruction uut_instruction (
.address(pc), .address(pc_addr),
.instruction(instruction) .instruction(instruction)
); );
@ -107,20 +110,13 @@ module risc_v_cpu (input clock, reset, output [31:0] out);
.data_out(memory_out) .data_out(memory_out)
); );
mux2_1 mux2_1_3 (
.A(4),
.B(alu_out),
.S(adder_pc),
.O(pc_store)
);
mux4_1 mux4_1_2 ( mux4_1 mux4_1_2 (
.A(pc_store + pc), .A(alu_out),
.B(alu_out), .B(memory_out),
.C(memory_out), .C(pc_addr + 4),
.D(0), .D(pc_addr + alu_out),
.S(input_reg), .S(reg_sel_data_in),
.O(input_d) .O(reg_data_in)
); );
endmodule endmodule