@@ -4,15 +4,22 @@ module Control (
44 input [6 :0 ] op_code,
55 input [2 :0 ] funct3,
66 input funct7_5,
7+ input [11 :0 ] csr,
78 output reg [1 :0 ] pc_src, // 00 pc+4 01 JALR 10 JAL
89 output reg reg_write, // write register or not
910 output reg alu_src_b, // 0 -> from register, 1 -> from imm
1011 output reg [3 :0 ] alu_op, // ALUop
11- output reg [1 :0 ] mem_to_reg, // 00 -> ALU, 01 -> imm, 10 -> pc+4, 11 -> RAM
12+ output reg [2 :0 ] mem_to_reg, // 00 -> ALU, 01 -> imm, 10 -> pc+4, 11 -> RAM
1213 output reg mem_write, // write RAM or not
1314 output reg branch, // is branch or not
1415 output reg b_type, // 1 -> beq, 0 -> bne
15- output reg auipc // is auipc or not
16+ output reg auipc, // is auipc or not
17+ output reg [1 :0 ] trap, // 00 no trap, 01 ecall, 10 unimp
18+ output reg [11 :0 ] csr_read_addr,
19+ output reg [11 :0 ] csr_write_addr,
20+ output reg csr_write,
21+ output reg csr_write_src,
22+ output reg rev_imm
1623);
1724 `include "AluOp.vh"
1825 always @(* ) begin
@@ -25,11 +32,17 @@ module Control (
2532 branch = 0 ;
2633 b_type = 0 ;
2734 auipc = 0 ;
35+ trap = 0 ;
36+ csr_write = 0 ;
37+ rev_imm = 0 ;
38+ csr_read_addr = 0 ;
39+ csr_write_addr = 0 ;
40+ csr_write_src = 0 ;
2841
2942 case (op_code)
3043 7'b0000011 : begin // lw
3144 reg_write = 1 ; alu_src_b = 1 ; alu_op = ADD;
32- mem_to_reg = 2'b11 ;
45+ mem_to_reg = 3'b011 ;
3346 end
3447 7'b0100011 : begin // sw
3548 alu_src_b = 1 ; alu_op = ADD; mem_write = 1 ;
@@ -51,12 +64,20 @@ module Control (
5164 end
5265 7'b1100011 : begin // bne beq
5366 alu_op = XOR; branch = 1 ; b_type = ~ funct3[0 ];
67+ case (funct3)
68+ 3'b000 : begin alu_op = XOR; b_type = 1 ; end // beq
69+ 3'b001 : begin alu_op = XOR; b_type = 0 ; end // bne
70+ 3'b100 : begin alu_op = SLT; b_type = 0 ; end // blt
71+ 3'b101 : begin alu_op = SLT; b_type = 1 ; end // bge
72+ 3'b110 : begin alu_op = SLTU; b_type = 0 ; end // bltu
73+ 3'b111 : begin alu_op = SLTU; b_type = 1 ; end // bgeu
74+ endcase
5475 end
5576 7'b1101111 : begin // jal
56- pc_src = 2'b10 ; reg_write = 1 ; mem_to_reg = 2'b10 ;
77+ pc_src = 2'b10 ; reg_write = 1 ; mem_to_reg = 3'b010 ;
5778 end
5879 7'b0110111 : begin // lui
59- reg_write = 1 ; mem_to_reg = 2'b01 ;
80+ reg_write = 1 ; mem_to_reg = 3'b001 ;
6081 end
6182 7'b0110011 : begin // add slt and or sll srl sltu
6283 reg_write = 1 ;
@@ -66,8 +87,70 @@ module Control (
6687 auipc = 1 ;
6788 end
6889 7'b1100111 : begin // jalr
69- pc_src = 2'b01 ; reg_write = 1 ; mem_to_reg = 2'b10 ;
70- alu_src_b = 1 ; alu_op = ADD;
90+ pc_src = 2'b01 ; reg_write = 1 ; mem_to_reg = 3'b010 ;
91+ alu_src_b = 1 ;
92+ end
93+ 7'b1110011 : begin
94+ case (funct3)
95+ 3'b000 : begin
96+ case (csr)
97+ 12'b000000000000 : begin // ecall
98+ trap = 2'b01 ; csr_read_addr = 12'h305 ;
99+ pc_src = 2'b11 ;
100+ end
101+ 12'b001100000010 : begin // mret
102+ trap = 2'b11 ;
103+ csr_read_addr = 12'h341 ; pc_src = 2'b11 ;
104+ end
105+ default : begin
106+ trap = 2'b10 ; csr_read_addr = 12'h305 ;
107+ pc_src = 2'b11 ;
108+ end
109+ endcase
110+ end
111+ 3'b001 : begin // csrrw **Note**: Just implement for csrw and csrr
112+ if (csr != 12'h300 && csr != 12'h341 && csr != 12'h305 && csr != 12'h342 ) begin
113+ trap = 2'b10 ; csr_read_addr = 12'h305 ;
114+ pc_src = 2'b11 ;
115+ end else begin
116+ csr_write = 1 ; csr_read_addr = csr;
117+ csr_write_addr = csr; csr_write_src = 0 ;
118+ reg_write = 1 ; mem_to_reg = 3'b100 ;
119+ end
120+ end
121+ 3'b010 : begin // csrrs
122+ if (csr != 12'h300 && csr != 12'h341 && csr != 12'h305 && csr != 12'h342 ) begin
123+ trap = 2'b10 ; csr_read_addr = 12'h305 ;
124+ pc_src = 2'b11 ;
125+ end else begin
126+ // csr_write = 1; csr_read_addr = imm[11:0];
127+ // csr_write_addr = imm[11:0]; csr_write_src = 1;
128+ // alu_op = OR; alu_src_b = 2'b10;
129+ // reg_write = 1; mem_to_reg = 3'b100;
130+ csr_write = 0 ; csr_read_addr = csr; // csrr
131+ reg_write = 1 ; mem_to_reg = 3'b100 ;
132+ end
133+ end
134+ 3'b011 : begin // csrrc
135+ csr_write = 1 ; csr_read_addr = csr;
136+ csr_write_addr = csr; csr_write_src = 1 ;
137+ alu_op = AND; alu_src_b = 2'b10 ; rev_imm = 1 ;
138+ reg_write = 1 ; mem_to_reg = 3'b100 ;
139+ end
140+ 3'b101 : begin // csrrwi
141+
142+ end
143+ 3'b110 : begin // csrrsi
144+
145+ end
146+ 3'b111 : begin // csrrci
147+
148+ end
149+ endcase
150+ end
151+ default : begin
152+ trap = 2'b10 ; csr_read_addr = 12'h305 ;
153+ pc_src = 2'b11 ;
71154 end
72155 endcase
73156 end
0 commit comments