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  popc.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
40/*
41 * Test bench
42 */
43
44SC_MODULE( proc1 )
45{
46  SC_HAS_PROCESS( proc1 );
47
48  sc_in_clk clk;
49
50  // Inputs
51  sc_in<bool> data_ack;
52  sc_in<int>  popc;
53  // Outputs
54  sc_out<bool> reset;
55  sc_out<bool> data_ready;
56  sc_out<int>  in;
57
58  // Constructor
59  proc1( sc_module_name NAME,
60	 sc_clock& CLK,
61	 sc_signal<bool>& DATA_ACK,
62         sc_signal<int>& POPC,
63         sc_signal<bool>& RESET,
64	 sc_signal<bool>& DATA_READY,
65         sc_signal<int>& IN_ )
66  {
67    clk(CLK);
68    data_ack(DATA_ACK); popc(POPC);
69    reset(RESET); data_ready(DATA_READY); in(IN_);
70	SC_CTHREAD( entry, clk.pos() );
71  }
72
73  // Process functionality goes here
74  void entry();
75};
76
77/*
78 * popc - The process doing the population count
79 *
80 */
81
82SC_MODULE( proc2 )
83{
84  SC_HAS_PROCESS( proc2 );
85
86  sc_in_clk clk;
87
88  // Inputs
89  sc_in<bool> reset;
90  sc_in<bool> data_ready;
91  sc_in<int>  in;
92  // Outputs
93  sc_out<bool> data_ack;
94  sc_out<int>  popc;
95
96  // Internal variables
97  int c;
98  int t;
99  int no;
100
101  proc2( sc_module_name NAME,
102	 sc_clock& CLK,
103         sc_signal<bool>& RESET,
104	 sc_signal<bool>& DATA_READY,
105         sc_signal<int>& IN_,
106	 sc_signal<bool>& DATA_ACK,
107         sc_signal<int>& POPC )
108  {
109    clk(CLK);
110    reset(RESET);
111    data_ready(DATA_READY);
112    in(IN_);
113    data_ack(DATA_ACK);
114    popc(POPC);
115    SC_CTHREAD( entry, clk.pos() );
116    reset_signal_is(reset,true);
117    c = 0;
118    t = 0;
119  }
120
121  // Process functionality
122  void entry();
123};
124
125
126/*
127 * Testbench functionality
128 */
129
130void proc1::entry()
131{
132    int i;
133    int j;
134
135    j = 1;
136    i = 0;
137    data_ready.write(false);
138    reset.write(false);
139
140    wait();
141
142    while(true){
143	in.write(j);
144
145        data_ready.write(true);
146        do { wait(); } while (data_ack == false);
147        data_ready.write(false);
148        do { wait(); } while (data_ack == true);
149
150        char buf[BUFSIZ];
151        sprintf( buf, "Input: %7d   Population Count: %3d", j, popc.read() );
152        cout << buf << endl;
153
154	i++;
155
156	if( i == 3){
157		reset.write(true);
158		wait();
159		reset.write(false);
160		wait(2);
161	}
162
163	if( i == 16)
164	    sc_stop();
165
166	j = (j<<1)|1;
167    }
168}
169
170
171/*
172 * popc - functionality
173 */
174
175void proc2::entry()
176{
177    // Reset behavior
178    no = 0;
179    data_ack.write(false);
180
181    wait();
182
183    while (true) {
184        do { wait(); } while (data_ready == false);
185
186	t = in.read();
187	c = 0;
188	while( t ){
189	    c++;
190	    t &= (t-1);
191	    wait();
192	}
193
194	no++;
195        popc.write(c);
196
197        data_ack.write(true);
198        do { wait(); } while (data_ready == true);
199        data_ack.write(false);
200    }
201}
202
203
204int
205sc_main(int argc, char *argv[])
206{
207  sc_signal<bool>  data_ready("Ready");
208  sc_signal<bool>  data_ack("Ack");
209  sc_signal<int>   in;
210  sc_signal<int>   popc;
211  sc_signal<bool>  reset;
212
213  sc_clock clock("CLOCK", 10, SC_NS, 0.5, 0.0, SC_NS);
214
215  proc1 TestBench("TestBench", clock, data_ack, popc, reset, data_ready, in);
216  proc2 Popc("Popc", clock, reset, data_ready, in,  data_ack, popc);
217
218
219  // Create trace file
220  sc_trace_file *tf = sc_create_vcd_trace_file("tracefile");
221  // Trace signals
222  sc_trace(tf, data_ready, "data_ready");
223  sc_trace(tf, data_ack, "data_ack");
224  sc_trace(tf, in, "in");
225  sc_trace(tf, popc, "popc");
226  sc_trace(tf, reset, "reset");
227  // sc_trace(tf, clock.signal(), "Clock");
228  sc_trace(tf, clock, "Clock");
229  // Trace internal variables
230  sc_trace(tf, Popc.t, "Popc.t");
231  sc_trace(tf, Popc.c, "Popc.c");
232  sc_trace(tf, Popc.no, "Popc.no");
233
234  sc_start();
235  return 0;
236}
237
238