OpenCores
URL https://opencores.org/ocsvn/steelcore/steelcore/trunk

Subversion Repositories steelcore

[/] [rtl/] [machine_control.v] - Blame information for rev 11

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 11 rafaelcalc
//////////////////////////////////////////////////////////////////////////////////
2
// Engineer: Rafael de Oliveira Calçada (rafaelcalcada@gmail.com) 
3
// 
4
// Create Date: 26.04.2020 23:18:08
5
// Module Name: machine_control
6
// Project Name: Steel Core 
7
// Description: Controls the core operation in M-mode 
8
// 
9
// Dependencies: globals.vh
10
// 
11
// Version 0.01
12
// 
13
//////////////////////////////////////////////////////////////////////////////////
14
 
15
/*********************************************************************************
16
 
17
MIT License
18
 
19
Copyright (c) 2020 Rafael de Oliveira Calçada
20
 
21
Permission is hereby granted, free of charge, to any person obtaining a copy
22
of this software and associated documentation files (the "Software"), to deal
23
in the Software without restriction, including without limitation the rights
24
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25
copies of the Software, and to permit persons to whom the Software is
26
furnished to do so, subject to the following conditions:
27
 
28
The above copyright notice and this permission notice shall be included in all
29
copies or substantial portions of the Software.
30
 
31
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37
SOFTWARE.
38
 
39
********************************************************************************/
40
 
41
`timescale 1ns / 1ps
42
`include "globals.vh"
43
 
44
module machine_control(
45
 
46
    input wire CLK,
47
    input wire RESET,
48
 
49
    // from control unit
50
    input wire ILLEGAL_INSTR,
51
    input wire MISALIGNED_LOAD,
52
    input wire MISALIGNED_STORE,
53
 
54
    // from pipeline stage 1
55
    input wire MISALIGNED_INSTR,
56
 
57
    // from instruction
58
    input wire [6:2] OPCODE_6_TO_2,
59
    input wire [2:0] FUNCT3,
60
    input wire [6:0] FUNCT7,
61
    input wire [4:0] RS1_ADDR,
62
    input wire [4:0] RS2_ADDR,
63
    input wire [4:0] RD_ADDR,
64
 
65
    // from interrupt controller
66
    input wire E_IRQ,
67
    input wire T_IRQ,
68
    input wire S_IRQ,
69
 
70
    // from CSR file
71
    input wire MIE,
72
    input wire MEIE,
73
    input wire MTIE,
74
    input wire MSIE,
75
    input wire MEIP,
76
    input wire MTIP,
77
    input wire MSIP,
78
 
79
    // to CSR file
80
    output reg I_OR_E,
81
    output reg SET_EPC,
82
    output reg SET_CAUSE,
83
    output reg [3:0] CAUSE,
84
    output reg INSTRET_INC,
85
    output reg MIE_CLEAR,
86
    output reg MIE_SET,
87
    output reg MISALIGNED_EXCEPTION,
88
 
89
    // to PC MUX
90
    output reg [1:0] PC_SRC,
91
 
92
    // to pipeline stage 2 register
93
    output reg FLUSH,
94
 
95
    // to Control Unit
96
    output wire TRAP_TAKEN
97
 
98
    );
99
 
100
    // state registers
101
    reg [3:0] curr_state;
102
    reg [3:0] next_state;
103
 
104
    // machine states
105
    parameter STATE_RESET         = 4'b0001;
106
    parameter STATE_OPERATING     = 4'b0010;
107
    parameter STATE_TRAP_TAKEN    = 4'b0100;
108
    parameter STATE_TRAP_RETURN   = 4'b1000;
109
 
110
    // internal control signals
111
    wire exception;
112
    wire ip;
113
    wire eip;
114
    wire tip;
115
    wire sip;
116
    wire is_system;
117
    wire RS1_ADDR_zero;
118
    wire RS2_ADDR_zero;
119
    wire rd_zero;
120
    wire RS2_ADDR_mret;
121
    wire RS2_ADDR_ebreak;
122
    wire FUNCT3_zero;
123
    wire FUNCT7_zero;
124
    wire FUNCT7_mret;
125
    wire csr;
126
    wire mret;
127
    wire ecall;
128
    wire ebreak;
129
    reg pre_instret_inc;
130
 
131
    // COMBINATIONAL LOGIC -------------------------------------------
