Hardware Design: SIE
Sign in or create your account | Project List | Help
Hardware Design: SIE Git Source Tree
Root/
| 1 | /* |
| 2 | * Milkymist VJ SoC |
| 3 | * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq |
| 4 | * |
| 5 | * This program is free software: you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation, version 3 of the License. |
| 8 | * |
| 9 | * This program is distributed in the hope that it will be useful, |
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | * GNU General Public License for more details. |
| 13 | * |
| 14 | * You should have received a copy of the GNU General Public License |
| 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | */ |
| 17 | |
| 18 | module vgafb #( |
| 19 | parameter csr_addr = 4'h0, |
| 20 | parameter fml_depth = 26 |
| 21 | ) ( |
| 22 | input sys_clk, |
| 23 | input sys_rst, |
| 24 | |
| 25 | /* Configuration interface */ |
| 26 | input [13:0] csr_a, |
| 27 | input csr_we, |
| 28 | input [31:0] csr_di, |
| 29 | output [31:0] csr_do, |
| 30 | |
| 31 | /* Framebuffer FML 4x64 interface */ |
| 32 | output [fml_depth-1:0] fml_adr, |
| 33 | output fml_stb, |
| 34 | input fml_ack, |
| 35 | input [63:0] fml_di, |
| 36 | |
| 37 | /* VGA pixel clock */ |
| 38 | input vga_clk, |
| 39 | |
| 40 | /* VGA signal pads */ |
| 41 | output vga_psave_n, |
| 42 | output reg vga_hsync_n, |
| 43 | output reg vga_vsync_n, |
| 44 | output vga_sync_n, |
| 45 | output vga_blank_n, |
| 46 | output reg [7:0] vga_r, |
| 47 | output reg [7:0] vga_g, |
| 48 | output reg [7:0] vga_b, |
| 49 | output [1:0] vga_clk_sel |
| 50 | ); |
| 51 | |
| 52 | /* |
| 53 | * Control interface |
| 54 | */ |
| 55 | wire vga_rst; |
| 56 | |
| 57 | wire [10:0] hres; |
| 58 | wire [10:0] hsync_start; |
| 59 | wire [10:0] hsync_end; |
| 60 | wire [10:0] hscan; |
| 61 | |
| 62 | wire [10:0] vres; |
| 63 | wire [10:0] vsync_start; |
| 64 | wire [10:0] vsync_end; |
| 65 | wire [10:0] vscan; |
| 66 | |
| 67 | wire [fml_depth-1:0] baseaddress; |
| 68 | wire baseaddress_ack; |
| 69 | |
| 70 | wire [17:0] nbursts; |
| 71 | |
| 72 | vgafb_ctlif #( |
| 73 | .csr_addr(csr_addr), |
| 74 | .fml_depth(fml_depth) |
| 75 | ) ctlif ( |
| 76 | .sys_clk(sys_clk), |
| 77 | .sys_rst(sys_rst), |
| 78 | |
| 79 | .csr_a(csr_a), |
| 80 | .csr_we(csr_we), |
| 81 | .csr_di(csr_di), |
| 82 | .csr_do(csr_do), |
| 83 | |
| 84 | .vga_rst(vga_rst), |
| 85 | |
| 86 | .hres(hres), |
| 87 | .hsync_start(hsync_start), |
| 88 | .hsync_end(hsync_end), |
| 89 | .hscan(hscan), |
| 90 | |
| 91 | .vres(vres), |
| 92 | .vsync_start(vsync_start), |
| 93 | .vsync_end(vsync_end), |
| 94 | .vscan(vscan), |
| 95 | |
| 96 | .baseaddress(baseaddress), |
| 97 | .baseaddress_ack(baseaddress_ack), |
| 98 | |
| 99 | .nbursts(nbursts), |
| 100 | |
| 101 | .vga_clk_sel(vga_clk_sel) |
| 102 | ); |
| 103 | |
| 104 | /* |
| 105 | * Generate signal data |
| 106 | */ |
| 107 | reg hsync_n; |
| 108 | reg vsync_n; |
| 109 | wire pixel_valid; |
| 110 | wire [15:0] pixel_fb; |
| 111 | wire pixel_ack; |
| 112 | wire [15:0] pixel; |
| 113 | |
| 114 | wire fifo_full; |
| 115 | |
| 116 | reg hactive; |
| 117 | reg vactive; |
| 118 | wire active = hactive & vactive; |
| 119 | assign pixel = active ? pixel_fb : 16'h0000; |
| 120 | |
| 121 | wire generate_en; |
| 122 | |
| 123 | reg [10:0] hcounter; |
| 124 | reg [10:0] vcounter; |
| 125 | |
| 126 | always @(posedge sys_clk) begin |
| 127 | if(vga_rst) begin |
| 128 | hcounter <= 10'd0; |
| 129 | vcounter <= 10'd0; |
| 130 | hactive <= 1'b0; |
| 131 | hsync_n <= 1'b1; |
| 132 | vactive <= 1'b0; |
| 133 | vsync_n <= 1'b1; |
| 134 | end else begin |
| 135 | if(generate_en) begin |
| 136 | hcounter <= hcounter + 10'd1; |
| 137 | |
| 138 | if(hcounter == 10'd0) hactive <= 1'b1; |
| 139 | if(hcounter == hres) hactive <= 1'b0; |
| 140 | if(hcounter == hsync_start) hsync_n <= 1'b0; |
| 141 | if(hcounter == hsync_end) hsync_n <= 1'b1; |
| 142 | if(hcounter == hscan) begin |
| 143 | hcounter <= 10'd0; |
| 144 | if(vcounter == vscan) |
| 145 | vcounter <= 10'd0; |
| 146 | else |
| 147 | vcounter <= vcounter + 10'd1; |
| 148 | end |
| 149 | |
| 150 | if(vcounter == 10'd0) vactive <= 1'b1; |
| 151 | if(vcounter == vres) vactive <= 1'b0; |
| 152 | if(vcounter == vsync_start) vsync_n <= 1'b0; |
| 153 | if(vcounter == vsync_end) vsync_n <= 1'b1; |
| 154 | end |
| 155 | end |
| 156 | end |
| 157 | |
| 158 | assign generate_en = ~fifo_full & (~active | pixel_valid); |
| 159 | assign pixel_ack = ~fifo_full & active & pixel_valid; |
| 160 | |
| 161 | vgafb_pixelfeed #( |
| 162 | .fml_depth(fml_depth) |
| 163 | ) pixelfeed ( |
| 164 | .sys_clk(sys_clk), |
| 165 | .sys_rst(sys_rst), |
| 166 | .vga_rst(vga_rst), |
| 167 | |
| 168 | .nbursts(nbursts), |
| 169 | .baseaddress(baseaddress), |
| 170 | .baseaddress_ack(baseaddress_ack), |
| 171 | |
| 172 | .fml_adr(fml_adr), |
| 173 | .fml_stb(fml_stb), |
| 174 | .fml_ack(fml_ack), |
| 175 | .fml_di(fml_di), |
| 176 | |
| 177 | .pixel_valid(pixel_valid), |
| 178 | .pixel(pixel_fb), |
| 179 | .pixel_ack(pixel_ack) |
| 180 | ); |
| 181 | |
| 182 | /* |
| 183 | * System clock to VGA clock domain crossing is |
| 184 | * acheived by an asynchronous FIFO. |
| 185 | * |
| 186 | * Bits 0-15 are RGB565 pixel data |
| 187 | * Bit 16 is negated Horizontal Sync |
| 188 | * Bit 17 is negated Verical Sync |
| 189 | */ |
| 190 | wire [17:0] fifo_do; |
| 191 | |
| 192 | vgafb_asfifo #( |
| 193 | .DATA_WIDTH(18), |
| 194 | .ADDRESS_WIDTH(6) |
| 195 | ) fifo ( |
| 196 | .Data_out(fifo_do), |
| 197 | .Empty_out(), |
| 198 | .ReadEn_in(1'b1), |
| 199 | .RClk(vga_clk), |
| 200 | |
| 201 | .Data_in({vsync_n, hsync_n, pixel}), |
| 202 | .Full_out(fifo_full), |
| 203 | .WriteEn_in(generate_en), |
| 204 | .WClk(sys_clk), |
| 205 | |
| 206 | .Clear_in(vga_rst) |
| 207 | ); |
| 208 | |
| 209 | /* |
| 210 | * Drive the VGA pads. |
| 211 | * RGB565 -> RGB888 color space conversion is also performed here |
| 212 | * by bit shifting and replicating the most significant bits of |
| 213 | * the input into the least significant bits of the output left |
| 214 | * undefined by the shifting. |
| 215 | */ |
| 216 | |
| 217 | assign vga_sync_n = 1'b0; /* Sync-on-Green is not implemented */ |
| 218 | assign vga_psave_n = 1'b1; |
| 219 | assign vga_blank_n = 1'b1; |
| 220 | |
| 221 | always @(posedge vga_clk) begin |
| 222 | vga_vsync_n <= fifo_do[17]; |
| 223 | vga_hsync_n <= fifo_do[16]; |
| 224 | vga_r <= {fifo_do[15:11], fifo_do[15:13]}; |
| 225 | vga_g <= {fifo_do[10:5], fifo_do[10:9]}; |
| 226 | vga_b <= {fifo_do[4:0], fifo_do[4:2]}; |
| 227 | end |
| 228 | |
| 229 | endmodule |
| 230 |
Branches:
master
