pipeline.cc revision 13966:3189413c5894
12SN/A/*
210911Sandreas.sandberg@arm.com * Copyright (c) 2013-2014 ARM Limited
310911Sandreas.sandberg@arm.com * All rights reserved
410911Sandreas.sandberg@arm.com *
510911Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
610911Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
710911Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
810911Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
910911Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1010911Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1110911Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1210911Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1310911Sandreas.sandberg@arm.com *
141762SN/A * Redistribution and use in source and binary forms, with or without
157534Ssteve.reinhardt@amd.com * modification, are permitted provided that the following conditions are
162SN/A * met: redistributions of source code must retain the above copyright
172SN/A * notice, this list of conditions and the following disclaimer;
182SN/A * redistributions in binary form must reproduce the above copyright
192SN/A * notice, this list of conditions and the following disclaimer in the
202SN/A * documentation and/or other materials provided with the distribution;
212SN/A * neither the name of the copyright holders nor the names of its
222SN/A * contributors may be used to endorse or promote products derived from
232SN/A * this software without specific prior written permission.
242SN/A *
252SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362SN/A *
372SN/A * Authors: Andrew Bardsley
382SN/A */
392SN/A
402665Ssaidi@eecs.umich.edu#include "cpu/minor/pipeline.hh"
412665Ssaidi@eecs.umich.edu
422665Ssaidi@eecs.umich.edu#include <algorithm>
432SN/A
442SN/A#include "cpu/minor/decode.hh"
452SN/A#include "cpu/minor/execute.hh"
462SN/A#include "cpu/minor/fetch1.hh"
472SN/A#include "cpu/minor/fetch2.hh"
482SN/A#include "debug/Drain.hh"
492SN/A#include "debug/MinorCPU.hh"
502SN/A#include "debug/MinorTrace.hh"
512SN/A#include "debug/Quiesce.hh"
525491Sgblack@eecs.umich.edu
535491Sgblack@eecs.umich.edunamespace Minor
542SN/A{
555491Sgblack@eecs.umich.edu
562SN/APipeline::Pipeline(MinorCPU &cpu_, MinorCPUParams &params) :
572SN/A    Ticked(cpu_, &(cpu_.BaseCPU::numCycles)),
588737Skoansin.tan@gmail.com    cpu(cpu_),
594762Snate@binkert.org    allow_idling(params.enableIdling),
609342SAndreas.Sandberg@arm.com    f1ToF2(cpu.name() + ".f1ToF2", "lines",
619356Snilay@cs.wisc.edu        params.fetch1ToFetch2ForwardDelay),
6256SN/A    f2ToF1(cpu.name() + ".f2ToF1", "prediction",
632SN/A        params.fetch1ToFetch2BackwardDelay, true),
642797Sktlim@umich.edu    f2ToD(cpu.name() + ".f2ToD", "insts",
652797Sktlim@umich.edu        params.fetch2ToDecodeForwardDelay),
6610023Smatt.horsnell@ARM.com    dToE(cpu.name() + ".dToE", "insts",
679196SAndreas.Sandberg@arm.com        params.decodeToExecuteForwardDelay),
682SN/A    eToF1(cpu.name() + ".eToF1", "branch",
692SN/A        params.executeBranchDelay),
702SN/A    execute(cpu.name() + ".execute", cpu, params,
719196SAndreas.Sandberg@arm.com        dToE.output(), eToF1.input()),
729196SAndreas.Sandberg@arm.com    decode(cpu.name() + ".decode", cpu, params,
739196SAndreas.Sandberg@arm.com        f2ToD.output(), dToE.input(), execute.inputBuffer),
749196SAndreas.Sandberg@arm.com    fetch2(cpu.name() + ".fetch2", cpu, params,
759196SAndreas.Sandberg@arm.com        f1ToF2.output(), eToF1.output(), f2ToF1.input(), f2ToD.input(),
769196SAndreas.Sandberg@arm.com        decode.inputBuffer),
779196SAndreas.Sandberg@arm.com    fetch1(cpu.name() + ".fetch1", cpu, params,
789196SAndreas.Sandberg@arm.com        eToF1.output(), f1ToF2.input(), f2ToF1.output(), fetch2.inputBuffer),
799196SAndreas.Sandberg@arm.com    activityRecorder(cpu.name() + ".activity", Num_StageId,
809196SAndreas.Sandberg@arm.com        /* The max depth of inter-stage FIFOs */
819196SAndreas.Sandberg@arm.com        std::max(params.fetch1ToFetch2ForwardDelay,
829196SAndreas.Sandberg@arm.com        std::max(params.fetch2ToDecodeForwardDelay,
839196SAndreas.Sandberg@arm.com        std::max(params.decodeToExecuteForwardDelay,
849196SAndreas.Sandberg@arm.com        params.executeBranchDelay)))),
859196SAndreas.Sandberg@arm.com    needToSignalDrained(false)
869196SAndreas.Sandberg@arm.com{
879196SAndreas.Sandberg@arm.com    if (params.fetch1ToFetch2ForwardDelay < 1) {
889342SAndreas.Sandberg@arm.com        fatal("%s: fetch1ToFetch2ForwardDelay must be >= 1 (%d)\n",
899196SAndreas.Sandberg@arm.com            cpu.name(), params.fetch1ToFetch2ForwardDelay);
909196SAndreas.Sandberg@arm.com    }
919196SAndreas.Sandberg@arm.com
929196SAndreas.Sandberg@arm.com    if (params.fetch2ToDecodeForwardDelay < 1) {
939196SAndreas.Sandberg@arm.com        fatal("%s: fetch2ToDecodeForwardDelay must be >= 1 (%d)\n",
949196SAndreas.Sandberg@arm.com            cpu.name(), params.fetch2ToDecodeForwardDelay);
959196SAndreas.Sandberg@arm.com    }
962SN/A
979342SAndreas.Sandberg@arm.com    if (params.decodeToExecuteForwardDelay < 1) {
982SN/A        fatal("%s: decodeToExecuteForwardDelay must be >= 1 (%d)\n",
992SN/A            cpu.name(), params.decodeToExecuteForwardDelay);
1002SN/A    }
1012SN/A
1029196SAndreas.Sandberg@arm.com    if (params.executeBranchDelay < 1) {
1032SN/A        fatal("%s: executeBranchDelay must be >= 1\n",
1042SN/A            cpu.name(), params.executeBranchDelay);
10510023Smatt.horsnell@ARM.com    }
10610023Smatt.horsnell@ARM.com}
10710023Smatt.horsnell@ARM.com
1084762Snate@binkert.orgvoid
1099196SAndreas.Sandberg@arm.comPipeline::regStats()
1104762Snate@binkert.org{
1114762Snate@binkert.org    Ticked::regStats();
1122SN/A
1134762Snate@binkert.org    fetch2.regStats();
1144762Snate@binkert.org}
1154762Snate@binkert.org
11610422Sandreas.hansson@arm.comvoid
1172SN/APipeline::minorTrace() const
1185034Smilesck@eecs.umich.edu{
1195034Smilesck@eecs.umich.edu    fetch1.minorTrace();
1201553SN/A    f1ToF2.minorTrace();
121265SN/A    f2ToF1.minorTrace();
1227532Ssteve.reinhardt@amd.com    fetch2.minorTrace();
1237532Ssteve.reinhardt@amd.com    f2ToD.minorTrace();
1247532Ssteve.reinhardt@amd.com    decode.minorTrace();
1257532Ssteve.reinhardt@amd.com    dToE.minorTrace();
1267532Ssteve.reinhardt@amd.com    execute.minorTrace();
1277532Ssteve.reinhardt@amd.com    eToF1.minorTrace();
128465SN/A    activityRecorder.minorTrace();
129465SN/A}
1307532Ssteve.reinhardt@amd.com
1317532Ssteve.reinhardt@amd.comvoid
1327532Ssteve.reinhardt@amd.comPipeline::evaluate()
1337532Ssteve.reinhardt@amd.com{
1347532Ssteve.reinhardt@amd.com    /* Note that it's important to evaluate the stages in order to allow
1357532Ssteve.reinhardt@amd.com     *  'immediate', 0-time-offset TimeBuffer activity to be visible from
1367532Ssteve.reinhardt@amd.com     *  later stages to earlier ones in the same cycle */
1377532Ssteve.reinhardt@amd.com    execute.evaluate();
1389196SAndreas.Sandberg@arm.com    decode.evaluate();
1399196SAndreas.Sandberg@arm.com    fetch2.evaluate();
1407532Ssteve.reinhardt@amd.com    fetch1.evaluate();
14110905Sandreas.sandberg@arm.com
1427532Ssteve.reinhardt@amd.com    if (DTRACE(MinorTrace))
1437532Ssteve.reinhardt@amd.com        minorTrace();
1447532Ssteve.reinhardt@amd.com
1457532Ssteve.reinhardt@amd.com    /* Update the time buffers after the stages */
1467532Ssteve.reinhardt@amd.com    f1ToF2.evaluate();
1477532Ssteve.reinhardt@amd.com    f2ToF1.evaluate();
1487532Ssteve.reinhardt@amd.com    f2ToD.evaluate();
1497532Ssteve.reinhardt@amd.com    dToE.evaluate();
1509196SAndreas.Sandberg@arm.com    eToF1.evaluate();
1519196SAndreas.Sandberg@arm.com
1529196SAndreas.Sandberg@arm.com    /* The activity recorder must be be called after all the stages and
1532SN/A     *  before the idler (which acts on the advice of the activity recorder */
1549196SAndreas.Sandberg@arm.com    activityRecorder.evaluate();
1559196SAndreas.Sandberg@arm.com
1569196SAndreas.Sandberg@arm.com    if (allow_idling) {
1579196SAndreas.Sandberg@arm.com        /* Become idle if we can but are not draining */
158330SN/A        if (!activityRecorder.active() && !needToSignalDrained) {
1592SN/A            DPRINTF(Quiesce, "Suspending as the processor is idle\n");
1607532Ssteve.reinhardt@amd.com            stop();
16110023Smatt.horsnell@ARM.com        }
16210023Smatt.horsnell@ARM.com
16310023Smatt.horsnell@ARM.com        /* Deactivate all stages.  Note that the stages *could*
16410023Smatt.horsnell@ARM.com         *  activate and deactivate themselves but that's fraught
16510023Smatt.horsnell@ARM.com         *  with additional difficulty.
16610023Smatt.horsnell@ARM.com         *  As organised herre */
16710023Smatt.horsnell@ARM.com        activityRecorder.deactivateStage(Pipeline::CPUStageId);
16810023Smatt.horsnell@ARM.com        activityRecorder.deactivateStage(Pipeline::Fetch1StageId);
16910023Smatt.horsnell@ARM.com        activityRecorder.deactivateStage(Pipeline::Fetch2StageId);
17010023Smatt.horsnell@ARM.com        activityRecorder.deactivateStage(Pipeline::DecodeStageId);
17110023Smatt.horsnell@ARM.com        activityRecorder.deactivateStage(Pipeline::ExecuteStageId);
17210023Smatt.horsnell@ARM.com    }
17310023Smatt.horsnell@ARM.com
17410023Smatt.horsnell@ARM.com    if (needToSignalDrained) /* Must be draining */
17510023Smatt.horsnell@ARM.com    {
1767532Ssteve.reinhardt@amd.com        DPRINTF(Drain, "Still draining\n");
1777532Ssteve.reinhardt@amd.com        if (isDrained()) {
1787823Ssteve.reinhardt@amd.com            DPRINTF(Drain, "Signalling end of draining\n");
1797532Ssteve.reinhardt@amd.com            cpu.signalDrainDone();
1807532Ssteve.reinhardt@amd.com            needToSignalDrained = false;
1817492Ssteve.reinhardt@amd.com            stop();
182330SN/A        }
1839196SAndreas.Sandberg@arm.com    }
18410913Sandreas.sandberg@arm.com}
18510913Sandreas.sandberg@arm.com
1869342SAndreas.Sandberg@arm.comMinorCPU::MinorCPUPort &
18710913Sandreas.sandberg@arm.comPipeline::getInstPort()
1889342SAndreas.Sandberg@arm.com{
18910911Sandreas.sandberg@arm.com    return fetch1.getIcachePort();
19010911Sandreas.sandberg@arm.com}
19110911Sandreas.sandberg@arm.com
19210911Sandreas.sandberg@arm.comMinorCPU::MinorCPUPort &
19310911Sandreas.sandberg@arm.comPipeline::getDataPort()
19410911Sandreas.sandberg@arm.com{
19510911Sandreas.sandberg@arm.com    return execute.getDcachePort();
19610911Sandreas.sandberg@arm.com}
19710911Sandreas.sandberg@arm.com
19810911Sandreas.sandberg@arm.comvoid
19910911Sandreas.sandberg@arm.comPipeline::wakeupFetch(ThreadID tid)
20010911Sandreas.sandberg@arm.com{
20110911Sandreas.sandberg@arm.com    fetch1.wakeupFetch(tid);
20210911Sandreas.sandberg@arm.com}
20310911Sandreas.sandberg@arm.com
20410911Sandreas.sandberg@arm.combool
20510911Sandreas.sandberg@arm.comPipeline::drain()
20610911Sandreas.sandberg@arm.com{
20710911Sandreas.sandberg@arm.com    DPRINTF(MinorCPU, "Draining pipeline by halting inst fetches. "
20810911Sandreas.sandberg@arm.com        " Execution should drain naturally\n");
20910911Sandreas.sandberg@arm.com
21010911Sandreas.sandberg@arm.com    execute.drain();
21110905Sandreas.sandberg@arm.com
21210905Sandreas.sandberg@arm.com    /* Make sure that needToSignalDrained isn't accidentally set if we
21310905Sandreas.sandberg@arm.com     *  are 'pre-drained' */
21410905Sandreas.sandberg@arm.com    bool drained = isDrained();
2159342SAndreas.Sandberg@arm.com    needToSignalDrained = !drained;
2169196SAndreas.Sandberg@arm.com
2179196SAndreas.Sandberg@arm.com    return drained;
21810905Sandreas.sandberg@arm.com}
219938SN/A
2201031SN/Avoid
2211031SN/APipeline::drainResume()
2221031SN/A{
2231031SN/A    DPRINTF(Drain, "Drain resume\n");
2241031SN/A
2251031SN/A    for (ThreadID tid = 0; tid < cpu.numThreads; tid++) {
2265314Sstever@gmail.com        fetch1.wakeupFetch(tid);
2275314Sstever@gmail.com    }
2285315Sstever@gmail.com
2295314Sstever@gmail.com    execute.drainResume();
2305314Sstever@gmail.com}
2315314Sstever@gmail.com
2322SN/Abool
2332SN/APipeline::isDrained()
23411067Sandreas.sandberg@arm.com{
23511067Sandreas.sandberg@arm.com    bool fetch1_drained = fetch1.isDrained();
23611067Sandreas.sandberg@arm.com    bool fetch2_drained = fetch2.isDrained();
23711067Sandreas.sandberg@arm.com    bool decode_drained = decode.isDrained();
23811067Sandreas.sandberg@arm.com    bool execute_drained = execute.isDrained();
23911067Sandreas.sandberg@arm.com
24011067Sandreas.sandberg@arm.com    bool f1_to_f2_drained = f1ToF2.empty();
24111067Sandreas.sandberg@arm.com    bool f2_to_f1_drained = f2ToF1.empty();
24211067Sandreas.sandberg@arm.com    bool f2_to_d_drained = f2ToD.empty();
24311067Sandreas.sandberg@arm.com    bool d_to_e_drained = dToE.empty();
24411067Sandreas.sandberg@arm.com
24511067Sandreas.sandberg@arm.com    bool ret = fetch1_drained && fetch2_drained &&
24611067Sandreas.sandberg@arm.com        decode_drained && execute_drained &&
24711067Sandreas.sandberg@arm.com        f1_to_f2_drained && f2_to_f1_drained &&
24811067Sandreas.sandberg@arm.com        f2_to_d_drained && d_to_e_drained;
2499554Sandreas.hansson@arm.com
2509554Sandreas.hansson@arm.com    DPRINTF(MinorCPU, "Pipeline undrained stages state:%s%s%s%s%s%s%s%s\n",
2519554Sandreas.hansson@arm.com        (fetch1_drained ? "" : " Fetch1"),
2529554Sandreas.hansson@arm.com        (fetch2_drained ? "" : " Fetch2"),
2532SN/A        (decode_drained ? "" : " Decode"),
254        (execute_drained ? "" : " Execute"),
255        (f1_to_f2_drained ? "" : " F1->F2"),
256        (f2_to_f1_drained ? "" : " F2->F1"),
257        (f2_to_d_drained ? "" : " F2->D"),
258        (d_to_e_drained ? "" : " D->E")
259        );
260
261    return ret;
262}
263
264}
265