132
 
133
    assign is_system = OPCODE_6_TO_2[6] & OPCODE_6_TO_2[5] & OPCODE_6_TO_2[4] & ~OPCODE_6_TO_2[3] & ~OPCODE_6_TO_2[2];
134
    assign FUNCT3_zero = ~(FUNCT3[2] | FUNCT3[1] | FUNCT3[0]);
135
    assign FUNCT7_zero = ~(FUNCT7[6] | FUNCT7[5] | FUNCT7[4] | FUNCT7[3] | FUNCT7[2] | FUNCT7[1] | FUNCT7[0]);
136
    assign FUNCT7_wfi = ~FUNCT7[6] & ~FUNCT7[5] & ~FUNCT7[4] & FUNCT7[3] & ~FUNCT7[2] & ~FUNCT7[1] & ~FUNCT7[0];
137
    assign FUNCT7_mret = ~FUNCT7[6] & ~FUNCT7[5] & FUNCT7[4] & FUNCT7[3] & ~FUNCT7[2] & ~FUNCT7[1] & ~FUNCT7[0];
138
    assign RS1_ADDR_zero = ~(RS1_ADDR[4] | RS1_ADDR[3] | RS1_ADDR[2] | RS1_ADDR[1] | RS1_ADDR[0]);
139
    assign RS2_ADDR_zero = ~(RS2_ADDR[4] | RS2_ADDR[3] | RS2_ADDR[2] | RS2_ADDR[1] | RS2_ADDR[0]);
140
    assign rd_zero = ~(RD_ADDR[4] | RD_ADDR[3] | RD_ADDR[2] | RD_ADDR[1] | RD_ADDR[0]);
141
    assign RS2_ADDR_wfi = ~RS2_ADDR[4] & ~RS2_ADDR[3] & RS2_ADDR[2] & ~RS2_ADDR[1] & RS2_ADDR[0];
142
    assign RS2_ADDR_mret = ~RS2_ADDR[4] & ~RS2_ADDR[3] & ~RS2_ADDR[2] & RS2_ADDR[1] & ~RS2_ADDR[0];
143
    assign RS2_ADDR_ebreak = ~RS2_ADDR[4] & ~RS2_ADDR[3] & ~RS2_ADDR[2] & ~RS2_ADDR[1] & RS2_ADDR[0];
144
    assign mret = is_system & FUNCT7_mret & RS2_ADDR_mret & RS1_ADDR_zero & FUNCT3_zero & rd_zero;
145
    assign ecall = is_system & FUNCT7_zero & RS2_ADDR_zero & RS1_ADDR_zero & FUNCT3_zero & rd_zero;
146
    assign ebreak = is_system & FUNCT7_zero & RS2_ADDR_ebreak & RS1_ADDR_zero & FUNCT3_zero & rd_zero;
147
 
148
    assign eip = MEIE & (E_IRQ | MEIP);
149
    assign tip = MTIE & (T_IRQ | MTIP);
150
    assign sip = MSIE & (S_IRQ | MSIP);
151
    assign ip = eip | tip | sip;
152
    assign exception = ILLEGAL_INSTR | MISALIGNED_INSTR | MISALIGNED_LOAD | MISALIGNED_STORE;
153
    assign TRAP_TAKEN = (MIE & ip) | exception | ecall | ebreak;
154
 
155
    always @*
156
    begin
157
        case(curr_state)
158
            STATE_RESET:
159
                next_state = STATE_OPERATING;
160
            STATE_OPERATING:
161
                if(TRAP_TAKEN) next_state = STATE_TRAP_TAKEN;
162
                else if(mret) next_state = STATE_TRAP_RETURN;
163
                else next_state = STATE_OPERATING;
164
            STATE_TRAP_TAKEN:
165
                next_state = STATE_OPERATING;
166
            STATE_TRAP_RETURN:
167
                next_state = STATE_OPERATING;
168
            default:
169
                next_state = STATE_OPERATING;
170
        endcase
171
    end
172
 
173
    // output generation
174
    always @*
175
    begin
176
        case(curr_state)
177
            STATE_RESET:
178
                begin
