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