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

Subversion Repositories steelcore

[/] [rtl/] [steel_top.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: 30.04.2020 02:39:50
5
// Module Name: steel_top
6
// Project Name: Steel Core 
7
// Description: Steel Core top module 
8
// 
9
// Dependencies: globals.vh
10
//               machine_control.v
11
//               alu.v
12
//               integer_file.v
13
//               branch_unit.v
14
//               decoder.v
15
//               csr_file.v
16
//               imm_generator.v
17
//               load_unit.v
18
//               store_unit.v
19
// 
20
// Version 0.01
21
// 
22
//////////////////////////////////////////////////////////////////////////////////
23
 
24
/*********************************************************************************
25
 
26
MIT License
27
 
28
Copyright (c) 2020 Rafael de Oliveira Calçada
29
 
30
Permission is hereby granted, free of charge, to any person obtaining a copy
31
of this software and associated documentation files (the "Software"), to deal
32
in the Software without restriction, including without limitation the rights
33
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
copies of the Software, and to permit persons to whom the Software is
35
furnished to do so, subject to the following conditions:
36
 
37
The above copyright notice and this permission notice shall be included in all
38
copies or substantial portions of the Software.
39
 
40
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
46
SOFTWARE.
47
 
48
********************************************************************************/
49
 
50
`timescale 1ns / 1ps
51
`include "globals.vh"
52
 
53
module steel_top #(
54
 
55
    parameter BOOT_ADDRESS = 32'h00000000
56
 
57
    )(
58
 
59
    input wire CLK,
60
    input wire RESET,
61
 
62
    // connection with Real Time Counter
63
    input wire [63:0] REAL_TIME,
64
 
65
    // connections with Instruction Memory
66
    output wire [31:0] I_ADDR,
67
    input wire [31:0] INSTR,
68
 
69
    // connections with Data Memory
70
    output wire [31:0] D_ADDR,
71
    output wire [31:0] DATA_OUT,
72
    output wire WR_REQ,
73
    output wire [3:0] WR_MASK,
74
    input wire [31:0] DATA_IN,
75
 
76
    //connections with Interrupt Controller
77
    input wire E_IRQ,
78
    input wire T_IRQ,
79
    input wire S_IRQ
80
 
81
    );
82
 
83
    // ---------------------------------
84
    // Internal wires and registers
85
    // ---------------------------------
86
 
87
    wire [4:0] RS1_ADDR;
88
    wire [4:0] RS2_ADDR;
89
    wire [4:0] RD_ADDR;
90
    reg [4:0] RD_ADDR_reg;
91
    wire [31:0] CSR_DATA;
92
    wire [11:0] CSR_ADDR;
93
    reg [11:0] CSR_ADDR_reg;
94
    wire [31:0] RS1;
95
    reg [31:0] RS1_reg;
96
    wire [31:0] RS2;
97
    reg [31:0] RS2_reg;
98
    reg [31:0] PC;
99
    reg [31:0] PC_reg;
100
    wire [31:0] NEXT_PC;
101
    wire [31:0] PC_PLUS_4;
102
    reg [31:0] PC_PLUS_4_reg;
103
    wire BRANCH_TAKEN;
104
    wire [31:0] IADDER_OUT;
105
    reg [31:0] IADDER_OUT_reg;
106
    wire [31:0] EPC;
107
    wire [31:0] TRAP_ADDRESS;
108
    wire [1:0] PC_SRC;
109
    wire [6:0] OPCODE;
110
    wire [6:0] FUNCT7;
111
    wire [2:0] FUNCT3;
112
    wire [3:0] ALU_OPCODE;
113
    reg [3:0] ALU_OPCODE_reg;
114
    wire MEM_WR_REQ;
115
    wire [3:0] MEM_WR_MASK;
116
    wire [1:0] LOAD_SIZE;
117
    reg [1:0] LOAD_SIZE_reg;
118
    wire LOAD_UNSIGNED;
119
    reg LOAD_UNSIGNED_reg;
120
    wire ALU_SRC;
121
    reg ALU_SRC_reg;
122
    wire IADDER_SRC;
123
    wire CSR_WR_EN;
124
    reg CSR_WR_EN_reg;
125
    wire RF_WR_EN;
126
    reg RF_WR_EN_reg;
127
    wire [2:0] WB_MUX_SEL;
128
    reg [2:0] WB_MUX_SEL_reg;
129
    wire [2:0] IMM_TYPE;
130
    wire [2:0] CSR_OP;
131
    reg [2:0] CSR_OP_reg;
132
    wire ILLEGAL_INSTR;
133
    wire MISALIGNED_LOAD;
134
    wire MISALIGNED_STORE;
135
    wire [31:0] IMM;
136
    reg [31:0] IMM_reg;
137
    wire I_OR_E;
