1 #include <iostream> 2 #include <sstream> 3 #include "systemc.h" 4 5 #define WIDTH 8 6 #define VEC_NUM 4 7 #define VEC_WIDTH 4 8 9 SC_MODULE(vector_mul) { 10 sc_in<bool> clk, rst_n; 11 sc_in<sc_int<WIDTH>> vec1[VEC_WIDTH],vec2[VEC_WIDTH]; 12 sc_out<sc_int<WIDTH * 2> > vec_o; 13 14 void compute_vector_mul(void) { 15 int temp = 0; 16 if (rst_n.read() == false) { 17 vec_o.write(0); 18 return; 19 } 20 for (int i = 0; i < VEC_WIDTH; ++i) { 21 temp = temp + vec1[i].read() * vec2[i].read(); 22 } 23 vec_o.write(temp); 24 }; 25 26 SC_CTOR(vector_mul) { 27 SC_METHOD(compute_vector_mul); 28 sensitive << clk.pos(); 29 sensitive << rst_n.neg(); 30 }; 31 }; 32 33 SC_MODULE(matrix_vector_mul) { 34 sc_in<bool> clk,rst_n; 35 sc_in<sc_int<WIDTH> > matrix[VEC_NUM][VEC_WIDTH]; 36 sc_in<sc_int<WIDTH> > vector_in[VEC_WIDTH]; 37 sc_out<sc_int<WIDTH * 2> > vector_out[VEC_NUM]; 38 39 vector_mul *pe[VEC_NUM]; 40 41 SC_CTOR(matrix_vector_mul) { 42 std::ostringstream pe_name; 43 for (int i = 0; i < VEC_NUM; ++i) { 44 pe_name << "pe" << i; 45 pe[i] = new vector_mul(pe_name.str().c_str()); 46 pe[i]->clk(clk); 47 pe[i]->rst_n(rst_n); 48 for (int j = 0; j < VEC_WIDTH; ++j) { 49 pe[i]->vec1[j](matrix[i][j]); 50 pe[i]->vec2[j](vector_in[j]); 51 } 52 pe[i]->vec_o(vector_out[i]); 53 pe_name.str(""); 54 } 55 }; 56 }; 57 58 SC_MODULE(driver) { 59 sc_in <bool> clk; 60 sc_out<bool> rst_n; 61 sc_out<sc_int<WIDTH>> mat[VEC_NUM][VEC_WIDTH]; 62 sc_out<sc_int<WIDTH>> vec[VEC_WIDTH]; 63 64 void generate_input(void) { 65 for (int i = 0; i < VEC_WIDTH; ++i) { 66 for (int j = 0; j < VEC_NUM; ++j) { 67 mat[j][i].write(rand() % ((int)pow(2,WIDTH) - 1)); 68 } 69 vec[i].write(rand() % ((int)pow(2,WIDTH) - 1)); 70 } 71 while(1) { 72 wait(); 73 for (int i = 0; i < VEC_WIDTH; ++i) { 74 for (int j = 0; j < VEC_NUM; ++j) { 75 mat[j][i].write(rand() % ((int)pow(2,WIDTH) - 1)); 76 } 77 vec[i].write(rand() % ((int)pow(2,WIDTH) - 1)); 78 } 79 } 80 }; 81 82 void generate_reset(void) { 83 rst_n.write(1); 84 wait(1,SC_NS); 85 rst_n.write(0); 86 wait(1,SC_NS); 87 rst_n.write(1); 88 }; 89 90 SC_CTOR(driver) { 91 SC_THREAD(generate_input); 92 sensitive << clk.neg(); 93 SC_THREAD(generate_reset); 94 }; 95 }; 96 97 int sc_main(int argc,char* argv[]) 98 { 99 sc_clock clk("clk", 10, SC_NS); 100 sc_signal<bool> rst_n; 101 sc_signal<sc_int<WIDTH> > mat[VEC_NUM][VEC_WIDTH], vec[VEC_WIDTH]; 102 sc_signal<sc_int<WIDTH * 2>>vec_o[VEC_NUM]; 103 104 sc_trace_file *fp; 105 fp=sc_create_vcd_trace_file("wave"); 106 fp->set_time_unit(1, SC_NS); 107 108 matrix_vector_mul dut("dut"); 109 dut.clk(clk); 110 dut.rst_n(rst_n); 111 for (int i = 0; i < VEC_NUM; ++i) { 112 for (int j = 0; j < VEC_WIDTH; ++j) { 113 dut.matrix[i][j](mat[i][j]); 114 } 115 } 116 for (int i = 0; i < VEC_WIDTH; ++i) { 117 dut.vector_in[i](vec[i]); 118 } 119 for (int i = 0; i < VEC_NUM; ++i) { 120 dut.vector_out[i](vec_o[i]); 121 } 122 123 driver d("dri"); 124 d.clk(clk); 125 d.rst_n(rst_n); 126 for (int i = 0; i < VEC_WIDTH; ++i) { 127 for (int j = 0; j < VEC_NUM; ++j) { 128 d.mat[j][i](mat[j][i]); 129 } 130 d.vec[i](vec[i]); 131 } 132 133 sc_trace(fp,clk,"clk"); 134 sc_trace(fp,rst_n,"rst_n"); 135 for (int i = 0; i < VEC_NUM; ++i) { 136 for (int j = 0; j < VEC_WIDTH; ++j) { 137 std::ostringstream mat_name; 138 mat_name << "matrix(" << i << "," << j << ")"; 139 sc_trace(fp,mat[i][j],mat_name.str()); 140 mat_name.str(""); 141 } 142 } 143 for (int i = 0; i < VEC_WIDTH; ++i) { 144 std::ostringstream stream1; 145 stream1 << "vec(" << i << ")"; 146 sc_trace(fp,vec[i],stream1.str()); 147 stream1.str(""); 148 } 149 for (int i = 0; i < VEC_NUM; ++i) { 150 std::ostringstream out_name; 151 out_name << "dout(" << i << ")"; 152 sc_trace(fp,vec_o[i],out_name.str()); 153 out_name.str(""); 154 } 155 156 sc_start(1000, SC_NS); 157 158 sc_close_vcd_trace_file(fp); 159 return 0; 160 };
编译: g++ sctest.cpp -lsystemc
运行: ./a.out
查看波形: gtkwave wave.vcd &
1 # Makefile for SystemC 2 3 export PRJ_PATH=$(shell pwd)/.. 4 export DESIGN=riscv_sopc 5 6 all: 7 @echo "Verification based on verilator and SystemC" 8 9 cmp: 10 verilator -Wno-fatal -f ../rtl/filelist/filelist.f --top-module $(DESIGN) --sc --trace --exe sc_main.cpp 11 make -C obj_dir -f V$(DESIGN).mk V$(DESIGN) 12 13 run: 14 ./obj_dir/V$(DESIGN) 15 16 wave: 17 gtkwave wave.vcd & 18 19 clean: 20 @rm -rf obj_dir wave.vcd
1 #include "verilated_vcd_sc.h" 2 #include "Vriscv_sopc.h" 3 4 SC_MODULE(rst_gen) { 5 sc_in <bool> clk; 6 sc_out<bool> rst_n; 7 8 void generate_reset(void) { 9 rst_n.write(1); 10 wait(1,SC_NS); 11 rst_n.write(0); 12 wait(1,SC_NS); 13 rst_n.write(1); 14 }; 15 16 SC_CTOR(rst_gen) { 17 sensitive << clk.neg(); 18 SC_THREAD(generate_reset); 19 }; 20 }; 21 22 int sc_main(int argc, char **argv) 23 { 24 Verilated::commandArgs(argc, argv); 25 Verilated::traceEverOn(true); 26 VerilatedVcdSc* tfp = new VerilatedVcdSc; 27 sc_clock clk("clk", 10, SC_NS, 0.5, 3, SC_NS, true); 28 sc_signal<bool> rst_n; 29 sc_signal<bool> uart_txd; 30 sc_signal<bool> uart_rxd; 31 sc_signal<uint32_t> led; 32 sc_signal<uint32_t> key; 33 Vriscv_sopc *top; 34 rst_gen *rst; 35 36 top = new Vriscv_sopc("top"); 37 rst = new rst_gen("rst"); 38 39 top->clk(clk); 40 top->rst_n(rst_n); 41 top->uart_txd(uart_txd); 42 top->uart_rxd(uart_rxd); 43 top->led(led); 44 top->key(key); 45 46 rst->clk(clk); 47 rst->rst_n(rst_n); 48 49 top->trace(tfp, 0); 50 tfp->open("wave.vcd"); 51 52 if (!Verilated::gotFinish()) { 53 sc_start(1, SC_MS); 54 } 55 56 tfp->close(); 57 delete top; 58 59 return 0; 60 }