pixelpump.hh revision 11012
13536Sgblack@eecs.umich.edu/*
23536Sgblack@eecs.umich.edu * Copyright (c) 2015 ARM Limited
33536Sgblack@eecs.umich.edu * All rights reserved
43536Sgblack@eecs.umich.edu *
53536Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
63536Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
73536Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
83536Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
93536Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
103536Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
113536Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
123536Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
133536Sgblack@eecs.umich.edu *
143536Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
153536Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
163536Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
173536Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
183536Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
193536Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
203536Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
213536Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
223536Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
233536Sgblack@eecs.umich.edu * this software without specific prior written permission.
243536Sgblack@eecs.umich.edu *
253536Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
263536Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
273536Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
283536Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
293536Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
303536Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
313536Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
323536Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
335543Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
343536Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
353536Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
363536Sgblack@eecs.umich.edu *
373536Sgblack@eecs.umich.edu * Authors: Andreas Sandberg
383536Sgblack@eecs.umich.edu */
393536Sgblack@eecs.umich.edu
403536Sgblack@eecs.umich.edu#ifndef __DEV_PIXELPUMP_HH__
415543Ssaidi@eecs.umich.edu#define __DEV_PIXELPUMP_HH__
425543Ssaidi@eecs.umich.edu
433536Sgblack@eecs.umich.edu#include "base/framebuffer.hh"
443536Sgblack@eecs.umich.edu#include "sim/clocked_object.hh"
453536Sgblack@eecs.umich.edu
463536Sgblack@eecs.umich.edustruct BasePixelPumpParams;
473536Sgblack@eecs.umich.edu
483536Sgblack@eecs.umich.edustruct DisplayTimings : public Serializable
493536Sgblack@eecs.umich.edu{
503536Sgblack@eecs.umich.edu    /**
513536Sgblack@eecs.umich.edu     * Create a display timing configuration struct
523536Sgblack@eecs.umich.edu     *
533536Sgblack@eecs.umich.edu     * @param width Width of the visible area of the screen.
545543Ssaidi@eecs.umich.edu     * @param height Height of the visible area of the screen.
555543Ssaidi@eecs.umich.edu     * @param hfp Horizontal front porch in pixel clocks.
563536Sgblack@eecs.umich.edu     * @param h_sync Horizontal sync in pixel clocks.
573536Sgblack@eecs.umich.edu     * @param hbp Horizontal back porch in pixel clocks.
583536Sgblack@eecs.umich.edu     * @param vfp Vertical front porch in scan lines.
593536Sgblack@eecs.umich.edu     * @param v_sync Vertical sync in scan lines.
603536Sgblack@eecs.umich.edu     * @param vbp Vertical back porch in scan lines.
613536Sgblack@eecs.umich.edu     */
623536Sgblack@eecs.umich.edu    DisplayTimings(unsigned width, unsigned height,
633536Sgblack@eecs.umich.edu                   unsigned hbp, unsigned h_sync, unsigned hfp,
643536Sgblack@eecs.umich.edu                   unsigned vbp, unsigned v_sync, unsigned vfp);
653536Sgblack@eecs.umich.edu
663536Sgblack@eecs.umich.edu    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
673536Sgblack@eecs.umich.edu    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
683536Sgblack@eecs.umich.edu
693536Sgblack@eecs.umich.edu    /** How many pixel clocks are required for one line? */
703536Sgblack@eecs.umich.edu    Cycles cyclesPerLine() const {
713536Sgblack@eecs.umich.edu        return Cycles(hSync + hBackPorch +  width + hBackPorch);
725543Ssaidi@eecs.umich.edu    }
733536Sgblack@eecs.umich.edu
743536Sgblack@eecs.umich.edu    /** How many pixel clocks are required for one frame? */
753536Sgblack@eecs.umich.edu    Cycles cyclesPerFrame() const {
763536Sgblack@eecs.umich.edu        return Cycles(cyclesPerLine() * linesPerFrame());
773536Sgblack@eecs.umich.edu    }
783536Sgblack@eecs.umich.edu
793536Sgblack@eecs.umich.edu    /** Calculate the first line of the vsync signal */
803536Sgblack@eecs.umich.edu    unsigned lineVSyncStart() const {
813536Sgblack@eecs.umich.edu        return 0;
823536Sgblack@eecs.umich.edu    }
833536Sgblack@eecs.umich.edu
843536Sgblack@eecs.umich.edu    /** Calculate the first line of the vertical back porch */
853536Sgblack@eecs.umich.edu    unsigned lineVBackPorchStart() const {
863536Sgblack@eecs.umich.edu        return lineVSyncStart() + vSync;
873536Sgblack@eecs.umich.edu    }
883536Sgblack@eecs.umich.edu
893536Sgblack@eecs.umich.edu    /** Calculate the first line of the visible region */
903536Sgblack@eecs.umich.edu    unsigned lineFirstVisible() const {
913536Sgblack@eecs.umich.edu        return lineVBackPorchStart() + vBackPorch;
925543Ssaidi@eecs.umich.edu    }
935543Ssaidi@eecs.umich.edu
943536Sgblack@eecs.umich.edu    /** Calculate the first line of the back porch */
953536Sgblack@eecs.umich.edu    unsigned lineFrontPorchStart() const {
963536Sgblack@eecs.umich.edu        return lineFirstVisible() + height;
973536Sgblack@eecs.umich.edu    }
983536Sgblack@eecs.umich.edu
993536Sgblack@eecs.umich.edu    /** Calculate the total number of lines in a frame */
1003536Sgblack@eecs.umich.edu    unsigned linesPerFrame() const {
1013536Sgblack@eecs.umich.edu        return lineFrontPorchStart() + vFrontPorch;
1023536Sgblack@eecs.umich.edu    }
1033536Sgblack@eecs.umich.edu
1043536Sgblack@eecs.umich.edu    /** Display width in pixels */
1053536Sgblack@eecs.umich.edu    unsigned width;
1063536Sgblack@eecs.umich.edu    /** Display height in pixels */
1073536Sgblack@eecs.umich.edu    unsigned height;
1083536Sgblack@eecs.umich.edu
1093536Sgblack@eecs.umich.edu    /** Horizontal back porch in pixels */
1103536Sgblack@eecs.umich.edu    unsigned hBackPorch;
1113536Sgblack@eecs.umich.edu    /** Horizontal front porch in pixels */
1123536Sgblack@eecs.umich.edu    unsigned hFrontPorch;
1133536Sgblack@eecs.umich.edu    /** Horizontal sync signal length in pixels */
1143536Sgblack@eecs.umich.edu    unsigned hSync;
1153536Sgblack@eecs.umich.edu
1163536Sgblack@eecs.umich.edu    /** Vertical back porch in lines */
1173536Sgblack@eecs.umich.edu    unsigned vBackPorch;
1183536Sgblack@eecs.umich.edu    /** Vertical front porch in lines */
1193536Sgblack@eecs.umich.edu    unsigned vFrontPorch;
1203536Sgblack@eecs.umich.edu    /** Vertical sync signal in lines */
1213536Sgblack@eecs.umich.edu    unsigned vSync;
1223536Sgblack@eecs.umich.edu
1233536Sgblack@eecs.umich.edu    static const DisplayTimings vga;
1243536Sgblack@eecs.umich.edu};
1253536Sgblack@eecs.umich.edu
1263536Sgblack@eecs.umich.edu/**
1273536Sgblack@eecs.umich.edu * Timing generator for a pixel-based display.
1283536Sgblack@eecs.umich.edu *
1293536Sgblack@eecs.umich.edu * Pixels are ordered relative to the top left corner of the
1303536Sgblack@eecs.umich.edu * display. Scan lines appear in the following order:
1313536Sgblack@eecs.umich.edu * <ol>
1323536Sgblack@eecs.umich.edu *   <li>Vertical Sync (starting at line 0)
1335107Sgblack@eecs.umich.edu *   <li>Vertical back porch
1343536Sgblack@eecs.umich.edu *   <li>Visible lines
1353536Sgblack@eecs.umich.edu *   <li>Vertical front porch
1367678Sgblack@eecs.umich.edu * </ol>
1375107Sgblack@eecs.umich.edu *
1383536Sgblack@eecs.umich.edu * Pixel order within a scan line:
1393536Sgblack@eecs.umich.edu * <ol>
1403536Sgblack@eecs.umich.edu *   <li>Horizontal Sync
1415567Snate@binkert.org *   <li>Horizontal Back Porch
1423536Sgblack@eecs.umich.edu *   <li>Visible pixels
1433550Sgblack@eecs.umich.edu *   <li>Horizontal Front Porch
1444060Ssaidi@eecs.umich.edu * </ol>
1453536Sgblack@eecs.umich.edu */
1463536Sgblack@eecs.umich.educlass BasePixelPump
1473536Sgblack@eecs.umich.edu    : public EventManager, public Clocked,
1483536Sgblack@eecs.umich.edu      public Serializable
1493536Sgblack@eecs.umich.edu{
1505543Ssaidi@eecs.umich.edu  public:
1513536Sgblack@eecs.umich.edu    BasePixelPump(EventManager &em, ClockDomain &pxl_clk, unsigned pixel_chunk);
1523536Sgblack@eecs.umich.edu    virtual ~BasePixelPump();
1533536Sgblack@eecs.umich.edu
1543536Sgblack@eecs.umich.edu    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
1553571Sgblack@eecs.umich.edu    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
1565107Sgblack@eecs.umich.edu
1573571Sgblack@eecs.umich.edu  public: // Public API
1585107Sgblack@eecs.umich.edu    /** Starting pushing pixels using the supplied display timings. */
1594070Ssaidi@eecs.umich.edu    void start(const DisplayTimings &timings);
1604070Ssaidi@eecs.umich.edu
1614070Ssaidi@eecs.umich.edu    /** Immediately stop pushing pixels */
1625107Sgblack@eecs.umich.edu    void stop();
1635107Sgblack@eecs.umich.edu
1645107Sgblack@eecs.umich.edu    /** Get a constant reference of the current display timings */
1655107Sgblack@eecs.umich.edu    const DisplayTimings &timings() const { return _timings; }
1665107Sgblack@eecs.umich.edu
1675107Sgblack@eecs.umich.edu    /** Is the pixel pump active and refreshing the display? */
1685107Sgblack@eecs.umich.edu    bool active() const { return evBeginLine.active(); }
1695107Sgblack@eecs.umich.edu
1703536Sgblack@eecs.umich.edu    /** Did a buffer underrun occur within this refresh interval? */
1713536Sgblack@eecs.umich.edu    bool underrun() const { return _underrun; }
1723536Sgblack@eecs.umich.edu
1733536Sgblack@eecs.umich.edu    /** Is the current line within the visible range? */
1743536Sgblack@eecs.umich.edu    bool visibleLine() const {
1755543Ssaidi@eecs.umich.edu        return line >= _timings.lineFirstVisible() &&
1765543Ssaidi@eecs.umich.edu            line < _timings.lineFrontPorchStart();
1773536Sgblack@eecs.umich.edu    }
1783536Sgblack@eecs.umich.edu
1793536Sgblack@eecs.umich.edu    /** Current pixel position within the visible area */
1803536Sgblack@eecs.umich.edu    unsigned posX() const { return _posX; }
1813536Sgblack@eecs.umich.edu
1827720Sgblack@eecs.umich.edu    /** Current pixel position within the visible area */
1837720Sgblack@eecs.umich.edu    unsigned posY() const {
1844172Ssaidi@eecs.umich.edu        return visibleLine() ? line - _timings.lineFirstVisible() : 0;
1854070Ssaidi@eecs.umich.edu    }
1864070Ssaidi@eecs.umich.edu
1874070Ssaidi@eecs.umich.edu    /** Output frame buffer */
1887720Sgblack@eecs.umich.edu    FrameBuffer fb;
1897720Sgblack@eecs.umich.edu
1904070Ssaidi@eecs.umich.edu  protected: // Callbacks
1914070Ssaidi@eecs.umich.edu    /**
1924060Ssaidi@eecs.umich.edu     * Get the next pixel from the scan line buffer.
1934070Ssaidi@eecs.umich.edu     *
1944172Ssaidi@eecs.umich.edu     * @param p Output pixel value, undefined on underrun
1954172Ssaidi@eecs.umich.edu     * @return true on success, false on buffer underrun
1964070Ssaidi@eecs.umich.edu     */
1974070Ssaidi@eecs.umich.edu    virtual bool nextPixel(Pixel &p) = 0;
1987720Sgblack@eecs.umich.edu
1997720Sgblack@eecs.umich.edu    /** First pixel clock of the first VSync line. */
2004070Ssaidi@eecs.umich.edu    virtual void onVSyncBegin() {};
2014070Ssaidi@eecs.umich.edu
2024060Ssaidi@eecs.umich.edu    /**
2034172Ssaidi@eecs.umich.edu     * Callback on the first pixel of the line after the end VSync
2044172Ssaidi@eecs.umich.edu     * region (typically the first pixel of the vertical back porch).
2054070Ssaidi@eecs.umich.edu     */
2064070Ssaidi@eecs.umich.edu    virtual void onVSyncEnd() {};
2074172Ssaidi@eecs.umich.edu
2084172Ssaidi@eecs.umich.edu    /**
2094172Ssaidi@eecs.umich.edu     * Start of the HSync region.
2104070Ssaidi@eecs.umich.edu     *
2114070Ssaidi@eecs.umich.edu     * @note This is called even for scan lines outside of the visible
2124060Ssaidi@eecs.umich.edu     * region.
2134060Ssaidi@eecs.umich.edu     */
2144060Ssaidi@eecs.umich.edu    virtual void onHSyncBegin() {};
2153571Sgblack@eecs.umich.edu
2163571Sgblack@eecs.umich.edu    /**
2173571Sgblack@eecs.umich.edu     * Start of the first pixel after the HSync region.
2183536Sgblack@eecs.umich.edu     *
2193536Sgblack@eecs.umich.edu     * @note This is called even for scan lines outside of the visible
2203536Sgblack@eecs.umich.edu     * region.
2213536Sgblack@eecs.umich.edu     */
2223536Sgblack@eecs.umich.edu    virtual void onHSyncEnd() {};
2235543Ssaidi@eecs.umich.edu
2245543Ssaidi@eecs.umich.edu    /**
2253536Sgblack@eecs.umich.edu     * Buffer underrun occurred on a frame.
2263536Sgblack@eecs.umich.edu     *
2273536Sgblack@eecs.umich.edu     * This method is called once if there is buffer underrun while
2283536Sgblack@eecs.umich.edu     * refreshing the display. The underrun state is reset on the next
2297720Sgblack@eecs.umich.edu     * refresh.
2307720Sgblack@eecs.umich.edu     *
2317720Sgblack@eecs.umich.edu     * @param x Coordinate within the visible region.
2327720Sgblack@eecs.umich.edu     * @param y Coordinate within the visible region.
2337720Sgblack@eecs.umich.edu     */
2347720Sgblack@eecs.umich.edu    virtual void onUnderrun(unsigned x, unsigned y) {};
2357720Sgblack@eecs.umich.edu
2363571Sgblack@eecs.umich.edu    /** Finished displaying the visible region of a frame */
2373550Sgblack@eecs.umich.edu    virtual void onFrameDone() {};
2383571Sgblack@eecs.umich.edu
2393536Sgblack@eecs.umich.edu  private: // Params
2403536Sgblack@eecs.umich.edu    /** Maximum number of pixels to handle per render callback */
2413536Sgblack@eecs.umich.edu    const unsigned pixelChunk;
2423536Sgblack@eecs.umich.edu
2433536Sgblack@eecs.umich.edu  private:
2444060Ssaidi@eecs.umich.edu    /**
2454060Ssaidi@eecs.umich.edu     * Callback helper class with suspend support.
2463536Sgblack@eecs.umich.edu     *
2473536Sgblack@eecs.umich.edu     * Unlike a normal EventWrapper, this class suspends an event on
2483536Sgblack@eecs.umich.edu     * drain() and restarts it at drainResume(). The suspend operation
2493536Sgblack@eecs.umich.edu     * stores the tick relative to curTick() and then deschedules the
2503536Sgblack@eecs.umich.edu     * event. The resume operation schedules the event at curTick()
2517720Sgblack@eecs.umich.edu     * plus the relative tick stored when the event was suspended.
2524060Ssaidi@eecs.umich.edu     */
2533536Sgblack@eecs.umich.edu    class PixelEvent : public Event, public Drainable
254    {
255        typedef void (BasePixelPump::* CallbackType)();
256
257      public:
258        PixelEvent(const char *name, BasePixelPump *parent, CallbackType func);
259
260        DrainState drain() M5_ATTR_OVERRIDE;
261        void drainResume() M5_ATTR_OVERRIDE;
262
263        void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
264        void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
265
266        const std::string name() const M5_ATTR_OVERRIDE { return _name; }
267        void process() M5_ATTR_OVERRIDE {
268            (parent.*func)();
269        }
270
271        bool active() const { return scheduled() || suspended; }
272
273      private:
274        void suspend();
275        void resume();
276
277        const std::string _name;
278        BasePixelPump &parent;
279        const CallbackType func;
280
281        bool suspended;
282        Tick relativeTick;
283    };
284
285    void beginLine();
286    void renderPixels();
287
288    /** Convenience vector when doing operations on all events */
289    std::vector<PixelEvent *> pixelEvents;
290
291    PixelEvent evVSyncBegin;
292    PixelEvent evVSyncEnd;
293    PixelEvent evHSyncBegin;
294    PixelEvent evHSyncEnd;
295    PixelEvent evBeginLine;
296    PixelEvent evRenderPixels;
297
298    DisplayTimings _timings;
299
300    /**
301     * Current line (including back porch, front porch, and vsync)
302     * within a frame.
303     */
304    unsigned line;
305    /** X-coordinate within the visible region of a frame */
306    unsigned _posX;
307
308    /** Did a buffer underrun occur within this refresh interval? */
309    bool _underrun;
310};
311
312#endif // __DEV_PIXELPUMP_HH__
313