|
| 1 | +#ifndef IPS_SEQ_ITEM_AMS_HPP |
| 2 | +#define IPS_SEQ_ITEM_AMS_HPP |
| 3 | + |
| 4 | +#define int64 systemc_int64 |
| 5 | +#define uint64 systemc_uint64 |
| 6 | +#include <systemc.h> |
| 7 | +#include <systemc-ams.h> |
| 8 | +#undef int64 |
| 9 | +#undef uint64 |
| 10 | +#define int64 opencv_int64 |
| 11 | +#define uint64 opencv_uint64 |
| 12 | +#include <opencv2/opencv.hpp> |
| 13 | +#undef int64 |
| 14 | +#undef uint64 |
| 15 | + |
| 16 | +// Image path |
| 17 | +#define IPS_IMG_PATH_TB "../../tools/datagen/src/imgs/car_rgb_noisy_image.jpg" |
| 18 | + |
| 19 | +/** |
| 20 | + * @brief This class is used to generate the data for the AMS test |
| 21 | + * |
| 22 | + * @tparam N - the number of output bits of the digital pixel |
| 23 | + * @tparam H_ACTIVE - output horizontal active video pixels |
| 24 | + * @tparam H_FP - wait after the display period before the sync |
| 25 | + * horizontal pulse |
| 26 | + * @tparam H_SYNC_PULSE - assert HSYNC |
| 27 | + * @tparam H_BP - wait after the sync horizontal pulse before starting |
| 28 | + * the next display period |
| 29 | + * @tparam V_ACTIVE - output vertical active video pixels |
| 30 | + * @tparam V_FP - wait after the display period before the sync |
| 31 | + * vertical pulse |
| 32 | + * @tparam V_SYNC_PULSE - assert VSYNC |
| 33 | + * @tparam V_BP - wait after the sync vertical pulse before starting |
| 34 | + * the next display period |
| 35 | + */ |
| 36 | +template < |
| 37 | + unsigned int N = 8, |
| 38 | + unsigned int H_ACTIVE = 640, |
| 39 | + unsigned int H_FP = 16, |
| 40 | + unsigned int H_SYNC_PULSE = 96, |
| 41 | + unsigned int H_BP = 48, |
| 42 | + unsigned int V_ACTIVE = 480, |
| 43 | + unsigned int V_FP = 10, |
| 44 | + unsigned int V_SYNC_PULSE = 2, |
| 45 | + unsigned int V_BP = 33 |
| 46 | +> |
| 47 | +SC_MODULE(seq_item_ams) |
| 48 | +{ |
| 49 | +protected: |
| 50 | + cv::Mat tx_img; |
| 51 | + |
| 52 | +public: |
| 53 | + // Input clock |
| 54 | + sc_core::sc_in<bool> clk; |
| 55 | + // Counters |
| 56 | + sc_core::sc_in<unsigned int> hcount; |
| 57 | + sc_core::sc_in<unsigned int> vcount; |
| 58 | + // Output pixel |
| 59 | + sc_core::sc_out<sc_uint<N> > o_red; |
| 60 | + sc_core::sc_out<sc_uint<N> > o_green; |
| 61 | + sc_core::sc_out<sc_uint<N> > o_blue; |
| 62 | + |
| 63 | + SC_CTOR(seq_item_ams) |
| 64 | + { |
| 65 | + // Read image |
| 66 | + const std::string img_path = IPS_IMG_PATH_TB; |
| 67 | + |
| 68 | + cv::Mat read_img = cv::imread(img_path, cv::IMREAD_COLOR); |
| 69 | + |
| 70 | + // CV_8UC3 Type: 8-bit unsigned, 3 channels (e.g., for a color image) |
| 71 | + read_img.convertTo(this->tx_img, CV_8UC3); |
| 72 | + |
| 73 | +#ifdef IPS_DEBUG_EN |
| 74 | + std::cout << "Loading image: " << img_path << std::endl; |
| 75 | +#endif // IPS_DEBUG_EN |
| 76 | + |
| 77 | + // Check if the image is loaded successfully |
| 78 | + if (this->tx_img.empty()) |
| 79 | + { |
| 80 | + std::cerr << "Error: Could not open or find the image!" << std::endl; |
| 81 | + exit(EXIT_FAILURE); |
| 82 | + } |
| 83 | + |
| 84 | +#ifdef IPS_DEBUG_EN |
| 85 | + std::cout << "TX image info: "; |
| 86 | + std::cout << "rows = " << this->tx_img.rows; |
| 87 | + std::cout << " cols = " << this->tx_img.cols; |
| 88 | + std::cout << " channels = " << this->tx_img.channels() << std::endl; |
| 89 | +#endif // IPS_DEBUG_EN |
| 90 | + |
| 91 | + SC_METHOD(run); |
| 92 | + sensitive << clk.pos(); |
| 93 | + } |
| 94 | + |
| 95 | + void run() |
| 96 | + { |
| 97 | + if (this->clk.read()) |
| 98 | + { |
| 99 | + const int IMG_ROW = static_cast<int>(this->vcount.read()) - (V_SYNC_PULSE + V_BP); |
| 100 | + const int IMG_COL = static_cast<int>(this->hcount.read()) - (H_SYNC_PULSE + H_BP); |
| 101 | + |
| 102 | +#ifdef IPS_DEBUG_EN |
| 103 | + std::cout << "TX image: "; |
| 104 | + std::cout << "row = " << IMG_ROW; |
| 105 | + std::cout << " col = " << IMG_COL; |
| 106 | +#endif // IPS_DEBUG_EN |
| 107 | + |
| 108 | + if ((IMG_ROW < 0) || (IMG_COL < 0) || (IMG_ROW >= static_cast<int>(V_ACTIVE)) || (IMG_COL >= static_cast<int>(H_ACTIVE))) |
| 109 | + { |
| 110 | + this->o_red.write(0); |
| 111 | + this->o_green.write(0); |
| 112 | + this->o_blue.write(0); |
| 113 | + |
| 114 | +#ifdef IPS_DEBUG_EN |
| 115 | + std::cout << " dpixel = (0,0,0) " << std::endl; |
| 116 | +#endif // IPS_DEBUG_EN |
| 117 | + } |
| 118 | + else |
| 119 | + { |
| 120 | + cv::Vec3b pixel = tx_img.at<cv::Vec3b>(IMG_ROW, IMG_COL, 0); |
| 121 | + |
| 122 | + this->o_red.write(static_cast<sc_uint<8>>(pixel[0])); |
| 123 | + this->o_green.write(static_cast<sc_uint<8>>(pixel[1])); |
| 124 | + this->o_blue.write(static_cast<sc_uint<8>>(pixel[2])); |
| 125 | + |
| 126 | +#ifdef IPS_DEBUG_EN |
| 127 | + std::cout << " ipixel = (" << static_cast<int>(pixel[0]) << "," |
| 128 | + << static_cast<int>(pixel[1]) << "," << static_cast<int>(pixel[2]) |
| 129 | + << ")" << std::endl; |
| 130 | +#endif // IPS_DEBUG_EN |
| 131 | + } |
| 132 | + } |
| 133 | + } |
| 134 | +}; |
| 135 | + |
| 136 | +#endif // IPS_SEQ_ITEM_AMS_HPP |
0 commit comments