-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathctrl.v
140 lines (134 loc) · 6.84 KB
/
ctrl.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
`include "ctrl_header.v"
module ctrl(
input wire clk,
input wire reset,
input wire zero,
input wire overflow,
input wire MIO_ready,
input wire [31:0] Inst_in,
output reg MemRead,
output reg MemWrite,
output wire CPU_MIO,
output reg IorD,
output reg IRWrite,
output reg RegWrite,
output reg ALUSrcA,
output reg PCWrite,
output reg PCWriteCond,
output reg Branch,
output reg Shift,
output reg [1:0] RegDst,
output reg [1:0] MemtoReg,
output reg [1:0] ALUSrcB,
output reg [1:0] PCSource,
output reg [2:0] ALU_operation,
output wire [4:0] state_out
);
// wires
wire [5:0] op = Inst_in[31:26];
wire [5:0] func = Inst_in[5:0];
// state transfer
reg [4:0] state = `FETCH;
always @(posedge clk or posedge reset) begin
if (reset) begin
state <= `FETCH;
end else if (clk) begin
case(state)
`FETCH: state <= `DECODE;
`DECODE: case(op)
`LW: state <= `COMPUTE_MEM;
`SW: state <= `COMPUTE_MEM;
`R_TYPE: case(func)
`JR: state <= `JR_STATE;
`JALR: state <= `JALR_STATE;
`SRL: state <= `SRL_STATE;
default:state <= `R_TYPE_ALU;
endcase
`BEQ: state <= `BEQ_STATE;
`J: state <= `JUMP_STATE;
`BNE: state <= `BNE_STATE;
`ADDI: state <= `I_TYPE_ALU;
`ANDI: state <= `I_TYPE_ALU;
`SLTI: state <= `I_TYPE_ALU;
`ORI: state <= `I_TYPE_ALU;
`XORI: state <= `I_TYPE_ALU;
`LUI: state <= `LUI_STATE;
`JAL: state <= `JAL_STATE;
default: state <= state;
endcase
`COMPUTE_MEM: case(op)
`LW: state <= `MEM_READ;
`SW: state <= `MEM_WRITE;
default: state <= state;
endcase
`MEM_READ: state <= `MEM_WBACK;
`MEM_WBACK: state <= `FETCH;
`MEM_WRITE: state <= `FETCH;
`R_TYPE_ALU: state <= `R_TYPE_WREG;
`R_TYPE_WREG: state <= `FETCH;
`BEQ_STATE: state <= `FETCH;
`JUMP_STATE: state <= `FETCH;
`BNE_STATE: state <= `FETCH;
`I_TYPE_ALU: state <= `I_TYPE_WREG;
`I_TYPE_WREG: state <= `FETCH;
`LUI_STATE: state <= `FETCH;
`JR_STATE: state <= `FETCH;
`JAL_STATE: state <= `JUMP_STATE;
`JALR_STATE: state <= `JR_STATE;
`SRL_STATE: state <= `R_TYPE_WREG;
default: state <= state;
endcase
end
end
// truth table
reg [1:0] ALU_OP;
always @ * begin
case(state)
`FETCH: `Signal <= {1'b1, 1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 2'b00, 2'b00, 1'b0, 2'b01, 1'b0, 2'b00, 1'b0, 1'b0, 2'b00};
`DECODE: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b00, 1'b0, 2'b11, 1'b0, 2'b00, 1'b0, 1'b0, 2'b00};
`COMPUTE_MEM: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b00, 1'b1, 2'b10, 1'b0, 2'b00, 1'b0, 1'b0, 2'b00};
`MEM_READ: `Signal <= {1'b0, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0, 2'b00, 2'b00, 1'b0, 2'b00, 1'b0, 2'b00, 1'b0, 1'b0, 2'b00};
`MEM_WBACK: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b01, 2'b00, 1'b0, 2'b00, 1'b1, 2'b00, 1'b0, 1'b0, 2'b00};
`MEM_WRITE: `Signal <= {1'b0, 1'b0, 1'b1, 1'b0, 1'b1, 1'b0, 2'b00, 2'b00, 1'b0, 2'b00, 1'b0, 2'b00, 1'b0, 1'b0, 2'b00};
`R_TYPE_ALU: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b00, 1'b1, 2'b00, 1'b0, 2'b00, 1'b0, 1'b0, 2'b10};
`R_TYPE_WREG: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b00, 1'b0, 2'b00, 1'b1, 2'b01, 1'b0, 1'b0, 2'b00};
`BEQ_STATE: `Signal <= {1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b01, 1'b1, 2'b00, 1'b0, 2'b00, 1'b1, 1'b0, 2'b01};
`JUMP_STATE: `Signal <= {1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b10, 1'b0, 2'b00, 1'b0, 2'b00, 1'b0, 1'b0, 2'b00};
`BNE_STATE: `Signal <= {1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b01, 1'b1, 2'b00, 1'b0, 2'b00, 1'b0, 1'b0, 2'b01};
`I_TYPE_ALU: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b00, 1'b1, 2'b10, 1'b0, 2'b00, 1'b0, 1'b0, 2'b11};
`I_TYPE_WREG: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b00, 1'b0, 2'b00, 1'b1, 2'b00, 1'b0, 1'b0, 2'b00};
`LUI_STATE: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b10, 2'b00, 1'b0, 2'b00, 1'b1, 2'b00, 1'b0, 1'b0, 2'b00};
`JR_STATE: `Signal <= {1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b11, 1'b0, 2'b00, 1'b0, 2'b00, 1'b0, 1'b0, 2'b00};
`JAL_STATE: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b11, 2'b00, 1'b0, 2'b00, 1'b1, 2'b10, 1'b0, 1'b0, 2'b00};
`JALR_STATE: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b11, 2'b00, 1'b0, 2'b00, 1'b1, 2'b01, 1'b0, 1'b0, 2'b00};
`SRL_STATE: `Signal <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 2'b00, 2'b00, 1'b1, 2'b00, 1'b0, 2'b00, 1'b0, 1'b1, 2'b10};
default: `Signal <= 20'b0;
endcase
end
// ALU translate
always @ * begin
case(ALU_OP)
2'b00: ALU_operation <= 3'b010; // add
2'b01: ALU_operation <= 3'b110; // sub
2'b10: case(func) // R_Type
`ADD: ALU_operation <= 3'b010; // add
`SUB: ALU_operation <= 3'b110; // sub
`AND: ALU_operation <= 3'b000; // and
`OR : ALU_operation <= 3'b001; // or
`SLT: ALU_operation <= 3'b111; // slt
`SRL: ALU_operation <= 3'b101; // srl
`NOR: ALU_operation <= 3'b100; // nor
`XOR: ALU_operation <= 3'b011; // xor
endcase
2'b11: case(op) // I_Type
`ADDI: ALU_operation <= 3'b010; // add
`ANDI: ALU_operation <= 3'b000; // and
`ORI : ALU_operation <= 3'b001; // or
`SLTI: ALU_operation <= 3'b111; // slt
`XORI: ALU_operation <= 3'b011; // xor
endcase
endcase
end
assign CPU_MIO = MIO_ready & (MemRead | MemWrite);
assign state_out = state;
endmodule