random.hh revision 5190:fc46e0d647b6
12686Sksewell@umich.edu/*
22100SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
35254Sksewell@umich.edu * All rights reserved.
45254Sksewell@umich.edu *
55254Sksewell@umich.edu * Redistribution and use in source and binary forms, with or without
65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are
75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright
85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer;
95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright
105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the
115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution;
125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its
135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from
145254Sksewell@umich.edu * this software without specific prior written permission.
155254Sksewell@umich.edu *
165254Sksewell@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275254Sksewell@umich.edu *
285254Sksewell@umich.edu * Authors: Nathan Binkert
295254Sksewell@umich.edu *          Ali Saidi
305254Sksewell@umich.edu */
315254Sksewell@umich.edu
322706Sksewell@umich.edu#ifndef __BASE_RANDOM_HH__
332022SN/A#define __BASE_RANDOM_HH__
342022SN/A
352043SN/A#include <ios>
362024SN/A#include <string>
372024SN/A
382043SN/A#include "base/range.hh"
392686Sksewell@umich.edu#include "sim/host.hh"
404661Sksewell@umich.edu
412022SN/Aclass Checkpoint;
422083SN/A
432686Sksewell@umich.educlass Random
442101SN/A{
452043SN/A  protected:
462043SN/A    static const int N = 624;
472101SN/A    static const int M = 397;
482101SN/A    static const uint32_t MATRIX_A = (uint32_t)0x9908b0df;
496384Sgblack@eecs.umich.edu    static const uint32_t UPPER_MASK = (uint32_t)0x80000000;
506384Sgblack@eecs.umich.edu    static const uint32_t LOWER_MASK = (uint32_t)0x7fffffff;
516384Sgblack@eecs.umich.edu
526384Sgblack@eecs.umich.edu    uint32_t mt[N];
536384Sgblack@eecs.umich.edu    int mti;
546384Sgblack@eecs.umich.edu
552101SN/A    uint32_t genrand();
562101SN/A    uint32_t genrand(uint32_t max);
572101SN/A    uint64_t genrand(uint64_t max);
582046SN/A
592686Sksewell@umich.edu    void
602686Sksewell@umich.edu    _random(int8_t &value)
612686Sksewell@umich.edu    {
622470SN/A        value = genrand() & (int8_t)-1;
632686Sksewell@umich.edu    }
644661Sksewell@umich.edu
655222Sksewell@umich.edu    void
665222Sksewell@umich.edu    _random(int16_t &value)
672686Sksewell@umich.edu    {
682686Sksewell@umich.edu        value = genrand() & (int16_t)-1;
692470SN/A    }
702241SN/A
712101SN/A    void
722495SN/A    _random(int32_t &value)
732495SN/A    {
742495SN/A        value = (int32_t)genrand();
752101SN/A    }
766384Sgblack@eecs.umich.edu
776384Sgblack@eecs.umich.edu    void
786384Sgblack@eecs.umich.edu    _random(int64_t &value)
796384Sgblack@eecs.umich.edu    {
806384Sgblack@eecs.umich.edu        value = (int64_t)genrand() << 32 | (int64_t)genrand();
812495SN/A    }
822101SN/A
832101SN/A    void
842495SN/A    _random(uint8_t &value)
852495SN/A    {
862495SN/A        value = genrand() & (uint8_t)-1;
872495SN/A    }
882495SN/A
892495SN/A    void
902495SN/A    _random(uint16_t &value)
912495SN/A    {
922495SN/A        value = genrand() & (uint16_t)-1;
932495SN/A    }
942495SN/A
952495SN/A    void
962495SN/A    _random(uint32_t &value)
972101SN/A    {
982101SN/A        value = genrand();
992101SN/A    }
1002101SN/A
1012101SN/A    void
1022101SN/A    _random(uint64_t &value)
1036384Sgblack@eecs.umich.edu    {
1046384Sgblack@eecs.umich.edu        value = (uint64_t)genrand() << 32 | (uint64_t)genrand();
1056384Sgblack@eecs.umich.edu    }
1066384Sgblack@eecs.umich.edu
1076384Sgblack@eecs.umich.edu    // [0,1]
1086384Sgblack@eecs.umich.edu    void
1092101SN/A    _random(float &value)
1102101SN/A    {
1112495SN/A        // ieee floats have 23 bits of mantissa
1122495SN/A        value = (genrand() >> 9) / 8388608.0;
1132495SN/A    }
1142495SN/A
1152495SN/A    // [0,1]
1166384Sgblack@eecs.umich.edu    void
1176384Sgblack@eecs.umich.edu    _random(double &value)
1186384Sgblack@eecs.umich.edu    {
1196384Sgblack@eecs.umich.edu        double number = genrand() * 2097152.0 + (genrand() >> 11);
1206384Sgblack@eecs.umich.edu        value = number / 9007199254740992.0;
1212495SN/A    }
1226384Sgblack@eecs.umich.edu
1232495SN/A
1242495SN/A    // Range based versions of the random number generator
1252043SN/A    int8_t
1262043SN/A    _random(int8_t min, int8_t max)
1272025SN/A    {
1282043SN/A        uint32_t diff = max - min;
1292686Sksewell@umich.edu        return static_cast<int8_t>(min + genrand(diff));
1302686Sksewell@umich.edu    }
1312123SN/A
1322101SN/A    int16_t
1336376Sgblack@eecs.umich.edu    _random(int16_t min, int16_t max)
1346376Sgblack@eecs.umich.edu    {
1356376Sgblack@eecs.umich.edu        uint32_t diff = max - min;
1366376Sgblack@eecs.umich.edu        return static_cast<int16_t>(min + genrand(diff));
1376376Sgblack@eecs.umich.edu    }
1386376Sgblack@eecs.umich.edu
1396376Sgblack@eecs.umich.edu    int32_t
1406376Sgblack@eecs.umich.edu    _random(int32_t min, int32_t max)
1416376Sgblack@eecs.umich.edu    {
1426376Sgblack@eecs.umich.edu        uint32_t diff = max - min;
1436376Sgblack@eecs.umich.edu        return static_cast<int32_t>(min + genrand(diff));
1446376Sgblack@eecs.umich.edu    }
1456376Sgblack@eecs.umich.edu
1466376Sgblack@eecs.umich.edu    int64_t
1476376Sgblack@eecs.umich.edu    _random(int64_t min, int64_t max)
1486376Sgblack@eecs.umich.edu    {
1492101SN/A        uint64_t diff = max - min;
1502042SN/A        return static_cast<int64_t>(min + genrand(diff));
1512101SN/A    }
1524661Sksewell@umich.edu
1532686Sksewell@umich.edu    uint8_t
1544661Sksewell@umich.edu    _random(uint8_t min, uint8_t max)
1552101SN/A    {
1562101SN/A        uint32_t diff = max - min;
1572042SN/A        return static_cast<uint8_t>(min + genrand(diff));
1582101SN/A    }
1592686Sksewell@umich.edu
1602686Sksewell@umich.edu    uint16_t
1615222Sksewell@umich.edu    _random(uint16_t min, uint16_t max)
1626384Sgblack@eecs.umich.edu    {
1635222Sksewell@umich.edu        uint32_t diff = max - min;
1642965Sksewell@umich.edu        return static_cast<uint16_t>(min + genrand(diff));
1656037Sksewell@umich.edu    }
1665222Sksewell@umich.edu
1672686Sksewell@umich.edu    uint32_t
1685222Sksewell@umich.edu    _random(uint32_t min, uint32_t max)
1692101SN/A    {
1702083SN/A        uint32_t diff = max - min;
1712043SN/A        return static_cast<uint32_t>(min + genrand(diff));
1722025SN/A    }
1732043SN/A
1746384Sgblack@eecs.umich.edu    uint64_t
1756384Sgblack@eecs.umich.edu    _random(uint64_t min, uint64_t max)
1764661Sksewell@umich.edu    {
1776384Sgblack@eecs.umich.edu        uint64_t diff = max - min;
1786384Sgblack@eecs.umich.edu        return static_cast<uint64_t>(min + genrand(diff));
1794661Sksewell@umich.edu    }
1802083SN/A
1812025SN/A  public:
1822043SN/A    Random();
1834661Sksewell@umich.edu    Random(uint32_t s);
1845222Sksewell@umich.edu    Random(uint32_t init_key[], int key_length);
1855222Sksewell@umich.edu    ~Random();
1864661Sksewell@umich.edu
1874661Sksewell@umich.edu    void init(uint32_t s);
1882686Sksewell@umich.edu    void init(uint32_t init_key[], int key_length);
1896384Sgblack@eecs.umich.edu
1906384Sgblack@eecs.umich.edu    template <typename T>
1916384Sgblack@eecs.umich.edu    T
1926384Sgblack@eecs.umich.edu    random()
1936384Sgblack@eecs.umich.edu    {
1945222Sksewell@umich.edu        T value;
1955222Sksewell@umich.edu        _random(value);
1966384Sgblack@eecs.umich.edu        return value;
1976384Sgblack@eecs.umich.edu    }
1986384Sgblack@eecs.umich.edu
1996384Sgblack@eecs.umich.edu    template <typename T>
2006384Sgblack@eecs.umich.edu    T
2015222Sksewell@umich.edu    random(T min, T max)
2022101SN/A    {
2032084SN/A        return _random(min, max);
2042025SN/A    }
2052495SN/A
2062495SN/A    template <typename T>
2072495SN/A    T
2086384Sgblack@eecs.umich.edu    random(const Range<T> &range)
2096384Sgblack@eecs.umich.edu    {
2106384Sgblack@eecs.umich.edu        return _random(range.start, range.end);
2116384Sgblack@eecs.umich.edu    }
2126384Sgblack@eecs.umich.edu
2136384Sgblack@eecs.umich.edu    // [0,1]
2146384Sgblack@eecs.umich.edu    double
2156384Sgblack@eecs.umich.edu    gen_real1()
2166384Sgblack@eecs.umich.edu    {
2175222Sksewell@umich.edu        return genrand() / 4294967296.0;
2186384Sgblack@eecs.umich.edu    }
2196384Sgblack@eecs.umich.edu
2206384Sgblack@eecs.umich.edu    // [0,1)
2216384Sgblack@eecs.umich.edu    double
2225222Sksewell@umich.edu    gen_real2()
2236384Sgblack@eecs.umich.edu    {
2246384Sgblack@eecs.umich.edu        return genrand() / 4294967295.0;
2256384Sgblack@eecs.umich.edu    }
2266384Sgblack@eecs.umich.edu
2276384Sgblack@eecs.umich.edu    // (0,1)
2285222Sksewell@umich.edu    double
2296384Sgblack@eecs.umich.edu    gen_real3()
2302495SN/A    {
2315222Sksewell@umich.edu        return ((double)genrand() + 0.5) / 4294967296.0;
2326384Sgblack@eecs.umich.edu    }
2336384Sgblack@eecs.umich.edu
2346384Sgblack@eecs.umich.edu  public:
2356384Sgblack@eecs.umich.edu    void serialize(const std::string &base, std::ostream &os);
2366384Sgblack@eecs.umich.edu    void unserialize(const std::string &base, Checkpoint *cp,
2375222Sksewell@umich.edu                     const std::string &section);
2386384Sgblack@eecs.umich.edu};
2396384Sgblack@eecs.umich.edu
2405222Sksewell@umich.eduextern Random random_mt;
2416384Sgblack@eecs.umich.edu
2425222Sksewell@umich.edu#endif // __BASE_RANDOM_HH__
2436384Sgblack@eecs.umich.edu