-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathid.v
123 lines (101 loc) · 3.55 KB
/
id.v
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
117
118
119
120
121
122
123
`include "defines.v"
module id(
input wire rst,
input wire[`InstAddrBus] pc_i,
input wire[`InstBus] inst_i,
// output to "regfile", "regfile" controller
output reg reg1_read_o,
output reg reg2_read_o,
output reg[`RegAddrBus] reg1_addr_o,
output reg[`RegAddrBus] reg2_addr_o,
// value read from "regfile"
input wire[`RegBus] reg1_data_i,
input wire[`RegBus] reg2_data_i,
// output for execution stagett
output reg[`AluOpBus] aluop_o,
output reg[`AluSelBus] alusel_o,
output reg[`RegBus] reg1_o,
output reg[`RegBus] reg2_o,
output reg[`RegAddrBus] wd_o,
output reg wreg_o
);
// operation code
// only need 26 - 31 bit to tell "ori" operation
wire[5:0] op = inst_i[31:26];
wire[4:0] op2 = inst_i[10:6];
wire[4:0] op3 = inst_i[5:0];
wire[5:0] op4 = inst_i[20:16];
// immediate number for storing instruction
reg[`RegBus] imm;
// validity of instruction
reg instvalid;
/*
stage 1. decode the instruction
*/
always @(*) begin
if(rst == `RstEnable) begin
aluop_o <= `EXE_NOP_OP;
alusel_o <= `EXE_RES_NOP;
wd_o <= `NOPRegAddr;
wreg_o <= `WriteDisable;
reg1_read_o <= 1'b0;
reg2_read_o <= 1'b0;
reg1_addr_o <= `NOPRegAddr;
reg2_addr_o <= `NOPRegAddr;
imm <= 32'h0;
end
else begin
aluop_o <= `EXE_NOP_OP;
alusel_o <= `EXE_RES_NOP;
wd_o <= inst_i[15:11];
wreg_o <= `WriteDisable;
instvalid <= `InstInvalid;
reg1_read_o <= 1'b0;
reg2_read_o <= 1'b0;
// default : passing reg_addr
reg1_addr_o <= inst_i[25:21];
reg2_addr_o <= inst_i[20:16];
imm <= `ZeroWord;
case(op)
`EXE_ORI: begin
// ori : need to write into reg, so-> WriteEnable
wreg_o <= `WriteEnable;
// "OR" type computation
aluop_o <= `EXE_OR_OP;
// "logic" type computation
alusel_o <= `EXE_RES_LOGIC;
// need regfile READ 1
reg1_read_o <= 1'b1;
// NOT need regfile READ 2, the other source num is imm
reg2_read_o <= 1'b0;
// immediate num : extended to 32 bits
imm <= {16'h0, inst_i[15:0]};
// addr of the result
wd_o <= inst_i[20:16];
// ori is valid instruction
instvalid <= `InstValid;
end
default : begin
end
endcase // case end
end // end if
end // end always
/*
stage 2. ensure the source number 1
*/
always @(*) begin
if(rst == `RstEnable) reg1_o <= `ZeroWord;
else if(reg1_read_o == 1'b1) reg1_o <= reg1_data_i;
else if(reg1_read_o == 1'b0) reg1_o <= imm;
else reg1_o <= `ZeroWord;
end
/*
stage 3. ensure the source number 2
*/
always @(*) begin
if(rst == `RstEnable) reg2_o <= `ZeroWord;
else if(reg2_read_o == 1'b1) reg2_o <= reg1_data_i;
else if(reg2_read_o == 1'b0) reg2_o <= imm;
else reg2_o <= `ZeroWord;
end
endmodule