138
    wire SET_CAUSE;
139
    wire [3:0] CAUSE_IN;
140
    wire SET_EPC;
141
    wire INSTRET_INC;
142
    wire MIE_CLEAR;
143
    wire MIE_SET;
144
    wire MIE;
145
    wire MEIE_OUT;
146
    wire MTIE_OUT;
147
    wire MSIE_OUT;
148
    wire MEIP_OUT;
149
    wire MTIP_OUT;
150
    wire MSIP_OUT;
151
    wire FLUSH;
152
    wire [31:0] LU_OUTPUT;
153
    wire [31:0] ALU_RESULT;
154
    reg [31:0] WB_MUX_OUT;
155
    wire [31:0] SU_DATA_OUT;
156
    wire [31:0] SU_D_ADDR;
157
    wire [3:0] SU_WR_MASK;
158
    wire SU_WR_REQ;
159
    wire TRAP_TAKEN;
160
    wire MISALIGNED_EXCEPTION;
161
 
162
    // ---------------------------------
163
    // PIPELINE STAGE 1
164
    // ---------------------------------
165
 
166
    // PC MUX
167
 
168
    reg [31:0] PC_MUX_OUT;
169
    always @*
170
    begin
171
        case (PC_SRC)
172
            `PC_BOOT:      PC_MUX_OUT = BOOT_ADDRESS;
173
            `PC_EPC:       PC_MUX_OUT = EPC;
174
            `PC_TRAP:      PC_MUX_OUT = TRAP_ADDRESS;
175
            `PC_NEXT:      PC_MUX_OUT = NEXT_PC;
176
        endcase
177
    end
178
 
179
    // PC Adder and Multiplexer
180
    assign PC_PLUS_4 = PC + 32'h00000004;
