gcd.cpp revision 12855:588919e0e4aa
1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  gcd.cpp --
23
24  Original Author: Martin Janssen, Synopsys, Inc., 2002-02-15
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38#include "systemc.h"
39
40struct gcd_cc : public sc_module {
41    sc_in_clk        clk;
42    sc_in<bool>      reset;
43    sc_in<unsigned>  a;
44    sc_in<unsigned>  b;
45    sc_out<unsigned> c;
46    sc_out<bool>     ready;
47
48    void gcd_compute();
49
50    SC_HAS_PROCESS( gcd_cc );
51
52    gcd_cc( sc_module_name name )
53    {
54        SC_CTHREAD( gcd_compute, clk.pos() );
55        reset_signal_is(reset,true);
56    }
57};
58
59void
60gcd_cc::gcd_compute()
61{
62    unsigned tmp_a = 0;
63    wait();         // Note that this wait() is required, otherwise,
64                    // the reset is wrong!  This is a problem with BC,
65                    // not our frontend.
66
67    while (true) {
68        unsigned tmp_b;
69
70        c = tmp_a;
71        ready = true;
72        wait();
73
74        tmp_a = a;
75        tmp_b = b;
76        ready = false;
77        wait();
78
79        while (tmp_b != 0) {
80
81            unsigned tmp_c = tmp_a;
82            tmp_a = tmp_b;
83            wait();
84
85            while (tmp_c >= tmp_b) {
86                tmp_c = tmp_c - tmp_b;
87                wait();
88            }
89
90            tmp_b = tmp_c;
91            wait();
92        }
93    }
94}
95
96static int numbers[] = { 49597, 41218, 20635, 40894, 16767, 17233, 36246, 28171, 60879, 49566, 10971, 24107, 30561, 49648, 50031, 12559, 23787, 35674, 43320, 37558, 840, 18689, 62466, 6308, 46271, 49801, 43433, 22683, 35494, 35259, 29020, 19555, 10941, 49656, 60450, 27709, 1353, 31160, 55880, 62232, 15190, 1315, 20803, 45751, 50963, 5298, 58311, 9215, 2378 };
97static unsigned numbers_index = 0;
98
99struct testbench : public sc_module {
100    sc_in_clk          clk;
101    sc_inout<bool>     reset;
102    sc_in<bool>        ready;
103    sc_inout<unsigned> a;
104    sc_inout<unsigned> b;
105    sc_in<unsigned>    c;
106
107    void reset_gen();
108    void stimu_gen();
109    void display();
110
111    SC_HAS_PROCESS( testbench );
112
113    testbench( sc_module_name name )
114    {
115        SC_CTHREAD( reset_gen, clk.pos() );
116        SC_CTHREAD( stimu_gen, clk.pos() );
117        SC_METHOD( display );
118        sensitive << ready;
119    }
120};
121
122void
123testbench::reset_gen()
124{
125    reset = 0;
126    wait();
127    reset = 1;
128    wait();
129    wait();
130    reset = 0;
131    wait();
132    /* die */
133}
134
135void
136testbench::stimu_gen()
137{
138    while (true) {
139        do { wait(); } while (ready == 0);
140        a = (unsigned) numbers[numbers_index++ % (sizeof(numbers)/sizeof(numbers[0]))];
141        b = (unsigned) numbers[(numbers_index*numbers_index) % (sizeof(numbers)/sizeof(numbers[0]))];
142        numbers_index++;
143    }
144}
145
146void
147testbench::display()
148{
149    if (ready) {
150        cout << "reset = " << reset << " ready = " << ready
151             << " a = " << a << " b = " << b << " c = " << c << endl;
152    }
153}
154
155int sc_main(int argc, char* argv[] )
156{
157    sc_signal<unsigned> a("a"), b("b"), c("c");
158    sc_clock            clk("clk", 20, SC_NS);
159    sc_signal<bool>     reset("reset"), ready("ready");
160
161    a = 0;
162    b = 0;
163    c = 0;
164    reset = false;
165    ready = false;
166
167    gcd_cc gcd("gcd");
168    gcd(clk, reset, a, b, c, ready);
169
170    testbench tb("tb");
171    tb(clk, reset, ready, a, b, c);
172
173    sc_start(2000000, SC_NS);
174    return 0;
175}
176