forked from gaph-pucrs/pucrs-rv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
execute.sv
116 lines (109 loc) · 4.98 KB
/
execute.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*!\file execute.sv
* PUCRS-RV VERSION - 1.0 - Public Release
*
* Distribution: September 2021
*
* Willian Nunes <willian.nunes@edu.pucrs.br>
* Marcos Sartori <marcos.sartori@acad.pucrs.br>
* Ney calazans <ney.calazans@pucrs.br>
*
* Research group: GAPH-PUCRS <>
*
* \brief
* Execute Unit is the fourth stage of the processor.
*
* \detailed
* Execute Unit is the fourth stage of the PUCRS-RV processor. At the
* entry it implements a dispatcher that assigns the operands only to the
* module responsible for that kind of instruction, the modules are:
* 1) Adder 2) Branch 3) Bypass 4) Logic 5) Memory 6) Shift. Each module is
* defined in a separeted file. These files must be included in this Unit
* if not compiled separately. At the other end it has a demux that collects
* the result only from the given module and bypass it to the next stage.
*/
import my_pkg::*;
module execute(
input logic clk,
input logic reset,
input logic [31:0] NPC, // Operand from Operand Fetch stage
input logic [31:0] opA, // ||
input logic [31:0] opB, // ||
input logic [31:0] opC, // ||
input instruction_type i, // Operation selector
input xu xu_sel, // Execute Unit selector
input logic [3:0] tag_in, // Instruction tag
output logic LS_operation,
output instruction_type i_out,
output logic [31:0] result_out [1:0], // Results array
output logic jump_out, // Signal that indicates a branch taken
output logic [3:0] tag_out, // Instruction tag
output logic we_out, // Write enable to regbank
output logic [31:0] read_address, // Memory Read Address
output logic read, // Allows memory read
output logic [3:0] we_mem); // Signal that indicates the write memory operation to retire
logic jump_int;
logic [3:0] we_mem_int;
logic [31:0] result [7:0];
instruction_type adder_i, logic_i, shift_i, branch_i, memory_i;
///////////////////////////////////////////////////// Instantiation of execution units ////////////////////
adderUnit adder1 (.opA(opA), .opB(opB), .i(adder_i), .result(result[0]));
logicUnit logical1 (.opA(opA), .opB(opB), .i(logic_i), .result(result[1]));
shiftUnit shift1 (.opA(opA), .opB(opB[4:0]), .i(shift_i), .result(result[2]));
branchUnit branch1 (.opA(opA), .opB(opB), .offset(opC), .NPC(NPC), .i(branch_i),
.result(result[4]), .result_jal(result[3]), .jump(jump_int), .we(we_branchUnit));
LSUnit memory1 (.opA(opA), .opB(opB), .data(opC), .i(memory_i),
.read_address(read_address), .read(read),
.write_address(result[7]), .DATA_wb(result[6]), .we_mem(we_mem_int), .we_rb(we_memoryUnit));
assign result[5] = opB; // bypass
////////////////////////////////////////////////////////////////////////////////////////////////////////////
assign adder_i = (xu_sel==adder) ? i : NOTOKEN;
assign logic_i = (xu_sel==logical) ? i : NOTOKEN;
assign shift_i = (xu_sel==shifter) ? i : NOTOKEN;
assign branch_i = (xu_sel==branch) ? i : NOTOKEN;
assign memory_i = (xu_sel==memory) ? i : NOTOKEN;
///////////////////////////////////////////////// DEMUX ////////////////////////////////////////////////////
always@(posedge clk) begin // RESULT[0]
if(xu_sel==adder)
result_out[0] <= result[0];
else if(xu_sel==logical)
result_out[0] <= result[1];
else if(xu_sel==shifter)
result_out[0] <= result[2];
else if(xu_sel==branch)
result_out[0] <= result[3];
else if(xu_sel==memory)
result_out[0] <= result[6];
else
result_out[0] <= result[5];
////////////////////////////////////
if(xu_sel==branch) // RESULT[1]
result_out[1] <= result[4];
else if(xu_sel==memory)
result_out[1] <= result[7];
else
result_out[1] <= '0;
////////////////////////////////////
if(xu_sel==branch) // JUMP_OUT
jump_out <= jump_int;
else
jump_out <= '0;
////////////////////////////////////
if(xu_sel==memory) begin // WRITE
LS_operation <= 1;
we_mem <= we_mem_int;
end else begin
LS_operation <= 0;
we_mem <= '0;
end
////////////////////////////////////
if(xu_sel==branch) // WE_OUT
we_out <= we_branchUnit;
else if(xu_sel==memory)
we_out <= we_memoryUnit;
else
we_out <= 1;
////////////////////////////////////
tag_out <= tag_in;
i_out <= i;
end
endmodule