1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/docs/wiki/VGA_Signal_Output Mon Apr 15 17:53:50 2019 +0200
1.3 @@ -0,0 +1,347 @@
1.4 += VGA Signal Output =
1.5 +
1.6 +There are two principal mechanisms for generating a VGA signal demonstrated in
1.7 +this project:
1.8 +
1.9 + * Using the CPU to "copy" pixel data to an output port
1.10 + * Using DMA transfers to "copy" pixel data to an output port
1.11 +
1.12 +Within the latter, there are a number of variations in the mechanism employed:
1.13 +
1.14 + * Use of general-purpose output pins versus parallel mode outputs
1.15 + * Use of large transfer cells containing each entire pixel line versus small
1.16 + transfer cells containing fragments of each line
1.17 + * Use of a single transfer-initiating event versus separate line-initiating
1.18 + and transfer-initiating events
1.19 +
1.20 +== Using the CPU for Transfers ==
1.21 +
1.22 +{{{#!graphviz
1.23 +//format=svg
1.24 +//transform=notugly
1.25 +digraph cpu {
1.26 + node [shape=box,fontsize="13.0",fontname="Helvetica"];
1.27 + rankdir=TD;
1.28 +
1.29 + subgraph {
1.30 + rank=same;
1.31 +
1.32 + timer [label="Display line\ntimer",style=filled,fillcolor=gold];
1.33 + t_0 [label="0",shape=ellipse];
1.34 + t_hsync [label="hsync",shape=ellipse];
1.35 + t_limit [label="limit",shape=ellipse];
1.36 + }
1.37 +
1.38 + oc1 [label="Output compare",style=filled,fillcolor=gold];
1.39 +
1.40 + subgraph {
1.41 + rank=same;
1.42 +
1.43 + lineirq [label="Display line\ninterrupt handler"];
1.44 + pixelirq [label="Pixel output\ninterrupt handler"];
1.45 + }
1.46 +
1.47 + subgraph {
1.48 + rank=same;
1.49 +
1.50 + pixels [label="Pixel output\nBlack/reset output",style=filled,fillcolor=green,shape=parallelogram];
1.51 + hsync [label="Horizontal sync",shape=house,style=filled,fillcolor=red];
1.52 + vsync [label="Vertical sync",shape=house,style=filled,fillcolor=red];
1.53 + }
1.54 +
1.55 + /* The timer starts at 0 and wraps around at limit. */
1.56 +
1.57 + timer -> t_0 [arrowhead=none];
1.58 + t_0 -> t_hsync -> t_limit -> t_0 [style=dashed];
1.59 +
1.60 + /* The timer initiates the interrupt request for pixel production. */
1.61 +
1.62 + t_0 -> pixelirq;
1.63 +
1.64 + /* The interrupt handler generates the pixel output. */
1.65 +
1.66 + pixelirq -> pixels;
1.67 +
1.68 + /* The timer feeds the output compare unit, driving hsync. */
1.69 +
1.70 + t_hsync -> oc1;
1.71 + oc1 -> hsync;
1.72 +
1.73 + /* The output compare unit initiates the interrupt request for each line,
1.74 + driving vsync. */
1.75 +
1.76 + oc1 -> lineirq;
1.77 + lineirq -> vsync;
1.78 +}
1.79 +}}}
1.80 +
1.81 +== Using DMA for Transfers ==
1.82 +
1.83 +{{{#!graphviz
1.84 +//format=svg
1.85 +//transform=notugly
1.86 +digraph dma {
1.87 + node [shape=box,fontsize="13.0",fontname="Helvetica"];
1.88 + rankdir=TD;
1.89 +
1.90 + subgraph {
1.91 + rank=same;
1.92 +
1.93 + timer [label="Display line\ntimer",style=filled,fillcolor=gold];
1.94 + t_0 [label="0",shape=ellipse];
1.95 + t_hsync [label="hsync",shape=ellipse];
1.96 + t_limit [label="limit",shape=ellipse];
1.97 + }
1.98 +
1.99 + oc1 [label="Output compare",style=filled,fillcolor=gold];
1.100 +
1.101 + subgraph {
1.102 + rank=same;
1.103 +
1.104 + dma_line [label="Pixel output\nDMA channel",style=filled,fillcolor=lightblue];
1.105 + dma_reset [label="Pixel reset\nDMA channel",style=filled,fillcolor=lightblue];
1.106 + lineirq [label="Display line\ninterrupt handler"];
1.107 + }
1.108 +
1.109 + subgraph {
1.110 + rank=same;
1.111 +
1.112 + pixels [label="Pixel output",style=filled,fillcolor=green,shape=parallelogram];
1.113 + black [label="Black/reset output",style=filled,fillcolor=black,fontcolor=white,shape=parallelogram];
1.114 + hsync [label="Horizontal sync",shape=house,style=filled,fillcolor=red];
1.115 + vsync [label="Vertical sync",shape=house,style=filled,fillcolor=red];
1.116 + }
1.117 +
1.118 + /* The timer starts at 0 and wraps around at limit. */
1.119 +
1.120 + timer -> t_0 [arrowhead=none];
1.121 + t_0 -> t_hsync -> t_limit -> t_0 [style=dashed];
1.122 +
1.123 + /* The timer initiates the DMA transfer for pixel production. */
1.124 +
1.125 + t_0 -> dma_line;
1.126 +
1.127 + /* The line channel generates the pixel output. */
1.128 +
1.129 + dma_line -> pixels;
1.130 +
1.131 + /* The completion of the line channel initiates the reset channel. */
1.132 +
1.133 + dma_line -> dma_reset;
1.134 +
1.135 + /* The reset channel generates black/reset output. */
1.136 +
1.137 + dma_reset -> black;
1.138 +
1.139 + /* The black/reset value follows the visible pixels. */
1.140 +
1.141 + pixels -> black [style=dashed];
1.142 +
1.143 + /* The timer feeds the output compare unit, driving hsync. */
1.144 +
1.145 + t_hsync -> oc1;
1.146 + oc1 -> hsync;
1.147 +
1.148 + /* The output compare unit initiates the interrupt request for each line,
1.149 + driving vsync. */
1.150 +
1.151 + oc1 -> lineirq;
1.152 + lineirq -> vsync;
1.153 +}
1.154 +}}}
1.155 +
1.156 +== Using DMA and Timed Transfers ==
1.157 +
1.158 +{{{#!graphviz
1.159 +//format=svg
1.160 +//transform=notugly
1.161 +digraph dma {
1.162 + node [shape=box,fontsize="13.0",fontname="Helvetica"];
1.163 + rankdir=TD;
1.164 +
1.165 + subgraph {
1.166 + rank=same;
1.167 +
1.168 + timer [label="Display line\ntimer",style=filled,fillcolor=gold];
1.169 + t_0 [label="0",shape=ellipse];
1.170 + t_hsync [label="hsync",shape=ellipse];
1.171 + t_limit [label="limit",shape=ellipse];
1.172 + }
1.173 +
1.174 + oc1 [label="Output compare",style=filled,fillcolor=gold];
1.175 +
1.176 + subgraph {
1.177 + rank=same;
1.178 +
1.179 + trtimer [label="Transfer timer",style=filled,fillcolor=gold];
1.180 + tr_0 [label="0",shape=ellipse];
1.181 + tr_limit [label="limit",shape=ellipse];
1.182 + }
1.183 +
1.184 + subgraph {
1.185 + rank=same;
1.186 +
1.187 + dma_init [label="Initiator\nDMA channel",style=filled,fillcolor=lightblue];
1.188 + dma_line [label="Pixel output\nDMA channel",style=filled,fillcolor=lightblue];
1.189 + dma_reset [label="Pixel reset\nDMA channel",style=filled,fillcolor=lightblue];
1.190 + lineirq [label="Display line\ninterrupt handler"];
1.191 + }
1.192 +
1.193 + subgraph {
1.194 + rank=same;
1.195 +
1.196 + pixels [label="Pixel output",style=filled,fillcolor=green,shape=parallelogram];
1.197 + black [label="Black/reset output",style=filled,fillcolor=black,fontcolor=white,shape=parallelogram];
1.198 + hsync [label="Horizontal sync",shape=house,style=filled,fillcolor=red];
1.199 + vsync [label="Vertical sync",shape=house,style=filled,fillcolor=red];
1.200 + }
1.201 +
1.202 + /* The line timer starts at 0 and wraps around at limit. */
1.203 +
1.204 + timer -> t_0 [arrowhead=none];
1.205 + t_0 -> t_hsync -> t_limit -> t_0 [style=dashed];
1.206 +
1.207 + /* The transfer timer starts at 0 and wraps around at limit. */
1.208 +
1.209 + trtimer -> tr_0 [arrowhead=none];
1.210 + tr_0 -> tr_limit -> tr_0 [style=dashed];
1.211 +
1.212 + /* The line timer initiates the DMA transfers for the display line. */
1.213 +
1.214 + t_0 -> dma_init;
1.215 +
1.216 + /* The completion of the initiating channel enables the line channel. */
1.217 +
1.218 + dma_init -> dma_line;
1.219 +
1.220 + /* Each cell transfer in the line channel is initiated by the transfer
1.221 + timer. */
1.222 +
1.223 + tr_0 -> dma_line;
1.224 +
1.225 + /* The line channel generates the pixel output. */
1.226 +
1.227 + dma_line -> pixels;
1.228 +
1.229 + /* The completion of the line channel initiates the reset channel. */
1.230 +
1.231 + dma_line -> dma_reset;
1.232 +
1.233 + /* The reset channel generates black/reset output. */
1.234 +
1.235 + dma_reset -> black;
1.236 +
1.237 + /* The black/reset value follows the visible pixels. */
1.238 +
1.239 + pixels -> black [style=dashed];
1.240 +
1.241 + /* The timer feeds the output compare unit, driving hsync. */
1.242 +
1.243 + t_hsync -> oc1;
1.244 + oc1 -> hsync;
1.245 +
1.246 + /* The output compare unit initiates the interrupt request for each line,
1.247 + driving vsync. */
1.248 +
1.249 + oc1 -> lineirq;
1.250 + lineirq -> vsync;
1.251 +}
1.252 +}}}
1.253 +
1.254 +== Using DMA and Timed Dual-Channel Transfers ==
1.255 +
1.256 +{{{#!graphviz
1.257 +//format=svg
1.258 +//transform=notugly
1.259 +digraph dma {
1.260 + node [shape=box,fontsize="13.0",fontname="Helvetica"];
1.261 + rankdir=TD;
1.262 +
1.263 + subgraph {
1.264 + rank=same;
1.265 +
1.266 + timer [label="Display line\ntimer",style=filled,fillcolor=gold];
1.267 + t_0 [label="0",shape=ellipse];
1.268 + t_hsync [label="hsync",shape=ellipse];
1.269 + t_limit [label="limit",shape=ellipse];
1.270 + }
1.271 +
1.272 + oc1 [label="Output compare",style=filled,fillcolor=gold];
1.273 +
1.274 + subgraph {
1.275 + rank=same;
1.276 +
1.277 + trtimer [label="Transfer timer",style=filled,fillcolor=gold];
1.278 + tr_0 [label="0",shape=ellipse];
1.279 + tr_limit [label="limit",shape=ellipse];
1.280 + }
1.281 +
1.282 + subgraph {
1.283 + rank=same;
1.284 +
1.285 + dma_init [label="Initiator\nDMA channel",style=filled,fillcolor=lightblue];
1.286 + dma_line [label="{Pixel output\nDMA channel #1 | Pixel output\nDMA channel #2}",style=filled,fillcolor=lightblue,shape=record];
1.287 + dma_reset [label="Pixel reset\nDMA channel",style=filled,fillcolor=lightblue];
1.288 + lineirq [label="Display line\ninterrupt handler"];
1.289 + }
1.290 +
1.291 + subgraph {
1.292 + rank=same;
1.293 +
1.294 + pixels [label="Pixel output",style=filled,fillcolor=green,shape=parallelogram];
1.295 + black [label="Black/reset output",style=filled,fillcolor=black,fontcolor=white,shape=parallelogram];
1.296 + hsync [label="Horizontal sync",shape=house,style=filled,fillcolor=red];
1.297 + vsync [label="Vertical sync",shape=house,style=filled,fillcolor=red];
1.298 + }
1.299 +
1.300 + /* The line timer starts at 0 and wraps around at limit. */
1.301 +
1.302 + timer -> t_0 [arrowhead=none];
1.303 + t_0 -> t_hsync -> t_limit -> t_0 [style=dashed];
1.304 +
1.305 + /* The transfer timer starts at 0 and wraps around at limit. */
1.306 +
1.307 + trtimer -> tr_0 [arrowhead=none];
1.308 + tr_0 -> tr_limit -> tr_0 [style=dashed];
1.309 +
1.310 + /* The line timer initiates the DMA transfers for the display line. */
1.311 +
1.312 + t_0 -> dma_init;
1.313 +
1.314 + /* The completion of the initiating channel enables the line channels. */
1.315 +
1.316 + dma_init -> dma_line;
1.317 +
1.318 + /* Each cell transfer in the line channels is initiated by the transfer
1.319 + timer. */
1.320 +
1.321 + tr_0 -> dma_line;
1.322 +
1.323 + /* The line channels generate the pixel output. */
1.324 +
1.325 + dma_line -> pixels;
1.326 +
1.327 + /* The completion of the line channels initiates the reset channel. */
1.328 +
1.329 + dma_line -> dma_reset;
1.330 +
1.331 + /* The reset channel generates black/reset output. */
1.332 +
1.333 + dma_reset -> black;
1.334 +
1.335 + /* The black/reset value follows the visible pixels. */
1.336 +
1.337 + pixels -> black [style=dashed];
1.338 +
1.339 + /* The timer feeds the output compare unit, driving hsync. */
1.340 +
1.341 + t_hsync -> oc1;
1.342 + oc1 -> hsync;
1.343 +
1.344 + /* The output compare unit initiates the interrupt request for each line,
1.345 + driving vsync. */
1.346 +
1.347 + oc1 -> lineirq;
1.348 + lineirq -> vsync;
1.349 +}
1.350 +}}}