181
    assign NEXT_PC = BRANCH_TAKEN ? {IADDER_OUT[31:1], 1'b0} : PC_PLUS_4;
182
 
183
    // Program Counter (PC) register
184
    always @(posedge CLK)
185
    begin
186
        if(RESET) PC <= BOOT_ADDRESS;
187
        else PC <= PC_MUX_OUT;
188
    end
189
 
190
    // ---------------------------------
191
    // PIPELINE STAGE 2
192
    // ---------------------------------       
193
 
194
    wire [31:0] INSTR_mux;
195
    assign INSTR_mux = FLUSH == 1'b1 ? 32'h00000013 : INSTR;
196
 
197
    assign OPCODE = INSTR_mux[6:0];
198
    assign FUNCT3 = INSTR_mux[14:12];
199
    assign FUNCT7 = INSTR_mux[31:25];
200
 
201
    store_unit su(
202
 
203
        .FUNCT3(FUNCT3[1:0]),
204
        .IADDER_OUT(IADDER_OUT),
205
        .RS2(RS2),
206
        .MEM_WR_REQ(MEM_WR_REQ),
207
 
208
        .DATA_OUT(SU_DATA_OUT),
209
        .D_ADDR(SU_D_ADDR),
210
        .WR_MASK(SU_WR_MASK),
211
        .WR_REQ(SU_WR_REQ)
212
 
213
    );
214
 
215
    decoder dec(
216
 
217
        .OPCODE(OPCODE),
218
        .FUNCT7_5(FUNCT7[5]),
219
        .FUNCT3(FUNCT3),
220
        .IADDER_OUT_1_TO_0(IADDER_OUT[1:0]),
221
        .TRAP_TAKEN(TRAP_TAKEN),
222
 
223
        .ALU_OPCODE(ALU_OPCODE),
224
        .MEM_WR_REQ(MEM_WR_REQ),
225
        .LOAD_SIZE(LOAD_SIZE),
226
        .LOAD_UNSIGNED(LOAD_UNSIGNED),
227
        .ALU_SRC(ALU_SRC),
228
        .IADDER_SRC(IADDER_SRC),
229
        .CSR_WR_EN(CSR_WR_EN),
230
        .RF_WR_EN(RF_WR_EN),
231
        .WB_MUX_SEL(WB_MUX_SEL),
232
        .IMM_TYPE(IMM_TYPE),
233
        .CSR_OP(CSR_OP),
234
        .ILLEGAL_INSTR(ILLEGAL_INSTR),
235
        .MISALIGNED_LOAD(MISALIGNED_LOAD),
236
        .MISALIGNED_STORE(MISALIGNED_STORE)
237
 
238
    );
239
 
240
    imm_generator immgen(
241
 
242
        .INSTR(INSTR_mux[31:7]),
243
        .IMM_TYPE(IMM_TYPE),
244
        .IMM(IMM)
245
 
246
    );
247
 
248
    // Immediate Adder
249
    wire [31:0] iadder_mux_out;
250
    assign iadder_mux_out = IADDER_SRC == 1'b1 ? RS1 : PC;
251
    assign IADDER_OUT = iadder_mux_out + IMM;
252
 
253
    branch_unit bunit(
254
 
255
        .OPCODE_6_TO_2(OPCODE[6:2]),
256
        .FUNCT3(FUNCT3),
257
        .RS1(RS1),
258
        .RS2(RS2),
259
        .BRANCH_TAKEN(BRANCH_TAKEN)
260
 
261
    );
262
 
263
    assign RS1_ADDR = INSTR_mux[19:15];
264
    assign RS2_ADDR = INSTR_mux[24:20];
265
    assign RD_ADDR = INSTR_mux[11:7];
266
 
267
    integer_file irf(
268
 
269
        .CLK(CLK),
270
 
271
        .RS_1_ADDR(RS1_ADDR),
272
        .RS_2_ADDR(RS2_ADDR),
273
        .RS_1(RS1),
274
        .RS_2(RS2),
275
 
276
        .RD_ADDR(RD_ADDR_reg),
277
        .WR_EN(FLUSH ? 1'b0 : RF_WR_EN_reg),
278
        .RD(WB_MUX_OUT)
279
 
280
    );
281
 
282
    assign CSR_ADDR = INSTR_mux[31:20];
283
 
284
    csr_file csrf(
285
 
286
        .CLK(CLK),
287
        .RESET(RESET),
288
 
289
        .WR_EN(FLUSH ? 1'b0 : CSR_WR_EN_reg),
290
        .CSR_ADDR(CSR_ADDR_reg),
291
        .CSR_OP(CSR_OP_reg),
292
        .CSR_UIMM(IMM_reg[4:0]),
293
        .CSR_DATA_IN(RS1_reg),
294
        .CSR_DATA_OUT(CSR_DATA),
295
 
296
        .PC(PC_reg),
297
        .IADDER_OUT(IADDER_OUT_reg),
298
 
299
        .E_IRQ(E_IRQ),
300
        .T_IRQ(T_IRQ),
301
        .S_IRQ(S_IRQ),
302
 
303
        .I_OR_E(I_OR_E),
304
        .SET_CAUSE(SET_CAUSE),
305
        .CAUSE_IN(CAUSE_IN),
306
        .SET_EPC(SET_EPC),
307
        .INSTRET_INC(INSTRET_INC),
308
        .MIE_CLEAR(MIE_CLEAR),
309
        .MIE_SET(MIE_SET),
310
        .MISALIGNED_EXCEPTION(MISALIGNED_EXCEPTION),
311
        .MIE(MIE),
312
        .MEIE_OUT(MEIE_OUT),
313
        .MTIE_OUT(MTIE_OUT),
314
        .MSIE_OUT(MSIE_OUT),
315
        .MEIP_OUT(MEIP_OUT),
316
        .MTIP_OUT(MTIP_OUT),
317
        .MSIP_OUT(MSIP_OUT),
318
 
319
        .REAL_TIME(REAL_TIME),
320
 
321
        .EPC_OUT(EPC),
322
        .TRAP_ADDRESS(TRAP_ADDRESS)
323
 
324
    );
325
 
326
    machine_control mc(
327
 
328
        .CLK(CLK),
329
        .RESET(RESET),
330
 
331
        .ILLEGAL_INSTR(ILLEGAL_INSTR),
332
        .MISALIGNED_INSTR(BRANCH_TAKEN & NEXT_PC[1]),
333
        .MISALIGNED_LOAD(MISALIGNED_LOAD),
334
        .MISALIGNED_STORE(MISALIGNED_STORE),
335
 
336
        .OPCODE_6_TO_2(OPCODE[6:2]),
337
        .FUNCT3(FUNCT3),
338
        .FUNCT7(FUNCT7),
339
        .RS1_ADDR(RS1_ADDR),
340
        .RS2_ADDR(RS2_ADDR),
341
        .RD_ADDR(RD_ADDR),
342
 
343
        .E_IRQ(E_IRQ),
344
        .T_IRQ(T_IRQ),
345
        .S_IRQ(S_IRQ),
346
 
347
        .I_OR_E(I_OR_E),
348
        .SET_CAUSE(SET_CAUSE),
349
        .CAUSE(CAUSE_IN),
350
        .SET_EPC(SET_EPC),
351
        .INSTRET_INC(INSTRET_INC),
352
        .MIE_CLEAR(MIE_CLEAR),
353
        .MIE_SET(MIE_SET),
354
        .MISALIGNED_EXCEPTION(MISALIGNED_EXCEPTION),
355
        .MIE(MIE),
356
        .MEIE(MEIE_OUT),
357
        .MTIE(MTIE_OUT),
358
        .MSIE(MSIE_OUT),
359
        .MEIP(MEIP_OUT),
360
        .MTIP(MTIP_OUT),
361
        .MSIP(MSIP_OUT),
362
 
363
        .PC_SRC(PC_SRC),
364
 
365
        .FLUSH(FLUSH),
366
 
367
        .TRAP_TAKEN(TRAP_TAKEN)
368
 
369
    );
370
 
371
    // Stages 1/2 interface registers
372
    always @(posedge CLK)
373
    begin
374
        if(RESET)
375
        begin
376
            RD_ADDR_reg <= 5'b00000;
377
            CSR_ADDR_reg <= 12'b000000000000;
378
            RS1_reg <= 32'h00000000;
379
            RS2_reg <= 32'h00000000;
380
            PC_reg <= BOOT_ADDRESS;
381
            PC_PLUS_4_reg <= 32'h00000000;
382
            IADDER_OUT_reg <= 32'h00000000;
383
            ALU_OPCODE_reg <= 4'b0000;
384
            LOAD_SIZE_reg <= 2'b00;
385
            LOAD_UNSIGNED_reg <= 1'b0;
386
            ALU_SRC_reg <= 1'b0;
387
            CSR_WR_EN_reg <= 1'b0;
388
            RF_WR_EN_reg <= 1'b0;
389
            WB_MUX_SEL_reg <= `WB_ALU;
390
            CSR_OP_reg <= 3'b000;
391
            IMM_reg <= 32'h00000000;
392
        end
393
        else
394
        begin
395
            RD_ADDR_reg <= RD_ADDR;
396
            CSR_ADDR_reg <= CSR_ADDR;
397
            RS1_reg <= RS1;
398
            RS2_reg <= RS2;
399
            PC_reg <= PC;
400
            PC_PLUS_4_reg <= PC_PLUS_4;
401
            IADDER_OUT_reg[31:1] <= IADDER_OUT[31:1];
402
            IADDER_OUT_reg[0] <= BRANCH_TAKEN ? 1'b0 : IADDER_OUT[0];
403
            ALU_OPCODE_reg <= ALU_OPCODE;
404
            LOAD_SIZE_reg <= LOAD_SIZE;
405
            LOAD_UNSIGNED_reg <= LOAD_UNSIGNED;
406
            ALU_SRC_reg <= ALU_SRC;
407
            CSR_WR_EN_reg <= CSR_WR_EN;
408
            RF_WR_EN_reg <= RF_WR_EN;
409
            WB_MUX_SEL_reg <= WB_MUX_SEL;
410
            CSR_OP_reg <= CSR_OP;
411
            IMM_reg <= IMM;
412
        end
413
    end
414
 
415
    // ---------------------------------
416
    // PIPELINE STAGE 3
417
    // ---------------------------------
418
 
419
    load_unit lu(
420
 
421
        .LOAD_SIZE(LOAD_SIZE_reg),
422
        .LOAD_UNSIGNED(LOAD_UNSIGNED_reg),
423
        .DATA_IN(DATA_IN),
424
        .IADDER_OUT_1_TO_0(IADDER_OUT_reg[1:0]),
425
        .OUTPUT(LU_OUTPUT)
426
 
427
    );
428
 
429
    wire [31:0] alu_2nd_src_mux;
430
    assign alu_2nd_src_mux = ALU_SRC_reg ? RS2_reg : IMM_reg;
431
 
432
    alu alu(
433
 
434
        .OP_1(RS1_reg),
435
        .OP_2(alu_2nd_src_mux),
436
        .OPCODE(ALU_OPCODE_reg),
437
        .RESULT(ALU_RESULT)
438
 
439
    );
440
 
441
    always @*
442
    begin
443
        case (WB_MUX_SEL_reg)
444
            `WB_ALU:        WB_MUX_OUT = ALU_RESULT;
445
            `WB_LU:         WB_MUX_OUT = LU_OUTPUT;
446
            `WB_IMM:        WB_MUX_OUT = IMM_reg;
447
            `WB_IADDER_OUT: WB_MUX_OUT = IADDER_OUT_reg;
448
            `WB_CSR:        WB_MUX_OUT = CSR_DATA;
449
            `WB_PC_PLUS:    WB_MUX_OUT = PC_PLUS_4_reg;
450
            default:        WB_MUX_OUT = ALU_RESULT;
451
        endcase
452
    end
453
 
454
    // ---------------------------------
455
    // OUTPUT ASSIGNMENTS
456
    // ---------------------------------
457
 
458
    assign I_ADDR = RESET ? BOOT_ADDRESS : PC_MUX_OUT;
459
    assign WR_REQ = SU_WR_REQ;
460
    assign WR_MASK = SU_WR_MASK;
461
    assign D_ADDR = SU_D_ADDR;
462
    assign DATA_OUT = SU_DATA_OUT;
463
 
464
endmodule

powered by: WebSVN 2.1.0

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