|
| 1 | +#ifndef IPS_VGA_MODEL_HPP |
| 2 | +#define IPS_VGA_MODEL_HPP |
| 3 | + |
| 4 | +#include <systemc.h> |
| 5 | + |
| 6 | +#define IPS_VGA_ACTIVE true |
| 7 | +#define IPS_VGA_INACTIVE false |
| 8 | + |
| 9 | +/** |
| 10 | + * @brief VGA representation class |
| 11 | + * |
| 12 | + * @tparam CLK_FREQ - clock frequency in HHz of the VGA |
| 13 | + * @tparam H_ACTIVE - output horizontal active video pixels |
| 14 | + * @tparam H_FP - wait after the display period before the sync |
| 15 | + * horizontal pulse |
| 16 | + * @tparam H_SYNC_PULSE - assert HSYNC |
| 17 | + * @tparam H_BP - wait after the sync horizontal pulse before starting |
| 18 | + * the next display period |
| 19 | + * @tparam V_ACTIVE - output vertical active video pixels |
| 20 | + * @tparam V_FP - wait after the display period before the sync |
| 21 | + * vertical pulse |
| 22 | + * @tparam V_SYNC_PULSE - assert VSYNC |
| 23 | + * @tparam V_BP - wait after the sync vertical pulse before starting |
| 24 | + * the next display period |
| 25 | + */ |
| 26 | +template < |
| 27 | + unsigned int H_ACTIVE = 640, |
| 28 | + unsigned int H_FP = 16, |
| 29 | + unsigned int H_SYNC_PULSE = 96, |
| 30 | + unsigned int H_BP = 48, |
| 31 | + unsigned int V_ACTIVE = 480, |
| 32 | + unsigned int V_FP = 10, |
| 33 | + unsigned int V_SYNC_PULSE = 2, |
| 34 | + unsigned int V_BP = 33 |
| 35 | +> |
| 36 | +SC_MODULE(vga) |
| 37 | +{ |
| 38 | +protected: |
| 39 | + // Horizontal count |
| 40 | + int h_count; |
| 41 | + // Vertical count |
| 42 | + int v_count; |
| 43 | +public: |
| 44 | + // Input clock |
| 45 | + sc_core::sc_in<bool> clk; |
| 46 | + // Output horizontal synch |
| 47 | + sc_core::sc_out<bool> o_hsync; |
| 48 | + // Output vertical synch |
| 49 | + sc_core::sc_out<bool> o_vsync; |
| 50 | +#ifdef IPS_DEBUG_EN |
| 51 | + // For debug |
| 52 | + sc_core::sc_out<int> o_h_count; |
| 53 | + sc_core::sc_out<int> o_v_count; |
| 54 | +#endif // IPS_DEBUG_EN |
| 55 | + |
| 56 | + SC_CTOR(vga) : o_hsync("o_hsync"), o_vsync("o_vsync") |
| 57 | + { |
| 58 | + this->h_count = 0; |
| 59 | + this->v_count = 0; |
| 60 | + |
| 61 | + SC_METHOD(run); |
| 62 | + sensitive << clk.pos(); |
| 63 | + } |
| 64 | + |
| 65 | + /** |
| 66 | + * @brief Override method |
| 67 | + * Compute the values output of the VGA |
| 68 | + * |
| 69 | + */ |
| 70 | + void run() |
| 71 | + { |
| 72 | + if (this->clk.read()) |
| 73 | + { |
| 74 | +#ifdef IPS_DEBUG_EN |
| 75 | + std::cout << "@" << sc_core::sc_time_stamp().to_seconds() * 1e6 << "us" << std::endl; |
| 76 | +#endif // IPS_DEBUG_EN |
| 77 | + |
| 78 | + // Increment H counter |
| 79 | + this->h_count++; |
| 80 | + |
| 81 | + // HSYNC pulse |
| 82 | + if (this->h_count == H_SYNC_PULSE) |
| 83 | + { |
| 84 | + this->o_hsync.write(IPS_VGA_ACTIVE); |
| 85 | + } |
| 86 | + // End of H-sync pulse |
| 87 | + else if (this->h_count == (H_SYNC_PULSE + H_BP)) |
| 88 | + { |
| 89 | + this->o_hsync.write(IPS_VGA_ACTIVE); |
| 90 | + } |
| 91 | + // H front porch |
| 92 | + else if (this->h_count == (H_SYNC_PULSE + H_BP + H_ACTIVE)) |
| 93 | + { |
| 94 | + this->o_hsync.write(IPS_VGA_INACTIVE); |
| 95 | + } |
| 96 | + // End of HSYNC |
| 97 | + else if (this->h_count == (H_SYNC_PULSE + H_BP + H_ACTIVE + H_FP)) |
| 98 | + { |
| 99 | + // Restart H counter |
| 100 | + this->o_hsync.write(IPS_VGA_ACTIVE); |
| 101 | + this->h_count = 0; |
| 102 | + |
| 103 | + // Increment H counter |
| 104 | + this->v_count++; |
| 105 | + |
| 106 | + // VSYNC pulse |
| 107 | + if (this->v_count == V_SYNC_PULSE) |
| 108 | + { |
| 109 | + this->o_vsync.write(IPS_VGA_INACTIVE); |
| 110 | + } |
| 111 | + // End of V-sync pulse |
| 112 | + else if (this->v_count == (V_SYNC_PULSE + V_BP)) |
| 113 | + { |
| 114 | + this->o_vsync.write(IPS_VGA_ACTIVE); |
| 115 | + } |
| 116 | + // V front porch |
| 117 | + else if (this->v_count == (V_SYNC_PULSE + V_BP + V_ACTIVE)) |
| 118 | + { |
| 119 | + this->o_vsync.write(IPS_VGA_INACTIVE); |
| 120 | + } |
| 121 | + // End of VSYNC |
| 122 | + else if (this->v_count == (V_SYNC_PULSE + V_BP + V_ACTIVE + V_FP)) |
| 123 | + { |
| 124 | + this->o_vsync.write(IPS_VGA_ACTIVE); |
| 125 | + this->v_count = 0; |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | +#ifdef IPS_DEBUG_EN |
| 130 | + this->o_v_count.write(this->v_count); |
| 131 | + this->o_h_count.write(this->h_count); |
| 132 | +#endif // IPS_DEBUG_EN |
| 133 | + } |
| 134 | + } |
| 135 | +}; |
| 136 | +#endif // IPS_VGA_MODEL_HPP |
0 commit comments