This repository was archived by the owner on Mar 24, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathctrl.v
More file actions
152 lines (126 loc) · 7.09 KB
/
ctrl.v
File metadata and controls
152 lines (126 loc) · 7.09 KB
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
141
142
143
144
145
146
147
148
149
150
151
152
`include "ctrl_encode_def.v"
module ctrl(Op, Funct7, Funct3, Zero,
RegWrite, MemWrite, MemRead,
EXTOp, ALUOp, NPCOp,
ALUSrc, WDSel
);
input [6:0] Op; // opcode
input [6:0] Funct7; // funct7
input [2:0] Funct3; // funct3
input Zero;
output RegWrite; // control signal for register write
output MemWrite; // control signal for memory write
output MemRead; // control signal for memory read
output [5:0] EXTOp; // control signal to signed extension
output [4:0] ALUOp; // ALU opertion
output [4:0] NPCOp; // next pc operation
output ALUSrc; // ALU source for B
output [1:0] WDSel; // (register) write data selection
// AUIPC
wire AUIPC = ~Op[6]&~Op[5]&Op[4]&~Op[3]&Op[2]&Op[1]&Op[0];
//LUI
wire LUI = ~Op[6]&Op[5]&Op[4]&~Op[3]&Op[2]&Op[1]&Op[0];
// r format 0110011
wire rtype = ~Op[6]&Op[5]&Op[4]&~Op[3]&~Op[2]&Op[1]&Op[0]; //0110011
wire i_add = rtype& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]&~Funct3[2]&~Funct3[1]&~Funct3[0]; // add 0000000 000
wire i_sub = rtype& ~Funct7[6]& Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]&~Funct3[2]&~Funct3[1]&~Funct3[0]; // sub 0100000 000
wire i_or = rtype& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]& Funct3[2]& Funct3[1]&~Funct3[0]; // or 0000000 110
wire i_and = rtype& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]& Funct3[2]& Funct3[1]& Funct3[0]; // and 0000000 111
wire i_xor = rtype& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]& Funct3[2]&~Funct3[1]&~Funct3[0]; // xor 0000000 100
wire i_sll = rtype& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]&~Funct3[2]&~Funct3[1]& Funct3[0]; // sll 0000000 001
wire i_srl = rtype& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]& Funct3[2]&~Funct3[1]& Funct3[0]; // srl 0000000 101
wire i_sra = rtype& ~Funct7[6]& Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]& Funct3[2]&~Funct3[1]& Funct3[0]; // sra 0100000 101
// **new add 1
wire i_slt = rtype& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]& ~Funct3[2]&Funct3[1]&~Funct3[0]; // slt 0000000 010
wire i_sltu = rtype& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]& ~Funct3[2]&Funct3[1]&Funct3[0]; // sltu 0000000 011
// i format load 0000011
wire itype_l = ~Op[6]&~Op[5]&~Op[4]&~Op[3]&~Op[2]&Op[1]&Op[0]; //0000011
wire i_lw = itype_l&~Funct3[2]& Funct3[1]&~Funct3[0];//lw 010
wire i_lb = itype_l&~Funct3[2]&~Funct3[1]&~Funct3[0];//lb 000
wire i_lh = itype_l&~Funct3[2]&~Funct3[1]&Funct3[0];//lh 001
wire i_lbu = itype_l&Funct3[2]&~Funct3[1]&~Funct3[0];//lbu 100
wire i_lhu = itype_l&Funct3[2]&~Funct3[1]&Funct3[0];// lhu 101
// i format 0010011
wire itype_r = ~Op[6]&~Op[5]&Op[4]&~Op[3]&~Op[2]&Op[1]&Op[0]; //0010011
wire i_addi = itype_r& ~Funct3[2]& ~Funct3[1]& ~Funct3[0]; // addi 000
// **new add 3
wire i_slti = itype_r& ~Funct3[2]& Funct3[1]& ~Funct3[0]; //slti 010
wire i_sltiu = itype_r& ~Funct3[2]& Funct3[1]& Funct3[0];//sltiu 011
wire i_xori = itype_r& Funct3[2]& ~Funct3[1]& ~Funct3[0];// xori 100
wire i_ori = itype_r& Funct3[2]& Funct3[1]& ~Funct3[0];// ori 110
wire i_andi = itype_r& Funct3[2]& Funct3[1]& Funct3[0];// andi 111
// **new add 2
wire i_slli = itype_r& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]&~Funct3[2]&~Funct3[1]&Funct3[0]; // slli 0000000 001
wire i_srli = itype_r& ~Funct7[6]&~Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]&Funct3[2]&~Funct3[1]&Funct3[0];// srli 0000000 101
wire i_srai = itype_r& ~Funct7[6]&Funct7[5]&~Funct7[4]&~Funct7[3]&~Funct7[2]&~Funct7[1]&~Funct7[0]&Funct3[2]&~Funct3[1]&Funct3[0];// srai 0100000 101
wire shamtype = i_slli | i_srli | i_srai;
// s format 0100011
wire stype = ~Op[6]&Op[5]&~Op[4]&~Op[3]&~Op[2]&Op[1]&Op[0];//0100011
wire i_sw = stype& ~Funct3[2]& Funct3[1]&~Funct3[0]; // sw 010
// sb format 1100011
wire sbtype = Op[6]&Op[5]&~Op[4]&~Op[3]&~Op[2]&Op[1]&Op[0];//1100011
wire i_beq = sbtype& ~Funct3[2]& ~Funct3[1]&~Funct3[0]; // beq 000
wire i_bne = sbtype& ~Funct3[2]& ~Funct3[1]&Funct3[0]; // bne 001
wire i_blt = sbtype& Funct3[2]& ~Funct3[1]&~Funct3[0]; // blt 100
wire i_bge = sbtype& Funct3[2]&~Funct3[1]&Funct3[0]; // bge 101
wire i_bltu = sbtype& Funct3[2]&Funct3[1]&~Funct3[0];// bltu 110
wire i_bgeu = sbtype& Funct3[2]&Funct3[1]&Funct3[0];// bgeu 111
// j format
wire i_jal = Op[6]& Op[5]&~Op[4]& Op[3]& Op[2]& Op[1]& Op[0]; // jal 1101111
wire i_jalr = Op[6]& Op[5]&~Op[4]&~Op[3]&Op[2]&Op[1]&Op[0];// jalr 1100111
// generate control signals
assign RegWrite = rtype | itype_r | LUI | itype_l | i_jalr | i_jal | AUIPC; // register write
assign MemWrite = stype; // memory write
assign MemRead = itype_l; // memory read
assign ALUSrc = itype_r | stype | LUI | itype_l | i_jalr | AUIPC; // ALU B is from instruction immediate
// signed extension
// EXT_CTRL_ITYPE_SHAMT 6'b100000
// EXT_CTRL_ITYPE 6'b010000
// EXT_CTRL_STYPE 6'b001000
// EXT_CTRL_BTYPE 6'b000100
// EXT_CTRL_UTYPE 6'b000010
// EXT_CTRL_JTYPE 6'b000001
assign EXTOp[5] = shamtype;
assign EXTOp[4] = i_addi | itype_l | (itype_r & ~shamtype) | i_jalr;
assign EXTOp[3] = stype;
assign EXTOp[2] = sbtype;
assign EXTOp[1] = LUI | AUIPC;
assign EXTOp[0] = i_jal;
// WDSel_FromALU 2'b00
// WDSel_FromMEM 2'b01
// WDSel_FromPC 2'b10
assign WDSel[1] = i_jal | i_jalr;
assign WDSel[0] = itype_l;
// NPC_PLUS4 5'b00000
// NPC_BRANCH 5'b00001
// NPC_JUMP 5'b00010
// NPC_JALR 5'b00100
assign NPCOp[4] = 0;
assign NPCOp[3] = 0;
assign NPCOp[2] = i_jalr;
assign NPCOp[1] = i_jal;
assign NPCOp[0] = sbtype;
// ALUOp_nop 5'b00000
// ALUOp_lui 5'b00001
// ALUOp_add 5'b00011
// ALUOp_sub 5'b00100
// ALUOp_xor 5'b01100
// ALUOp_or 5'b01101
// ALUOp_and 5'b01110
// ALUOp_sll 5'b01111
// ALUOp_srl 5'b10000
// ALUOp_sra 5'b10001
// ALUOp_sub 5'b00100
// ALUOp_bne 5'b00101
// ALUOp_blt 5'b00110
// ALUOp_bge 5'b00111
// ALUOp_bltu 5'b01000
// ALUOp_bgeu 5'b01001
// ALUOp_slt 5'b01010 slti
// ALUOp_sltu 5'b01011 sltiu
assign ALUOp[4] = i_srl | i_sra | i_srli | i_srai;
assign ALUOp[3] = i_and | i_or | i_sll | i_xor | i_slt | i_sltu | i_slti | i_sltiu | i_andi | i_ori | i_xori | i_slli | i_bltu | i_bgeu;
assign ALUOp[2] = i_and | i_or | i_sub | i_sll | i_xor | i_andi | i_ori | i_xori | i_slli | i_beq | i_bne | i_blt | i_bge;
assign ALUOp[1] = i_addi | i_add | i_and | i_sll | itype_l | stype | i_slt | i_sltu | i_slti | i_sltiu | i_andi | i_slli | i_jalr | i_lw | i_sw | i_blt | i_bge | AUIPC;
assign ALUOp[0] = i_addi | i_add | i_or | LUI | i_sll | i_sra | itype_l | stype | i_sltu | i_sltiu | i_ori | i_slli | i_srai | i_jalr | i_lw | i_sw | i_bne | i_bge | i_bgeu | AUIPC;
endmodule