Added support for MUL/DIV (Passes all tests)

This commit is contained in:
felsabbagh3 2019-03-22 03:54:59 -04:00
parent 01d142c6e6
commit 097e0217de
12 changed files with 766 additions and 450 deletions

View file

@ -9,7 +9,7 @@ module VX_d_e_reg (
input wire[31:0] in_rd1,
input wire[4:0] in_rs2,
input wire[31:0] in_rd2,
input wire[3:0] in_alu_op,
input wire[4:0] in_alu_op,
input wire[1:0] in_wb,
input wire in_rs2_src, // NEW
input wire[31:0] in_itype_immed, // new
@ -37,7 +37,7 @@ module VX_d_e_reg (
output wire[31:0] out_rd1,
output wire[4:0] out_rs2,
output wire[31:0] out_rd2,
output wire[3:0] out_alu_op,
output wire[4:0] out_alu_op,
output wire[1:0] out_wb,
output wire out_rs2_src, // NEW
output wire[31:0] out_itype_immed, // new
@ -58,7 +58,7 @@ module VX_d_e_reg (
reg[31:0] rd1;
reg[4:0] rs2;
reg[31:0] rd2;
reg[3:0] alu_op;
reg[4:0] alu_op;
reg[1:0] wb;
reg[31:0] PC_next_out;
reg rs2_src;

View file

@ -29,7 +29,7 @@ module VX_decode(
output wire[4:0] out_rs2,
output wire[31:0] out_rd2,
output wire[1:0] out_wb,
output wire[3:0] out_alu_op,
output wire[4:0] out_alu_op,
output wire out_rs2_src, // NEW
output reg[31:0] out_itype_immed, // new
output wire[2:0] out_mem_read, // NEW
@ -45,7 +45,6 @@ module VX_decode(
wire[6:0] curr_opcode;
reg[3:0] alu_op;
wire[31:0] rd1_register;
wire[31:0] rd2_register;
@ -94,8 +93,10 @@ module VX_decode(
wire[11:0] alu_shift_i_immed;
wire[1:0] csr_type;
reg[3:0] csr_alu;
reg[4:0] csr_alu;
reg[4:0] alu_op;
reg[4:0] mul_alu;
// always @(posedge clk) begin
// $display("Decode: curr_pc: %h", in_curr_PC);
@ -306,6 +307,20 @@ module VX_decode(
endcase
end
always @(*) begin
// ALU OP
case(func3)
3'h0: mul_alu = `MUL;
3'h1: mul_alu = `MULH;
3'h2: mul_alu = `MULHSU;
3'h3: mul_alu = `MULHU;
3'h4: mul_alu = `DIV;
3'h5: mul_alu = `DIVU;
3'h6: mul_alu = `REM;
3'h7: mul_alu = `REMU;
default: mul_alu = `NO_ALU;
endcase
end
assign csr_type = func3[1:0];
@ -318,14 +333,16 @@ module VX_decode(
endcase
end
wire[4:0] temp_final_alu;
assign out_alu_op = is_btype ? ((out_branch_type < `BLTU) ? `SUB : `SUBU) :
assign temp_final_alu = is_btype ? ((out_branch_type < `BLTU) ? `SUB : `SUBU) :
is_lui ? `LUI_ALU :
is_auipc ? `AUIPC_ALU :
is_csr ? csr_alu :
(is_stype || is_linst) ? `ADD :
alu_op;
assign out_alu_op = ((func7[0] == 1'b1) && is_rtype) ? mul_alu : temp_final_alu;
endmodule

View file

@ -46,23 +46,31 @@
`define BGTU 3'h6
`define NO_ALU 4'd15
`define ADD 4'd0
`define SUB 4'd1
`define SLLA 4'd2
`define SLT 4'd3
`define SLTU 4'd4
`define XOR 4'd5
`define SRL 4'd6
`define SRA 4'd7
`define OR 4'd8
`define AND 4'd9
`define SUBU 4'd10
`define LUI_ALU 4'd11
`define AUIPC_ALU 4'd12
`define CSR_ALU_RW 4'd13
`define CSR_ALU_RS 4'd14
`define CSR_ALU_RC 4'd15
`define NO_ALU 5'd15
`define ADD 5'd0
`define SUB 5'd1
`define SLLA 5'd2
`define SLT 5'd3
`define SLTU 5'd4
`define XOR 5'd5
`define SRL 5'd6
`define SRA 5'd7
`define OR 5'd8
`define AND 5'd9
`define SUBU 5'd10
`define LUI_ALU 5'd11
`define AUIPC_ALU 5'd12
`define CSR_ALU_RW 5'd13
`define CSR_ALU_RS 5'd14
`define CSR_ALU_RC 5'd15
`define MUL 5'd16
`define MULH 5'd17
`define MULHSU 5'd18
`define MULHU 5'd19
`define DIV 5'd20
`define DIVU 5'd21
`define REM 5'd22
`define REMU 5'd23

View file

@ -7,7 +7,7 @@ module VX_execute (
input wire[31:0] in_rd1,
input wire[4:0] in_rs2,
input wire[31:0] in_rd2,
input wire[3:0] in_alu_op,
input wire[4:0] in_alu_op,
input wire[1:0] in_wb,
input wire in_rs2_src, // NEW
input wire[31:0] in_itype_immed, // new
@ -68,101 +68,53 @@ module VX_execute (
// $display("EXECUTE CURR_PC: %h",in_curr_PC);
// end
/* verilator lint_off UNUSED */
wire[63:0] mult_unsigned_result = ALU_in1 * ALU_in2;
wire[63:0] mult_signed_result = $signed(ALU_in1) * $signed(ALU_in2);
wire[63:0] alu_in1_signed = {{32{ALU_in1[31]}}, ALU_in1};
wire[63:0] mult_signed_un_result = alu_in1_signed * ALU_in2;
/* verilator lint_on UNUSED */
always @(*) begin
case(in_alu_op)
`CSR_ALU_RW: out_csr_result = in_csr_mask;
`CSR_ALU_RS: out_csr_result = in_csr_data | in_csr_mask;
`CSR_ALU_RC: out_csr_result = in_csr_data & (32'hFFFFFFFF - in_csr_mask);
default: out_csr_result = 32'hdeadbeef;
endcase
end
always @(*) begin
case(in_alu_op)
`ADD:
begin
out_alu_result = $signed(ALU_in1) + $signed(ALU_in2);
out_csr_result = 32'hdeadbeef;
end
`SUB:
begin
out_alu_result = $signed(ALU_in1) - $signed(ALU_in2);
// $display("PC: %h ----> %h and %h",in_curr_PC, $signed(ALU_in1), $signed(ALU_in2));
out_csr_result = 32'hdeadbeef;
end
`SLLA:
begin
out_alu_result = ALU_in1 << ALU_in2[4:0];
out_csr_result = 32'hdeadbeef;
end
`SLT:
begin
out_alu_result = ($signed(ALU_in1) < $signed(ALU_in2)) ? 32'h1 : 32'h0;
out_csr_result = 32'hdeadbeef;
end
`SLTU:
begin
out_alu_result = ALU_in1 < ALU_in2 ? 32'h1 : 32'h0;
out_csr_result = 32'hdeadbeef;
end
`XOR:
begin
out_alu_result = ALU_in1 ^ ALU_in2;
out_csr_result = 32'hdeadbeef;
end
`SRL:
begin
out_alu_result = ALU_in1 >> ALU_in2[4:0];
out_csr_result = 32'hdeadbeef;
end
`SRA:
begin
out_alu_result = $signed(ALU_in1) >>> ALU_in2[4:0];
// $display("Shifting right arithmatic - PC: %h\t%h >>> %h = %h",in_curr_PC, $signed(ALU_in1), ALU_in2, out_alu_result);
out_csr_result = 32'hdeadbeef;
end
`OR:
begin
out_alu_result = ALU_in1 | ALU_in2;
out_csr_result = 32'hdeadbeef;
end
`AND:
begin
out_alu_result = ALU_in2 & ALU_in1;
out_csr_result = 32'hdeadbeef;
end
`SUBU:
begin
if (ALU_in1 >= ALU_in2) begin
out_alu_result = 32'h0;
end else begin
out_alu_result = 32'hffffffff;
end
out_csr_result = 32'hdeadbeef;
end
`LUI_ALU:
begin
out_alu_result = upper_immed;
out_csr_result = 32'hdeadbeef;
end
`AUIPC_ALU:
begin
out_alu_result = $signed(in_curr_PC) + $signed(upper_immed);
out_csr_result = 32'hdeadbeef;
end
`CSR_ALU_RW:
begin
out_alu_result = in_csr_data;
out_csr_result = in_csr_mask;
end
`CSR_ALU_RS:
begin
out_alu_result = in_csr_data;
out_csr_result = in_csr_data | in_csr_mask;
end
`CSR_ALU_RC:
begin
out_alu_result = in_csr_data;
out_csr_result = in_csr_data & (32'hFFFFFFFF - in_csr_mask);
end
default:
begin
out_alu_result = 32'h0;
out_csr_result = 32'hdeadbeef;
end
`ADD: out_alu_result = $signed(ALU_in1) + $signed(ALU_in2);
`SUB: out_alu_result = $signed(ALU_in1) - $signed(ALU_in2);
`SLLA: out_alu_result = ALU_in1 << ALU_in2[4:0];
`SLT: out_alu_result = ($signed(ALU_in1) < $signed(ALU_in2)) ? 32'h1 : 32'h0;
`SLTU: out_alu_result = ALU_in1 < ALU_in2 ? 32'h1 : 32'h0;
`XOR: out_alu_result = ALU_in1 ^ ALU_in2;
`SRL: out_alu_result = ALU_in1 >> ALU_in2[4:0];
`SRA: out_alu_result = $signed(ALU_in1) >>> ALU_in2[4:0];
`OR: out_alu_result = ALU_in1 | ALU_in2;
`AND: out_alu_result = ALU_in2 & ALU_in1;
`SUBU: out_alu_result = (ALU_in1 >= ALU_in2) ? 32'h0 : 32'hffffffff;
`LUI_ALU: out_alu_result = upper_immed;
`AUIPC_ALU: out_alu_result = $signed(in_curr_PC) + $signed(upper_immed);
`CSR_ALU_RW: out_alu_result = in_csr_data;
`CSR_ALU_RS: out_alu_result = in_csr_data;
`CSR_ALU_RC: out_alu_result = in_csr_data;
`MUL: out_alu_result = mult_signed_result[31:0];
`MULH: out_alu_result = mult_signed_result[63:32];
`MULHSU: out_alu_result = mult_signed_un_result[63:32];
`MULHU: out_alu_result = mult_unsigned_result[63:32];
`DIV: out_alu_result = (ALU_in2 == 0) ? 32'hffffffff : $signed($signed(ALU_in1) / $signed(ALU_in2));
`DIVU: out_alu_result = (ALU_in2 == 0) ? 32'hffffffff : ALU_in1 / ALU_in2;
`REM: out_alu_result = (ALU_in2 == 0) ? ALU_in1 : $signed($signed(ALU_in1) % $signed(ALU_in2));
`REMU: out_alu_result = (ALU_in2 == 0) ? ALU_in1 : ALU_in1 % ALU_in2;
default: out_alu_result = 32'h0;
endcase // in_alu_op
end

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -48,8 +48,10 @@ VL_MODULE(VVortex) {
VL_SIG8(Vortex__DOT__vx_f_d_reg__DOT__valid,0,0);
VL_SIG8(Vortex__DOT__vx_decode__DOT__is_itype,0,0);
VL_SIG8(Vortex__DOT__vx_decode__DOT__is_csr,0,0);
VL_SIG8(Vortex__DOT__vx_decode__DOT__mul_alu,4,0);
VL_SIG8(Vortex__DOT__vx_decode__DOT__temp_final_alu,4,0);
VL_SIG8(Vortex__DOT__vx_d_e_reg__DOT__rd,4,0);
VL_SIG8(Vortex__DOT__vx_d_e_reg__DOT__alu_op,3,0);
VL_SIG8(Vortex__DOT__vx_d_e_reg__DOT__alu_op,4,0);
VL_SIG8(Vortex__DOT__vx_d_e_reg__DOT__wb,1,0);
VL_SIG8(Vortex__DOT__vx_d_e_reg__DOT__rs2_src,0,0);
VL_SIG8(Vortex__DOT__vx_d_e_reg__DOT__mem_read,2,0);
@ -98,10 +100,10 @@ VL_MODULE(VVortex) {
VL_SIG(Vortex__DOT__vx_decode__DOT__rd2_register,31,0);
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__rd1,31,0);
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__rd2,31,0);
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__PC_next_out,31,0);
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__itype_immed,31,0);
};
struct {
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__PC_next_out,31,0);
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__itype_immed,31,0);
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__upper_immed,19,0);
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__csr_mask,31,0);
VL_SIG(Vortex__DOT__vx_d_e_reg__DOT__curr_PC,31,0);
@ -117,6 +119,7 @@ VL_MODULE(VVortex) {
VL_SIG(Vortex__DOT__vx_m_w_reg__DOT__alu_result,31,0);
VL_SIG(Vortex__DOT__vx_m_w_reg__DOT__mem_result,31,0);
VL_SIG(Vortex__DOT__vx_m_w_reg__DOT__PC_next,31,0);
VL_SIG64(Vortex__DOT__vx_execute__DOT__mult_signed_result,63,0);
VL_SIG64(Vortex__DOT__vx_csr_handler__DOT__cycle,63,0);
VL_SIG64(Vortex__DOT__vx_csr_handler__DOT__instret,63,0);
VL_SIG(Vortex__DOT__vx_decode__DOT__vx_register_file__DOT__registers[32],31,0);
@ -126,8 +129,10 @@ VL_MODULE(VVortex) {
// LOCAL VARIABLES
// Internals; generally not touched by application code
// Begin mtask footprint all:
VL_SIG8(__Vtableidx1,2,0);
VL_SIG8(__Vclklast__TOP__clk,0,0);
VL_SIG8(__Vclklast__TOP__reset,0,0);
static VL_ST_SIG8(__Vtable1_Vortex__DOT__vx_decode__DOT__mul_alu[8],4,0);
// INTERNAL VARIABLES
// Internals; generally not touched by application code

Binary file not shown.

View file

@ -2,11 +2,11 @@
C "-Wall -cc Vortex.v VX_fetch.v VX_f_d_reg.v VX_decode.v VX_register_file.v VX_d_e_reg.v VX_execute.v VX_e_m_reg.v VX_memory.v VX_m_w_reg.v VX_writeback.v VX_csr_handler.v VX_forwarding.v --exe test_bench.cpp"
S 4608404 12889046060 1553037052 0 1548678579 0 "/usr/local/Cellar/verilator/4.010/bin/verilator_bin"
S 1495 12889087229 1553211178 0 1553211178 0 "VX_csr_handler.v"
S 4626 12889079539 1553190875 0 1553190875 0 "VX_d_e_reg.v"
S 8725 12889063385 1553236943 0 1553236943 0 "VX_decode.v"
S 1351 12889079483 1553200040 0 1553200040 0 "VX_define.v"
S 4626 12889079539 1553237386 0 1553237386 0 "VX_d_e_reg.v"
S 9200 12889063385 1553237914 0 1553237914 0 "VX_decode.v"
S 1503 12889079483 1553237629 0 1553237629 0 "VX_define.v"
S 3644 12889083963 1553196174 0 1553196174 0 "VX_e_m_reg.v"
S 4919 12889081819 1553236958 0 1553236958 0 "VX_execute.v"
S 4844 12889081819 1553241258 0 1553241258 0 "VX_execute.v"
S 1120 12889050060 1553236935 0 1553236935 0 "VX_f_d_reg.v"
S 3537 12889047675 1553236929 0 1553236929 0 "VX_fetch.v"
S 5020 12889086478 1553236985 0 1553236985 0 "VX_forwarding.v"
@ -14,12 +14,12 @@ S 1578 12889085814 1553211072 0 1553211072 0 "VX_m_w_
S 2606 12889084513 1553234474 0 1553234474 0 "VX_memory.v"
S 958 12889070228 1553234503 0 1553234503 0 "VX_register_file.v"
S 806 12889086287 1553236964 0 1553236964 0 "VX_writeback.v"
S 12863 12889050092 1553211358 0 1553211358 0 "Vortex.v"
T 78272 12889102709 1553237041 0 1553237041 0 "obj_dir/VVortex.cpp"
T 7758 12889102708 1553237041 0 1553237041 0 "obj_dir/VVortex.h"
T 1800 12889102711 1553237041 0 1553237041 0 "obj_dir/VVortex.mk"
T 530 12889102707 1553237041 0 1553237041 0 "obj_dir/VVortex__Syms.cpp"
T 711 12889102706 1553237041 0 1553237041 0 "obj_dir/VVortex__Syms.h"
T 455 12889102712 1553237041 0 1553237041 0 "obj_dir/VVortex__ver.d"
T 0 0 1553237041 0 1553237041 0 "obj_dir/VVortex__verFiles.dat"
T 1159 12889102710 1553237041 0 1553237041 0 "obj_dir/VVortex_classes.mk"
S 12863 12889050092 1553237368 0 1553237368 0 "Vortex.v"
T 88166 12889102709 1553241260 0 1553241260 0 "obj_dir/VVortex.cpp"
T 8044 12889102708 1553241260 0 1553241260 0 "obj_dir/VVortex.h"
T 1800 12889102711 1553241260 0 1553241260 0 "obj_dir/VVortex.mk"
T 530 12889102707 1553241260 0 1553241260 0 "obj_dir/VVortex__Syms.cpp"
T 711 12889102706 1553241260 0 1553241260 0 "obj_dir/VVortex__Syms.h"
T 455 12889102712 1553241260 0 1553241260 0 "obj_dir/VVortex__ver.d"
T 0 0 1553241260 0 1553241260 0 "obj_dir/VVortex__verFiles.dat"
T 1159 12889102710 1553241260 0 1553241260 0 "obj_dir/VVortex_classes.mk"

View file

@ -340,3 +340,75 @@
# CPI: 1.04314
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING
**************** ../../src/riscv_tests/rv32um-p-div.hex ****************
# Dynamic Instructions: 112
# of total cycles: 123
# of forwarding stalls: 0
# of branch stalls: 0
# CPI: 1.09821
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING
**************** ../../src/riscv_tests/rv32um-p-divu.hex ****************
# Dynamic Instructions: 113
# of total cycles: 124
# of forwarding stalls: 0
# of branch stalls: 0
# CPI: 1.09735
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING
**************** ../../src/riscv_tests/rv32um-p-mul.hex ****************
# Dynamic Instructions: 589
# of total cycles: 600
# of forwarding stalls: 0
# of branch stalls: 0
# CPI: 1.01868
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING
**************** ../../src/riscv_tests/rv32um-p-mulh.hex ****************
# Dynamic Instructions: 585
# of total cycles: 596
# of forwarding stalls: 0
# of branch stalls: 0
# CPI: 1.0188
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING
**************** ../../src/riscv_tests/rv32um-p-mulhsu.hex ****************
# Dynamic Instructions: 585
# of total cycles: 596
# of forwarding stalls: 0
# of branch stalls: 0
# CPI: 1.0188
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING
**************** ../../src/riscv_tests/rv32um-p-mulhu.hex ****************
# Dynamic Instructions: 585
# of total cycles: 596
# of forwarding stalls: 0
# of branch stalls: 0
# CPI: 1.0188
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING
**************** ../../src/riscv_tests/rv32um-p-rem.hex ****************
# Dynamic Instructions: 112
# of total cycles: 123
# of forwarding stalls: 0
# of branch stalls: 0
# CPI: 1.09821
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING
**************** ../../src/riscv_tests/rv32um-p-remu.hex ****************
# Dynamic Instructions: 112
# of total cycles: 123
# of forwarding stalls: 0
# of branch stalls: 0
# CPI: 1.09821
# time to simulate: 6.95313e-310 milliseconds
# GRADE: PASSING

View file

@ -2,7 +2,7 @@
#include "test_bench.h"
#define NUM_TESTS 38
#define NUM_TESTS 46
int main(int argc, char **argv)
{
@ -52,6 +52,14 @@ int main(int argc, char **argv)
"../../src/riscv_tests/rv32ui-p-sw.hex",
"../../src/riscv_tests/rv32ui-p-xor.hex",
"../../src/riscv_tests/rv32ui-p-xori.hex",
"../../src/riscv_tests/rv32um-p-div.hex",
"../../src/riscv_tests/rv32um-p-divu.hex",
"../../src/riscv_tests/rv32um-p-mul.hex",
"../../src/riscv_tests/rv32um-p-mulh.hex",
"../../src/riscv_tests/rv32um-p-mulhsu.hex",
"../../src/riscv_tests/rv32um-p-mulhu.hex",
"../../src/riscv_tests/rv32um-p-rem.hex",
"../../src/riscv_tests/rv32um-p-remu.hex"
};
for (int ii = 0; ii < NUM_TESTS; ii++)

View file

@ -38,7 +38,7 @@ wire[31:0] decode_rd1;
wire[4:0] decode_rs2;
wire[31:0] decode_rd2;
wire[1:0] decode_wb;
wire[3:0] decode_alu_op;
wire[4:0] decode_alu_op;
wire decode_rs2_src;
reg[31:0] decode_itype_immed;
wire[2:0] decode_mem_read;
@ -59,7 +59,7 @@ wire[4:0] d_e_rs1;
wire[31:0] d_e_rd1;
wire[4:0] d_e_rs2;
wire[31:0] d_e_rd2;
wire[3:0] d_e_alu_op;
wire[4:0] d_e_alu_op;
wire[1:0] d_e_wb;
wire d_e_rs2_src;
wire[31:0] d_e_itype_immed;