/* To use hw_fifo, compile the model with the line below. g++ -DREFINMENT -Wall -O2 -I/Users/zheng/Dropbox/work/sw/systemc-2.3.1/include -L/Users/zheng/Dropbox/work/sw/systemc-2.3.1/lib-macosx64 -o refine refinement.cpp -lsystemc To use sc_fifo, compile the model with the line below. g++ -Wall -O2 -I/Users/zheng/Dropbox/work/sw/systemc-2.3.1/include -L/Users/zheng/Dropbox/work/sw/systemc-2.3.1/lib-macosx64 -o refine refinement.cpp -lsystemc */ #include "systemc.h" #include "ctype.h" /*** HW FIFO implementation ***/ template class hw_fifo : public sc_module { public: sc_in clock; sc_in din; sc_in valid_in; sc_out ready_out; sc_out dout; sc_out valid_out; sc_in ready_in; SC_HAS_PROCESS(hw_fifo); hw_fifo(sc_module_name name, unsigned size) : sc_module(name), _size(size) { assert(size > 0); _first = _items = 0; _data = new T[_size]; SC_METHOD(main); sensitive << clock.pos(); ready_out.initialize(true); valid_out.initialize(false); } ~hw_fifo() { delete _data; } protected: void main() { // write operation if (valid_in.read() && ready_out.read()) { _data[(_first + _items) % _size] = din; _items++; } // read operation if (ready_in.read() && valid_out.read()) { _items--; _first = (_first + 1) % _size; } ready_out = (_items < _size); valid_out = (_items > 0); dout = _data[_first]; } unsigned _size, _first, _items; T* _data; }; /*** hw fifo wrapper ***/ template class hw_fifo_wrapper : public sc_module, public sc_fifo_in_if, public sc_fifo_out_if { public: sc_in clock; protected: sc_signal wr_data; sc_signal wr_valid; sc_signal wr_ready; sc_signal rd_data; sc_signal rd_valid; sc_signal rd_ready; hw_fifo hw_fifo_inst; public: // SC_CTOR(hw_fifo_wrapper) { // unsigned int size = 16; hw_fifo_wrapper(sc_module_name name, unsigned int size) : sc_module(name), hw_fifo_inst("fifo1", size) { hw_fifo_inst.clock(clock); // port binding for hw_fifo_inst hw_fifo_inst.clock(clock); hw_fifo_inst.din(wr_data); hw_fifo_inst.valid_in(wr_valid); hw_fifo_inst.ready_out(wr_ready); hw_fifo_inst.dout(rd_data); hw_fifo_inst.valid_out(rd_valid); hw_fifo_inst.ready_in(rd_ready); } virtual void write(const T& data) { wr_data = data; wr_valid = true; while (wr_ready != true) { wait (clock->posedge_event()); } wr_valid = false; } virtual T read() { rd_ready = true; while (rd_valid != true) { wait (clock->posedge_event()); } rd_ready = false; return rd_data.read(); } virtual void read(T& d) { d = read(); } //Dummy functions sc_event e; virtual bool nb_read(T&) { return false; } virtual bool nb_write(const T&) { return false; } virtual int num_available() const { return 0; } virtual int num_free() const { return 0; } virtual const sc_event& data_read_event() const { return e; } virtual const sc_event& data_written_event() const { return e; } }; /** Producer-consumer model **/ class producer : public sc_module { public: sc_port > dout; SC_CTOR(producer) // module constructor { SC_THREAD(main); // start the process } void main() // the producer process { std::string str = "first systemc code: producer -> consumer\n"; unsigned int i = 0; while (i < str.size()) { char c = str[i]; dout->write(c); i++; } dout->write('\0'); } }; // the consumer module class consumer : public sc_module { public: sc_port > din; SC_CTOR(consumer) // module constructor { SC_THREAD(main); // start the process } void main() // the consumer process { while (1) { char c; din->read(c); cout << c; } } }; // the top module class top : public sc_module { public: producer prod_inst; consumer cons_inst; #ifdef REFINEMENT sc_in clock; hw_fifo_wrapper hw_fifo_inst_1; SC_CTOR(top) : prod_inst("Producer1"), cons_inst("Consumer1"), hw_fifo_inst_1("hw_fifo_inst_1", 16) { hw_fifo_inst_1.clock(clock); prod_inst.dout(hw_fifo_inst_1); cons_inst.din(hw_fifo_inst_1); } #else sc_fifo sc_fifo_inst_1; SC_CTOR(top) : prod_inst("Producer1"), cons_inst("Consumer1") { prod_inst.dout(sc_fifo_inst_1); cons_inst.din(sc_fifo_inst_1); } #endif ~top() {} }; int sc_main(int, char *[]) { #ifdef REFINEMENT cout << "Simulating model using hw_fifo " << endl; top top_inst("top_inst"); sc_clock clock ("my_clock", 1, 0.5); top_inst.clock(clock); #else cout << "Simulating model using sc_fifo " << endl; top top_inst("top_inst"); #endif sc_start(1000, SC_NS); return 0; }