本文介绍了如何使用 SystemC 完成矩阵乘法。
向量乘法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 SC_MODULE (vector_mul) { sc_in<bool > clk, rst_n; sc_in<sc_int<WIDTH> > vec1[KK], vec2[KK]; sc_out<sc_int<WIDTH * 2 > > vec_o; void compute_vector_mul (void ) { int temp = 0 ; if (rst_n.read () == false ) { vec_o.write (0 ); return ; } for (int k = 0 ; k < KK; ++k) { temp = temp + vec1[k].read () * vec2[k].read (); } vec_o.write (temp); }; SC_CTOR (vector_mul) { SC_METHOD (compute_vector_mul); sensitive_pos << clk; sensitive_neg << rst_n; }; };
矩阵乘法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 SC_MODULE (matrix_mul) { sc_in<bool > clk, rst_n; sc_in<sc_int<WIDTH> > matA[MM][KK], matB[KK][NN]; sc_out<sc_int<WIDTH * 2 > > matC[MM][NN]; vector_mul *pe[MM][NN]; SC_CTOR (matrix_mul) { std::ostringstream pe_name; for (int i = 0 ; i < MM; ++i) { for (int j = 0 ; j < NN; ++j) { pe_name << "pe_" << i << "_" << j; pe[i][j] = new vector_mul (pe_name.str ().c_str ()); pe[i][j]->clk (clk); pe[i][j]->rst_n (rst_n); for (int k = 0 ; k < KK; ++k) { pe[i][j]->vec1[k](matA[i][k]); pe[i][j]->vec2[k](matB[k][j]); } pe[i][j]->vec_o (matC[i][j]); pe_name.str ("" ); } } }; };
激励源 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 SC_MODULE (driver) { sc_in <bool > clk; sc_out<bool > rst_n; sc_out<sc_int<WIDTH> > matA[MM][KK], matB[NN][KK]; void generate_input (void ) { for (int i = 0 ; i < MM; ++i) { for (int k = 0 ; k < KK; ++k) { matA[i][k].write (i * KK + k); } } for (int k = 0 ; k < KK; ++k) { for (int j = 0 ; j < NN; ++j) { matB[k][j].write (k * NN + j); } } while (1 ) { wait (); for (int i = 0 ; i < MM; ++i) { for (int k = 0 ; k < KK; ++k) { matA[i][k].write (i * KK + k); } } for (int k = 0 ; k < KK; ++k) { for (int j = 0 ; j < NN; ++j) { matB[k][j].write (k * NN + j); } } } }; void generate_reset (void ) { rst_n.write (1 ); wait (1 , SC_NS); rst_n.write (0 ); wait (1 , SC_NS); rst_n.write (1 ); }; SC_CTOR (driver) { SC_THREAD (generate_input); sensitive_neg << clk; SC_THREAD (generate_reset); }; };
主函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 #define WIDTH 32 #define VEC_WIDTH 8 #define MM 4 #define NN 4 #define KK 4 #include <systemc.h> using namespace std;int sc_main (int argc,char * argv[]) { sc_core::sc_report_handler::set_actions ( "/IEEE_Std_1666/deprecated" , sc_core::SC_DO_NOTHING ); sc_clock clk ("clk" , 10 , SC_NS) ; sc_signal<bool > rst_n; sc_signal<sc_int<WIDTH> > matA[MM][KK], matB[KK][NN]; sc_signal<sc_int<WIDTH * 2 > > matC[MM][NN]; matrix_mul dut ("dut" ) ; dut.clk (clk); dut.rst_n (rst_n); for (int i = 0 ; i < MM; ++i) { for (int k = 0 ; k < KK; ++k) { dut.matA[i][k](matA[i][k]); } } for (int k = 0 ; k < KK; ++k) { for (int j = 0 ; j < NN; ++j) { dut.matB[k][j](matB[k][j]); } } for (int i = 0 ; i < MM; ++i) { for (int j = 0 ; j < NN; ++j) { dut.matC[i][j](matC[i][j]); } } driver dri ("dri" ) ; dri.clk (clk); dri.rst_n (rst_n); for (int i = 0 ; i < MM; ++i) { for (int k = 0 ; k < KK; ++k) { dri.matA[i][k](matA[i][k]); } } for (int k = 0 ; k < KK; ++k) { for (int j = 0 ; j < NN; ++j) { dri.matB[k][j](matB[k][j]); } } sc_start (1000 , SC_NS); for (int i = 0 ; i < MM; ++i) { for (int j = 0 ; j < NN; ++j) { cout << matC[i][j] << " " ; } cout << endl; } return 0 ; };
参考 SystemC入门笔记