179
                    PC_SRC = `PC_BOOT;
180
                    FLUSH = 1'b1;
181
                    INSTRET_INC = 1'b0;
182
                    SET_EPC = 1'b0;
183
                    SET_CAUSE = 1'b0;
184
                    MIE_CLEAR = 1'b0;
185
                    MIE_SET = 1'b0;
186
                end
187
            STATE_OPERATING:
188
                begin
189
                    PC_SRC = `PC_NEXT;
190
                    FLUSH = 1'b0;
191
                    INSTRET_INC = 1'b1;
192
                    SET_EPC = 1'b0;
193
                    SET_CAUSE = 1'b0;
194
                    MIE_CLEAR = 1'b0;
195
                    MIE_SET = 1'b0;
196
                end
197
            STATE_TRAP_TAKEN:
198
                begin
199
                    PC_SRC = `PC_TRAP;
200
                    FLUSH = 1'b1;
201
                    INSTRET_INC = 1'b0;
202
                    SET_EPC = 1'b1;
203
                    SET_CAUSE = 1'b1;
204
                    MIE_CLEAR = 1'b1;
205
                    MIE_SET = 1'b0;
206
                end
207
            STATE_TRAP_RETURN:
208
                begin
209
                    PC_SRC = `PC_EPC;
210
                    FLUSH = 1'b1;
211
                    INSTRET_INC = 1'b0;
212
                    SET_EPC = 1'b0;
213
                    SET_CAUSE = 1'b0;
214
                    MIE_CLEAR = 1'b0;
215
                    MIE_SET = 1'b1;
216
                end
217
            default:
218
                begin
219
                    PC_SRC = `PC_NEXT;
220
                    FLUSH = 1'b0;
221
                    INSTRET_INC = 1'b1;
222
                    SET_EPC = 1'b0;
223
                    SET_CAUSE = 1'b0;
224
                    MIE_CLEAR = 1'b0;
225
                    MIE_SET = 1'b0;
226
                end
227
        endcase
228
 
229
    end
230
 
231
    // SEQUENTIAL LOGIC -------------------------------------------
232
 
233
    always @(posedge CLK)
234
    begin
235
        if(RESET) curr_state <= STATE_RESET;
236
        else curr_state <= next_state;
237
    end
238
 
239
    always @(posedge CLK)
240
    begin
241
        if(RESET) MISALIGNED_EXCEPTION <= 1'b0;
242
        else MISALIGNED_EXCEPTION <= MISALIGNED_INSTR | MISALIGNED_LOAD | MISALIGNED_STORE;
243
    end
244
 
245
    always @(posedge CLK)
246
    begin
247
        if(RESET)
248
        begin
249
            CAUSE <= 4'b0;
250
            I_OR_E <= 1'b0;
251
        end
252
        else if(curr_state == STATE_OPERATING)
253
        begin
254
            if(MIE & eip)
255
            begin
256
                CAUSE <= 4'b1011; // M-mode external interrupt
257
                I_OR_E <= 1'b1;
258
            end
259
            else if(MIE & sip)
260
            begin
261
                CAUSE <= 4'b0011; // M-mode software interrupt
262
                I_OR_E <= 1'b1;
263
            end
264
            else if(MIE & tip)
265
            begin
266
                CAUSE <= 4'b0111; // M-mode timer interrupt
267
                I_OR_E <= 1'b1;
268
            end
269
            else if(ILLEGAL_INSTR)
270
            begin
271
                CAUSE <= 4'b0010; // Illegal instruction
272
                I_OR_E <= 1'b0;
273
            end
274
            else if(MISALIGNED_INSTR)
275
            begin
276
                CAUSE <= 4'b0000; // Instruction address misaligned
277
                I_OR_E <= 1'b0;
278
            end
279
            else if(ecall)
280
            begin
281
                CAUSE <= 4'b1011; // Environment call from M-mode
282
                I_OR_E <= 1'b0;
283
            end
284
            else if(ebreak)
285
            begin
286
                CAUSE <= 4'b0011; // Breakpoint
287
                I_OR_E <= 1'b0;
288
            end
289
            else if(MISALIGNED_STORE)
290
            begin
291
                CAUSE <= 4'b0110; // Store address misaligned
292
                I_OR_E <= 1'b0;
293
            end
294
            else if(MISALIGNED_LOAD)
295
            begin
296
                CAUSE <= 4'b0100; // Load address misaligned
297
                I_OR_E <= 1'b0;
298
            end
299
        end
300
    end
301
 
302
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2021 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.