Advertisement
Guest User

Untitled

a guest
Dec 10th, 2015
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.15 KB | None | 0 0
  1. #include <memory>
  2. #include <boost/format.hpp>
  3. #include <systemc.h>
  4.  
  5. const sc_time clk(1, SC_NS);
  6.  
  7. #define LOG(x) log(x)
  8. #define LOG_M(x) log_module(*this, x)
  9. #define LOG_C(m, x) log_module(m, x)
  10.  
  11. void log(const std::string& s) {
  12.   std::cout << boost::format("[%1%] %2%\n") % sc_time_stamp() % s;
  13. }
  14.  
  15. void log(const boost::format& f) {
  16.   log(boost::str(f));
  17. }
  18.  
  19. template<class Message>
  20. void log_module(const sc_module& module, const Message& s) {
  21.   log(boost::format("<%1%> %2%") % module.name() % s);
  22. }
  23.  
  24. //////
  25. //////
  26. //////
  27.  
  28. struct Flit {
  29.   unsigned tag;
  30.   uint64_t address;
  31.   unsigned length;
  32.   unsigned processing_time;
  33.   sc_time earliest_sending;
  34.  
  35.   Flit()
  36.     : tag(-1)
  37.     , address{0}
  38.     , length{0}
  39.     , processing_time{0}
  40.     , earliest_sending{SC_ZERO_TIME}
  41.   {}
  42.  
  43.   Flit(unsigned tag, uint64_t address, unsigned length, unsigned processing_time)
  44.     : tag{tag}
  45.     , address{address}
  46.     , length{length}
  47.     , processing_time{processing_time}
  48.     , earliest_sending{SC_ZERO_TIME}
  49.   {}
  50.  
  51.   std::string to_str() const {
  52.     return boost::str(boost::format("tag:%1%, addr:%2%, length:%3%, proc_time:%4%")
  53.         % tag
  54.         % address
  55.         % length
  56.         % processing_time
  57.         );
  58.   }
  59.  
  60.   inline friend std::ostream& operator<<(std::ostream& os, const Flit& flit) {
  61.     os << flit.to_str();
  62.     return os;
  63.   }
  64.  
  65.   inline bool operator==(const Flit& flit) const {
  66.     return tag == flit.tag;
  67.   }
  68. };
  69.  
  70. void sc_trace(sc_trace_file*& tf, const Flit& flit, const std::string& name) {
  71.   sc_trace(tf, flit.tag, name + ".tag");
  72.   sc_trace(tf, flit.address, name + ".address");
  73.   sc_trace(tf, flit.length, name + ".length");
  74.   sc_trace(tf, flit.processing_time, name + ".proc_time");
  75. }
  76.  
  77. typedef sc_in<Flit> FlitInPort;
  78. typedef sc_out<Flit> FlitOutPort;
  79. typedef sc_signal<Flit> FlitSignal;
  80.  
  81. typedef sc_in<unsigned> CreditReceivePort;
  82. typedef sc_out<unsigned> CreditReturnPort;
  83. typedef sc_buffer<unsigned> CreditSignal;
  84.  
  85. //////
  86. //////
  87. //////
  88.  
  89. class Source : public sc_module {
  90.   SC_HAS_PROCESS(Source);
  91.  
  92. public:
  93.   FlitOutPort req_out;
  94.  
  95.   Source(const sc_module_name& module_name) {
  96.     SC_THREAD(generate_request);
  97.   }
  98.  
  99. private:
  100.   void generate_request() {
  101.     send_flit(Flit(1, 0, 32, 10));
  102.     wait(11 * clk);
  103.     send_flit(Flit(2, 0, 32, 2));
  104.   }
  105.  
  106.   void send_flit(const Flit& flit) {
  107.     LOG_M(boost::format("Sending %1%") % flit);
  108.     req_out.write(flit);
  109.   }
  110. };
  111.  
  112. class Buffer : public sc_module {
  113.   SC_HAS_PROCESS(Buffer);
  114.  
  115. public:
  116.   FlitInPort req_in;
  117.   FlitOutPort req_out;
  118.   CreditReceivePort cr_rcv;
  119.  
  120.   Buffer(const sc_module_name& module_name) {
  121.     SC_METHOD(receive);
  122.     sensitive << req_in;
  123.     dont_initialize();
  124.  
  125.     SC_METHOD(process_buffer);
  126.     sensitive << process_buffer_event_;
  127.     dont_initialize();
  128.  
  129.     SC_METHOD(receive_credits);
  130.     sensitive << cr_rcv;
  131.     dont_initialize();
  132.   }
  133.  
  134. private:
  135.   std::vector<Flit> buffer_;
  136.   sc_event process_buffer_event_;
  137.   unsigned credits_ { 2 };
  138.  
  139.   void receive() {
  140.     assert(req_in.event());
  141.     auto& flit = req_in.read();
  142.     LOG_M(boost::format("Received %1%") % flit.to_str());
  143.     buffer_.push_back(flit);
  144.     buffer_.back().earliest_sending = sc_time_stamp() + clk;
  145.     process_buffer_event_.notify(clk);
  146.   }
  147.  
  148.   void process_buffer() {
  149.     if (buffer_.empty())
  150.       return;
  151.  
  152.     if (credits_ == 0) {
  153.       LOG_M("No credits!!!");
  154.       return;
  155.     }
  156.  
  157.     auto& flit = buffer_.front();
  158.     LOG_M(boost::format("Sending %1%") % flit.to_str());
  159.     assert(sc_time_stamp() >= flit.earliest_sending);
  160.     req_out.write(flit);
  161.     credits_--;
  162.     buffer_.erase(begin(buffer_));
  163.     if (!buffer_.empty())
  164.       process_buffer_event_.notify(clk);
  165.   }
  166.  
  167.   void receive_credits() {
  168.     assert(cr_rcv.event());
  169.     auto credits = cr_rcv.read();
  170.     assert(credits > 0);
  171.     credits_ += credits;
  172.     LOG_M(boost::format("%1% credits received (total=%2%)") % credits % credits_);
  173.     process_buffer_event_.notify(SC_ZERO_TIME);
  174.   }
  175. };
  176.  
  177. class Sink : public sc_module {
  178.   SC_HAS_PROCESS(Sink);
  179.  
  180. public:
  181.   FlitInPort req_in;
  182.   CreditReturnPort cr_ret;
  183.  
  184.   Sink(const sc_module_name& module_name) {
  185.     SC_METHOD(receive);
  186.     sensitive << req_in;
  187.     dont_initialize();
  188.  
  189.     SC_METHOD(return_credit);
  190.     sensitive << return_credit_event;
  191.     dont_initialize();
  192.   }
  193.  
  194. private:
  195.   sc_event_queue return_credit_event;
  196.  
  197.   void receive() {
  198.     assert(req_in.event());
  199.     auto& flit = req_in.read();
  200.     LOG_M(boost::format("Received %1%)") % flit.to_str());
  201.     return_credit_event.notify(flit.processing_time * clk);
  202.   }
  203.  
  204.   void return_credit() {
  205.     LOG_M("Returning one credit");
  206.     cr_ret.write(1);
  207.   }
  208. };
  209.  
  210. int sc_main(int argc, char** argv) {
  211.   Source source("source");
  212.   Buffer buffer("buffer");
  213.   Sink sink("sink");
  214.  
  215.   FlitSignal src_to_buf_signal;
  216.   source.req_out(src_to_buf_signal);
  217.   buffer.req_in(src_to_buf_signal);
  218.  
  219.   FlitSignal buf_to_sink_signal;
  220.   buffer.req_out(buf_to_sink_signal);
  221.   sink.req_in(buf_to_sink_signal);
  222.  
  223.   CreditSignal sink_to_buf_credit_signal;
  224.   sink.cr_ret(sink_to_buf_credit_signal);
  225.   buffer.cr_rcv(sink_to_buf_credit_signal);
  226.  
  227.   sc_start();
  228.  
  229.   return 0;
  230. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement