OpenCores
URL https://opencores.org/ocsvn/vgafb/vgafb/trunk

Subversion Repositories vgafb

[/] [vgafb/] [trunk/] [vgafb.tar] - Diff between revs 2 and 3

Only display areas with differences | Details | Blame | View Log

Rev 2 Rev 3
vgafb/0000755000175000017500000000000011411201677012327 5ustar  lekernellekernelvgafb/rtl/0000755000175000017500000000000011411201677013130 5ustar  lekernellekernelvgafb/rtl/vgafb.v0000644000175000017500000001155011413143055014403 0ustar  lekernellekernel/*
vgafb/0000755000175000017500000000000011411201677012327 5ustar  lekernellekernelvgafb/rtl/0000755000175000017500000000000011411201677013130 5ustar  lekernellekernelvgafb/rtl/vgafb.v0000644000175000017500000001155011413143055014403 0ustar  lekernellekernel/*
 * Milkymist VJ SoC
 * Milkymist VJ SoC
 * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
 * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
 *
 *
 * This program is free software: you can redistribute it and/or modify
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 * the Free Software Foundation, version 3 of the License.
 *
 *
 * This program is distributed in the hope that it will be useful,
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 *
 *
 * You should have received a copy of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 * along with this program.  If not, see .
 */
 */
module vgafb #(
module vgafb #(
        parameter csr_addr = 4'h0,
        parameter csr_addr = 4'h0,
        parameter fml_depth = 26
        parameter fml_depth = 26
) (
) (
        input sys_clk,
        input sys_clk,
        input sys_rst,
        input sys_rst,
        /* Configuration interface */
        /* Configuration interface */
        input [13:0] csr_a,
        input [13:0] csr_a,
        input csr_we,
        input csr_we,
        input [31:0] csr_di,
        input [31:0] csr_di,
        output [31:0] csr_do,
        output [31:0] csr_do,
        /* Framebuffer FML 4x64 interface */
        /* Framebuffer FML 4x64 interface */
        output [fml_depth-1:0] fml_adr,
        output [fml_depth-1:0] fml_adr,
        output fml_stb,
        output fml_stb,
        input fml_ack,
        input fml_ack,
        input [63:0] fml_di,
        input [63:0] fml_di,
        /* Direct Cache Bus */
        /* Direct Cache Bus */
        output dcb_stb,
        output dcb_stb,
        output [fml_depth-1:0] dcb_adr,
        output [fml_depth-1:0] dcb_adr,
        input [63:0] dcb_dat,
        input [63:0] dcb_dat,
        input dcb_hit,
        input dcb_hit,
        /* VGA pixel clock */
        /* VGA pixel clock */
        input vga_clk,
        input vga_clk,
        /* VGA signal pads */
        /* VGA signal pads */
        output vga_psave_n,
        output vga_psave_n,
        output reg vga_hsync_n,
        output reg vga_hsync_n,
        output reg vga_vsync_n,
        output reg vga_vsync_n,
        output vga_sync_n,
        output vga_sync_n,
        output vga_blank_n,
        output vga_blank_n,
        output reg [7:0] vga_r,
        output reg [7:0] vga_r,
        output reg [7:0] vga_g,
        output reg [7:0] vga_g,
        output reg [7:0] vga_b,
        output reg [7:0] vga_b,
        inout vga_sda,
        inout vga_sda,
        output vga_sdc
        output vga_sdc
);
);
/*
/*
 * Control interface
 * Control interface
 */
 */
wire vga_rst;
wire vga_rst;
wire [10:0] hres;
wire [10:0] hres;
wire [10:0] hsync_start;
wire [10:0] hsync_start;
wire [10:0] hsync_end;
wire [10:0] hsync_end;
wire [10:0] hscan;
wire [10:0] hscan;
wire [10:0] vres;
wire [10:0] vres;
wire [10:0] vsync_start;
wire [10:0] vsync_start;
wire [10:0] vsync_end;
wire [10:0] vsync_end;
wire [10:0] vscan;
wire [10:0] vscan;
wire [fml_depth-1:0] baseaddress;
wire [fml_depth-1:0] baseaddress;
wire baseaddress_ack;
wire baseaddress_ack;
wire [17:0] nbursts;
wire [17:0] nbursts;
vgafb_ctlif #(
vgafb_ctlif #(
        .csr_addr(csr_addr),
        .csr_addr(csr_addr),
        .fml_depth(fml_depth)
        .fml_depth(fml_depth)
) ctlif (
) ctlif (
        .sys_clk(sys_clk),
        .sys_clk(sys_clk),
        .sys_rst(sys_rst),
        .sys_rst(sys_rst),
        .csr_a(csr_a),
        .csr_a(csr_a),
        .csr_we(csr_we),
        .csr_we(csr_we),
        .csr_di(csr_di),
        .csr_di(csr_di),
        .csr_do(csr_do),
        .csr_do(csr_do),
        .vga_rst(vga_rst),
        .vga_rst(vga_rst),
        .hres(hres),
        .hres(hres),
        .hsync_start(hsync_start),
        .hsync_start(hsync_start),
        .hsync_end(hsync_end),
        .hsync_end(hsync_end),
        .hscan(hscan),
        .hscan(hscan),
        .vres(vres),
        .vres(vres),
        .vsync_start(vsync_start),
        .vsync_start(vsync_start),
        .vsync_end(vsync_end),
        .vsync_end(vsync_end),
        .vscan(vscan),
        .vscan(vscan),
        .baseaddress(baseaddress),
        .baseaddress(baseaddress),
        .baseaddress_ack(baseaddress_ack),
        .baseaddress_ack(baseaddress_ack),
        .nbursts(nbursts),
        .nbursts(nbursts),
        .vga_sda(vga_sda),
        .vga_sda(vga_sda),
        .vga_sdc(vga_sdc)
        .vga_sdc(vga_sdc)
);
);
/*
/*
 * Generate signal data
 * Generate signal data
 */
 */
reg hsync_n;
reg hsync_n;
reg vsync_n;
reg vsync_n;
wire pixel_valid;
wire pixel_valid;
wire [15:0] pixel_fb;
wire [15:0] pixel_fb;
wire pixel_ack;
wire pixel_ack;
wire [15:0] pixel;
wire [15:0] pixel;
wire fifo_full;
wire fifo_full;
reg hactive;
reg hactive;
reg vactive;
reg vactive;
wire active = hactive & vactive;
wire active = hactive & vactive;
assign pixel = active ? pixel_fb : 16'h0000;
assign pixel = active ? pixel_fb : 16'h0000;
wire generate_en;
wire generate_en;
reg [10:0] hcounter;
reg [10:0] hcounter;
reg [10:0] vcounter;
reg [10:0] vcounter;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(vga_rst) begin
        if(vga_rst) begin
                hcounter <= 10'd0;
                hcounter <= 10'd0;
                vcounter <= 10'd0;
                vcounter <= 10'd0;
                hactive <= 1'b0;
                hactive <= 1'b0;
                hsync_n <= 1'b1;
                hsync_n <= 1'b1;
                vactive <= 1'b0;
                vactive <= 1'b0;
                vsync_n <= 1'b1;
                vsync_n <= 1'b1;
        end else begin
        end else begin
                if(generate_en) begin
                if(generate_en) begin
                        hcounter <= hcounter + 10'd1;
                        hcounter <= hcounter + 10'd1;
                        if(hcounter == 10'd0) hactive <= 1'b1;
                        if(hcounter == 10'd0) hactive <= 1'b1;
                        if(hcounter == hres) hactive <= 1'b0;
                        if(hcounter == hres) hactive <= 1'b0;
                        if(hcounter == hsync_start) hsync_n <= 1'b0;
                        if(hcounter == hsync_start) hsync_n <= 1'b0;
                        if(hcounter == hsync_end) hsync_n <= 1'b1;
                        if(hcounter == hsync_end) hsync_n <= 1'b1;
                        if(hcounter == hscan) begin
                        if(hcounter == hscan) begin
                                hcounter <= 10'd0;
                                hcounter <= 10'd0;
                                if(vcounter == vscan)
                                if(vcounter == vscan)
                                        vcounter <= 10'd0;
                                        vcounter <= 10'd0;
                                else
                                else
                                        vcounter <= vcounter + 10'd1;
                                        vcounter <= vcounter + 10'd1;
                        end
                        end
                        if(vcounter == 10'd0) vactive <= 1'b1;
                        if(vcounter == 10'd0) vactive <= 1'b1;
                        if(vcounter == vres) vactive <= 1'b0;
                        if(vcounter == vres) vactive <= 1'b0;
                        if(vcounter == vsync_start) vsync_n <= 1'b0;
                        if(vcounter == vsync_start) vsync_n <= 1'b0;
                        if(vcounter == vsync_end) vsync_n <= 1'b1;
                        if(vcounter == vsync_end) vsync_n <= 1'b1;
                end
                end
        end
        end
end
end
assign generate_en = ~fifo_full & (~active | pixel_valid);
assign generate_en = ~fifo_full & (~active | pixel_valid);
assign pixel_ack = ~fifo_full & active & pixel_valid;
assign pixel_ack = ~fifo_full & active & pixel_valid;
vgafb_pixelfeed #(
vgafb_pixelfeed #(
        .fml_depth(fml_depth)
        .fml_depth(fml_depth)
) pixelfeed (
) pixelfeed (
        .sys_clk(sys_clk),
        .sys_clk(sys_clk),
        .sys_rst(sys_rst),
        .sys_rst(sys_rst),
        .vga_rst(vga_rst),
        .vga_rst(vga_rst),
        .nbursts(nbursts),
        .nbursts(nbursts),
        .baseaddress(baseaddress),
        .baseaddress(baseaddress),
        .baseaddress_ack(baseaddress_ack),
        .baseaddress_ack(baseaddress_ack),
        .fml_adr(fml_adr),
        .fml_adr(fml_adr),
        .fml_stb(fml_stb),
        .fml_stb(fml_stb),
        .fml_ack(fml_ack),
        .fml_ack(fml_ack),
        .fml_di(fml_di),
        .fml_di(fml_di),
        .dcb_stb(dcb_stb),
        .dcb_stb(dcb_stb),
        .dcb_adr(dcb_adr),
        .dcb_adr(dcb_adr),
        .dcb_dat(dcb_dat),
        .dcb_dat(dcb_dat),
        .dcb_hit(dcb_hit),
        .dcb_hit(dcb_hit),
        .pixel_valid(pixel_valid),
        .pixel_valid(pixel_valid),
        .pixel(pixel_fb),
        .pixel(pixel_fb),
        .pixel_ack(pixel_ack)
        .pixel_ack(pixel_ack)
);
);
/*
/*
 * System clock to VGA clock domain crossing is
 * System clock to VGA clock domain crossing is
 * acheived by an asynchronous FIFO.
 * acheived by an asynchronous FIFO.
 *
 *
 * Bits 0-15 are RGB565 pixel data
 * Bits 0-15 are RGB565 pixel data
 * Bit 16 is negated Horizontal Sync
 * Bit 16 is negated Horizontal Sync
 * Bit 17 is negated Verical Sync
 * Bit 17 is negated Verical Sync
 */
 */
wire [17:0] fifo_do;
wire [17:0] fifo_do;
asfifo #(
asfifo #(
        .data_width(18),
        .data_width(18),
        .address_width(6)
        .address_width(6)
) fifo (
) fifo (
        .data_out(fifo_do),
        .data_out(fifo_do),
        .empty(),
        .empty(),
        .read_en(1'b1),
        .read_en(1'b1),
        .clk_read(vga_clk),
        .clk_read(vga_clk),
        .data_in({vsync_n, hsync_n, pixel}),
        .data_in({vsync_n, hsync_n, pixel}),
        .full(fifo_full),
        .full(fifo_full),
        .write_en(generate_en),
        .write_en(generate_en),
        .clk_write(sys_clk),
        .clk_write(sys_clk),
        .rst(vga_rst)
        .rst(vga_rst)
);
);
/*
/*
 * Drive the VGA pads.
 * Drive the VGA pads.
 * RGB565 -> RGB888 color space conversion is also performed here
 * RGB565 -> RGB888 color space conversion is also performed here
 * by bit shifting and replicating the most significant bits of
 * by bit shifting and replicating the most significant bits of
 * the input into the least significant bits of the output left
 * the input into the least significant bits of the output left
 * undefined by the shifting.
 * undefined by the shifting.
 */
 */
assign vga_sync_n = 1'b0; /* Sync-on-Green is not implemented */
assign vga_sync_n = 1'b0; /* Sync-on-Green is not implemented */
assign vga_psave_n = 1'b1;
assign vga_psave_n = 1'b1;
assign vga_blank_n = 1'b1;
assign vga_blank_n = 1'b1;
always @(posedge vga_clk) begin
always @(posedge vga_clk) begin
        vga_vsync_n <= fifo_do[17];
        vga_vsync_n <= fifo_do[17];
        vga_hsync_n <= fifo_do[16];
        vga_hsync_n <= fifo_do[16];
        vga_r <= {fifo_do[15:11], fifo_do[15:13]};
        vga_r <= {fifo_do[15:11], fifo_do[15:13]};
        vga_g <= {fifo_do[10:5], fifo_do[10:9]};
        vga_g <= {fifo_do[10:5], fifo_do[10:9]};
        vga_b <= {fifo_do[4:0], fifo_do[4:2]};
        vga_b <= {fifo_do[4:0], fifo_do[4:2]};
end
end
endmodule
endmodule
vgafb/rtl/vgafb_pixelfeed.v0000644000175000017500000001166711411201677016444 0ustar  lekernellekernel/*
vgafb/rtl/vgafb_pixelfeed.v0000644000175000017500000001166711411201677016444 0ustar  lekernellekernel/*
 * Milkymist VJ SoC
 * Milkymist VJ SoC
 * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
 * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
 *
 *
 * This program is free software: you can redistribute it and/or modify
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 * the Free Software Foundation, version 3 of the License.
 *
 *
 * This program is distributed in the hope that it will be useful,
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 *
 *
 * You should have received a copy of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 * along with this program.  If not, see .
 */
 */
module vgafb_pixelfeed #(
module vgafb_pixelfeed #(
        parameter fml_depth = 26
        parameter fml_depth = 26
) (
) (
        input sys_clk,
        input sys_clk,
        /* We must take into account both resets :
        /* We must take into account both resets :
         * VGA reset should not interrupt a pending FML request
         * VGA reset should not interrupt a pending FML request
         * but system reset should.
         * but system reset should.
         */
         */
        input sys_rst,
        input sys_rst,
        input vga_rst,
        input vga_rst,
        input [17:0] nbursts,
        input [17:0] nbursts,
        input [fml_depth-1:0] baseaddress,
        input [fml_depth-1:0] baseaddress,
        output baseaddress_ack,
        output baseaddress_ack,
        output reg [fml_depth-1:0] fml_adr,
        output reg [fml_depth-1:0] fml_adr,
        output reg fml_stb,
        output reg fml_stb,
        input fml_ack,
        input fml_ack,
        input [63:0] fml_di,
        input [63:0] fml_di,
        output reg dcb_stb,
        output reg dcb_stb,
        output [fml_depth-1:0] dcb_adr,
        output [fml_depth-1:0] dcb_adr,
        input [63:0] dcb_dat,
        input [63:0] dcb_dat,
        input dcb_hit,
        input dcb_hit,
        output pixel_valid,
        output pixel_valid,
        output [15:0] pixel,
        output [15:0] pixel,
        input pixel_ack
        input pixel_ack
);
);
/* FIFO that stores the 64-bit bursts and slices it in 16-bit words */
/* FIFO that stores the 64-bit bursts and slices it in 16-bit words */
reg fifo_source_cache;
reg fifo_source_cache;
reg fifo_stb;
reg fifo_stb;
wire fifo_valid;
wire fifo_valid;
vgafb_fifo64to16 fifo64to16(
vgafb_fifo64to16 fifo64to16(
        .sys_clk(sys_clk),
        .sys_clk(sys_clk),
        .vga_rst(vga_rst),
        .vga_rst(vga_rst),
        .stb(fifo_stb),
        .stb(fifo_stb),
        .di(fifo_source_cache ? dcb_dat : fml_di),
        .di(fifo_source_cache ? dcb_dat : fml_di),
        .do_valid(fifo_valid),
        .do_valid(fifo_valid),
        .do(pixel),
        .do(pixel),
        .next(pixel_ack)
        .next(pixel_ack)
);
);
assign pixel_valid = fifo_valid;
assign pixel_valid = fifo_valid;
/* BURST COUNTER */
/* BURST COUNTER */
reg sof;
reg sof;
wire counter_en;
wire counter_en;
reg [17:0] bcounter;
reg [17:0] bcounter;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(vga_rst) begin
        if(vga_rst) begin
                bcounter <= 18'd1;
                bcounter <= 18'd1;
                sof <= 1'b1;
                sof <= 1'b1;
        end else begin
        end else begin
                if(counter_en) begin
                if(counter_en) begin
                        if(bcounter == nbursts) begin
                        if(bcounter == nbursts) begin
                                bcounter <= 18'd1;
                                bcounter <= 18'd1;
                                sof <= 1'b1;
                                sof <= 1'b1;
                        end else begin
                        end else begin
                                bcounter <= bcounter + 18'd1;
                                bcounter <= bcounter + 18'd1;
                                sof <= 1'b0;
                                sof <= 1'b0;
                        end
                        end
                end
                end
        end
        end
end
end
/* FML ADDRESS GENERATOR */
/* FML ADDRESS GENERATOR */
wire next_address;
wire next_address;
assign baseaddress_ack = sof & next_address;
assign baseaddress_ack = sof & next_address;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(sys_rst) begin
        if(sys_rst) begin
                fml_adr <= {fml_depth{1'b0}};
                fml_adr <= {fml_depth{1'b0}};
        end else begin
        end else begin
                if(next_address) begin
                if(next_address) begin
                        if(sof)
                        if(sof)
                                fml_adr <= baseaddress;
                                fml_adr <= baseaddress;
                        else
                        else
                                fml_adr <= fml_adr + {{fml_depth-6{1'b0}}, 6'd32};
                                fml_adr <= fml_adr + {{fml_depth-6{1'b0}}, 6'd32};
                end
                end
        end
        end
end
end
/* DCB ADDRESS GENERATOR */
/* DCB ADDRESS GENERATOR */
reg [1:0] dcb_index;
reg [1:0] dcb_index;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(dcb_stb)
        if(dcb_stb)
                dcb_index <= dcb_index + 2'd1;
                dcb_index <= dcb_index + 2'd1;
        else
        else
                dcb_index <= 2'd0;
                dcb_index <= 2'd0;
end
end
assign dcb_adr = {fml_adr[fml_depth-1:5], dcb_index, 3'b000};
assign dcb_adr = {fml_adr[fml_depth-1:5], dcb_index, 3'b000};
/* CONTROLLER */
/* CONTROLLER */
reg [3:0] state;
reg [3:0] state;
reg [3:0] next_state;
reg [3:0] next_state;
parameter IDLE          = 4'd0;
parameter IDLE          = 4'd0;
parameter TRYCACHE      = 4'd1;
parameter TRYCACHE      = 4'd1;
parameter CACHE1        = 4'd2;
parameter CACHE1        = 4'd2;
parameter CACHE2        = 4'd3;
parameter CACHE2        = 4'd3;
parameter CACHE3        = 4'd4;
parameter CACHE3        = 4'd4;
parameter CACHE4        = 4'd5;
parameter CACHE4        = 4'd5;
parameter FML1          = 4'd6;
parameter FML1          = 4'd6;
parameter FML2          = 4'd7;
parameter FML2          = 4'd7;
parameter FML3          = 4'd8;
parameter FML3          = 4'd8;
parameter FML4          = 4'd9;
parameter FML4          = 4'd9;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(sys_rst)
        if(sys_rst)
                state <= IDLE;
                state <= IDLE;
        else
        else
                state <= next_state;
                state <= next_state;
end
end
/*
/*
 * Do not put spurious data into the FIFO if the VGA reset
 * Do not put spurious data into the FIFO if the VGA reset
 * is asserted and released during the FML access. Getting
 * is asserted and released during the FML access. Getting
 * the FIFO out of sync would result in distorted pictures
 * the FIFO out of sync would result in distorted pictures
 * we really want to avoid.
 * we really want to avoid.
 */
 */
reg ignore;
reg ignore;
reg ignore_clear;
reg ignore_clear;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(vga_rst)
        if(vga_rst)
                ignore <= 1'b1;
                ignore <= 1'b1;
        else if(ignore_clear)
        else if(ignore_clear)
                ignore <= 1'b0;
                ignore <= 1'b0;
end
end
reg next_burst;
reg next_burst;
assign counter_en = next_burst;
assign counter_en = next_burst;
assign next_address = next_burst;
assign next_address = next_burst;
always @(*) begin
always @(*) begin
        next_state = state;
        next_state = state;
        fifo_stb = 1'b0;
        fifo_stb = 1'b0;
        next_burst = 1'b0;
        next_burst = 1'b0;
        fml_stb = 1'b0;
        fml_stb = 1'b0;
        ignore_clear = 1'b0;
        ignore_clear = 1'b0;
        dcb_stb = 1'b0;
        dcb_stb = 1'b0;
        fifo_source_cache = 1'b0;
        fifo_source_cache = 1'b0;
        case(state)
        case(state)
                IDLE: begin
                IDLE: begin
                        if(~fifo_valid & ~vga_rst) begin
                        if(~fifo_valid & ~vga_rst) begin
                                /* We're in need of pixels ! */
                                /* We're in need of pixels ! */
                                next_burst = 1'b1;
                                next_burst = 1'b1;
                                ignore_clear = 1'b1;
                                ignore_clear = 1'b1;
                                next_state = TRYCACHE;
                                next_state = TRYCACHE;
                        end
                        end
                end
                end
                /* Try to fetch from L2 first */
                /* Try to fetch from L2 first */
                TRYCACHE: begin
                TRYCACHE: begin
                        dcb_stb = 1'b1;
                        dcb_stb = 1'b1;
                        next_state = CACHE1;
                        next_state = CACHE1;
                end
                end
                CACHE1: begin
                CACHE1: begin
                        fifo_source_cache = 1'b1;
                        fifo_source_cache = 1'b1;
                        if(dcb_hit) begin
                        if(dcb_hit) begin
                                dcb_stb = 1'b1;
                                dcb_stb = 1'b1;
                                if(~ignore) fifo_stb = 1'b1;
                                if(~ignore) fifo_stb = 1'b1;
                                next_state = CACHE2;
                                next_state = CACHE2;
                        end else
                        end else
                                next_state = FML1; /* Not in L2 cache, fetch from DRAM */
                                next_state = FML1; /* Not in L2 cache, fetch from DRAM */
                end
                end
                /* No need to check for cache hits anymore:
                /* No need to check for cache hits anymore:
                 * - we fetched from the beginning of a line
                 * - we fetched from the beginning of a line
                 * - we fetch exactly a line
                 * - we fetch exactly a line
                 * - we do not release dcb_stb so the cache controller locks the line
                 * - we do not release dcb_stb so the cache controller locks the line
                 * Therefore, next 3 fetchs always are cache hits.
                 * Therefore, next 3 fetchs always are cache hits.
                 */
                 */
                CACHE2: begin
                CACHE2: begin
                        dcb_stb = 1'b1;
                        dcb_stb = 1'b1;
                        fifo_source_cache = 1'b1;
                        fifo_source_cache = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        next_state = CACHE3;
                        next_state = CACHE3;
                end
                end
                CACHE3: begin
                CACHE3: begin
                        dcb_stb = 1'b1;
                        dcb_stb = 1'b1;
                        fifo_source_cache = 1'b1;
                        fifo_source_cache = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        next_state = CACHE4;
                        next_state = CACHE4;
                end
                end
                CACHE4: begin
                CACHE4: begin
                        fifo_source_cache = 1'b1;
                        fifo_source_cache = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        next_state = IDLE;
                        next_state = IDLE;
                end
                end
                FML1: begin
                FML1: begin
                        fml_stb = 1'b1;
                        fml_stb = 1'b1;
                        if(fml_ack) begin
                        if(fml_ack) begin
                                if(~ignore) fifo_stb = 1'b1;
                                if(~ignore) fifo_stb = 1'b1;
                                next_state = FML2;
                                next_state = FML2;
                        end
                        end
                end
                end
                FML2: begin
                FML2: begin
                        if(~ignore) fifo_stb = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        next_state = FML3;
                        next_state = FML3;
                end
                end
                FML3: begin
                FML3: begin
                        if(~ignore) fifo_stb = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        next_state = FML4;
                        next_state = FML4;
                end
                end
                FML4: begin
                FML4: begin
                        if(~ignore) fifo_stb = 1'b1;
                        if(~ignore) fifo_stb = 1'b1;
                        next_state = IDLE;
                        next_state = IDLE;
                end
                end
        endcase
        endcase
end
end
endmodule
endmodule
vgafb/rtl/vgafb_fifo64to16.v0000644000175000017500000000334611411201677016301 0ustar  lekernellekernel/*
vgafb/rtl/vgafb_fifo64to16.v0000644000175000017500000000334611411201677016301 0ustar  lekernellekernel/*
 * Milkymist VJ SoC
 * Milkymist VJ SoC
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 *
 *
 * This program is free software: you can redistribute it and/or modify
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 * the Free Software Foundation, version 3 of the License.
 *
 *
 * This program is distributed in the hope that it will be useful,
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 *
 *
 * You should have received a copy of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 * along with this program.  If not, see .
 */
 */
module vgafb_fifo64to16(
module vgafb_fifo64to16(
        input sys_clk,
        input sys_clk,
        input vga_rst,
        input vga_rst,
        input stb,
        input stb,
        input [63:0] di,
        input [63:0] di,
        output do_valid,
        output do_valid,
        output reg [15:0] do,
        output reg [15:0] do,
        input next /* should only be asserted when do_valid = 1 */
        input next /* should only be asserted when do_valid = 1 */
);
);
/*
/*
 * FIFO can hold 4 64-bit words
 * FIFO can hold 4 64-bit words
 * that is 16 16-bit words.
 * that is 16 16-bit words.
 */
 */
reg [63:0] storage[0:3];
reg [63:0] storage[0:3];
reg [1:0] produce; /* in 64-bit words */
reg [1:0] produce; /* in 64-bit words */
reg [3:0] consume; /* in 16-bit words */
reg [3:0] consume; /* in 16-bit words */
/*
/*
 * 16-bit words stored in the FIFO, 0-16 (17 possible values)
 * 16-bit words stored in the FIFO, 0-16 (17 possible values)
 */
 */
reg [4:0] level;
reg [4:0] level;
wire [63:0] do64;
wire [63:0] do64;
assign do64 = storage[consume[3:2]];
assign do64 = storage[consume[3:2]];
always @(*) begin
always @(*) begin
        case(consume[1:0])
        case(consume[1:0])
                2'd0: do <= do64[63:48];
                2'd0: do <= do64[63:48];
                2'd1: do <= do64[47:32];
                2'd1: do <= do64[47:32];
                2'd2: do <= do64[31:16];
                2'd2: do <= do64[31:16];
                2'd3: do <= do64[15:0];
                2'd3: do <= do64[15:0];
        endcase
        endcase
end
end
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(vga_rst) begin
        if(vga_rst) begin
                produce = 2'd0;
                produce = 2'd0;
                consume = 4'd0;
                consume = 4'd0;
                level = 5'd0;
                level = 5'd0;
        end else begin
        end else begin
                if(stb) begin
                if(stb) begin
                        storage[produce] = di;
                        storage[produce] = di;
                        produce = produce + 2'd1;
                        produce = produce + 2'd1;
                        level = level + 5'd4;
                        level = level + 5'd4;
                end
                end
                if(next) begin /* next should only be asserted when do_valid = 1 */
                if(next) begin /* next should only be asserted when do_valid = 1 */
                        consume = consume + 4'd1;
                        consume = consume + 4'd1;
                        level = level - 5'd1;
                        level = level - 5'd1;
                end
                end
        end
        end
end
end
assign do_valid = ~(level == 5'd0);
assign do_valid = ~(level == 5'd0);
endmodule
endmodule
vgafb/rtl/vgafb_ctlif.v0000644000175000017500000000630011413143411015555 0ustar  lekernellekernel/*
vgafb/rtl/vgafb_ctlif.v0000644000175000017500000000630011413143411015555 0ustar  lekernellekernel/*
 * Milkymist VJ SoC
 * Milkymist VJ SoC
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 *
 *
 * This program is free software: you can redistribute it and/or modify
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 * the Free Software Foundation, version 3 of the License.
 *
 *
 * This program is distributed in the hope that it will be useful,
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 *
 *
 * You should have received a copy of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 * along with this program.  If not, see .
 */
 */
module vgafb_ctlif #(
module vgafb_ctlif #(
        parameter csr_addr = 4'h0,
        parameter csr_addr = 4'h0,
        parameter fml_depth = 26
        parameter fml_depth = 26
) (
) (
        input sys_clk,
        input sys_clk,
        input sys_rst,
        input sys_rst,
        input [13:0] csr_a,
        input [13:0] csr_a,
        input csr_we,
        input csr_we,
        input [31:0] csr_di,
        input [31:0] csr_di,
        output reg [31:0] csr_do,
        output reg [31:0] csr_do,
        output reg vga_rst,
        output reg vga_rst,
        output reg [10:0] hres,
        output reg [10:0] hres,
        output reg [10:0] hsync_start,
        output reg [10:0] hsync_start,
        output reg [10:0] hsync_end,
        output reg [10:0] hsync_end,
        output reg [10:0] hscan,
        output reg [10:0] hscan,
        output reg [10:0] vres,
        output reg [10:0] vres,
        output reg [10:0] vsync_start,
        output reg [10:0] vsync_start,
        output reg [10:0] vsync_end,
        output reg [10:0] vsync_end,
        output reg [10:0] vscan,
        output reg [10:0] vscan,
        output reg [fml_depth-1:0] baseaddress,
        output reg [fml_depth-1:0] baseaddress,
        input baseaddress_ack,
        input baseaddress_ack,
        output reg [17:0] nbursts,
        output reg [17:0] nbursts,
        inout vga_sda,
        inout vga_sda,
        output reg vga_sdc
        output reg vga_sdc
);
);
/* I2C */
/* I2C */
reg sda_1;
reg sda_1;
reg sda_2;
reg sda_2;
reg sda_oe;
reg sda_oe;
reg sda_o;
reg sda_o;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        sda_1 <= vga_sda;
        sda_1 <= vga_sda;
        sda_2 <= sda_1;
        sda_2 <= sda_1;
end
end
assign vga_sda = (sda_oe & ~sda_o) ? 1'b0 : 1'bz;
assign vga_sda = (sda_oe & ~sda_o) ? 1'b0 : 1'bz;
/* */
/* */
reg [fml_depth-1:0] baseaddress_act;
reg [fml_depth-1:0] baseaddress_act;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(sys_rst)
        if(sys_rst)
                baseaddress_act <= {fml_depth{1'b0}};
                baseaddress_act <= {fml_depth{1'b0}};
        else if(baseaddress_ack)
        else if(baseaddress_ack)
                baseaddress_act <= baseaddress;
                baseaddress_act <= baseaddress;
end
end
wire csr_selected = csr_a[13:10] == csr_addr;
wire csr_selected = csr_a[13:10] == csr_addr;
always @(posedge sys_clk) begin
always @(posedge sys_clk) begin
        if(sys_rst) begin
        if(sys_rst) begin
                csr_do <= 32'd0;
                csr_do <= 32'd0;
                vga_rst <= 1'b1;
                vga_rst <= 1'b1;
                hres <= 10'd640;
                hres <= 10'd640;
                hsync_start <= 10'd656;
                hsync_start <= 10'd656;
                hsync_end <= 10'd752;
                hsync_end <= 10'd752;
                hscan <= 10'd799;
                hscan <= 10'd799;
                vres <= 10'd480;
                vres <= 10'd480;
                vsync_start <= 10'd491;
                vsync_start <= 10'd491;
                vsync_end <= 10'd493;
                vsync_end <= 10'd493;
                vscan <= 10'd523;
                vscan <= 10'd523;
                baseaddress <= {fml_depth{1'b0}};
                baseaddress <= {fml_depth{1'b0}};
                nbursts <= 18'd19200;
                nbursts <= 18'd19200;
                sda_oe <= 1'b0;
                sda_oe <= 1'b0;
                sda_o <= 1'b0;
                sda_o <= 1'b0;
                vga_sdc <= 1'b0;
                vga_sdc <= 1'b0;
        end else begin
        end else begin
                csr_do <= 32'd0;
                csr_do <= 32'd0;
                if(csr_selected) begin
                if(csr_selected) begin
                        if(csr_we) begin
                        if(csr_we) begin
                                case(csr_a[3:0])
                                case(csr_a[3:0])
                                        4'd0: vga_rst <= csr_di[0];
                                        4'd0: vga_rst <= csr_di[0];
                                        4'd1: hres <= csr_di[10:0];
                                        4'd1: hres <= csr_di[10:0];
                                        4'd2: hsync_start <= csr_di[10:0];
                                        4'd2: hsync_start <= csr_di[10:0];
                                        4'd3: hsync_end <= csr_di[10:0];
                                        4'd3: hsync_end <= csr_di[10:0];
                                        4'd4: hscan <= csr_di[10:0];
                                        4'd4: hscan <= csr_di[10:0];
                                        4'd5: vres <= csr_di[10:0];
                                        4'd5: vres <= csr_di[10:0];
                                        4'd6: vsync_start <= csr_di[10:0];
                                        4'd6: vsync_start <= csr_di[10:0];
                                        4'd7: vsync_end <= csr_di[10:0];
                                        4'd7: vsync_end <= csr_di[10:0];
                                        4'd8: vscan <= csr_di[10:0];
                                        4'd8: vscan <= csr_di[10:0];
                                        4'd9: baseaddress <= csr_di[fml_depth-1:0];
                                        4'd9: baseaddress <= csr_di[fml_depth-1:0];
                                        // 10: baseaddress_act is read-only for Wishbone
                                        // 10: baseaddress_act is read-only for Wishbone
                                        4'd11: nbursts <= csr_di[17:0];
                                        4'd11: nbursts <= csr_di[17:0];
                                        4'd12: begin
                                        4'd12: begin
                                                sda_o <= csr_di[1];
                                                sda_o <= csr_di[1];
                                                sda_oe <= csr_di[2];
                                                sda_oe <= csr_di[2];
                                                vga_sdc <= csr_di[3];
                                                vga_sdc <= csr_di[3];
                                        end
                                        end
                                endcase
                                endcase
                        end
                        end
                        case(csr_a[3:0])
                        case(csr_a[3:0])
                                4'd0: csr_do <= vga_rst;
                                4'd0: csr_do <= vga_rst;
                                4'd1: csr_do <= hres;
                                4'd1: csr_do <= hres;
                                4'd2: csr_do <= hsync_start;
                                4'd2: csr_do <= hsync_start;
                                4'd3: csr_do <= hsync_end;
                                4'd3: csr_do <= hsync_end;
                                4'd4: csr_do <= hscan;
                                4'd4: csr_do <= hscan;
                                4'd5: csr_do <= vres;
                                4'd5: csr_do <= vres;
                                4'd6: csr_do <= vsync_start;
                                4'd6: csr_do <= vsync_start;
                                4'd7: csr_do <= vsync_end;
                                4'd7: csr_do <= vsync_end;
                                4'd8: csr_do <= vscan;
                                4'd8: csr_do <= vscan;
                                4'd9: csr_do <= baseaddress;
                                4'd9: csr_do <= baseaddress;
                                4'd10: csr_do <= baseaddress_act;
                                4'd10: csr_do <= baseaddress_act;
                                4'd11: csr_do <= nbursts;
                                4'd11: csr_do <= nbursts;
                                4'd12: csr_do <= {vga_sdc, sda_oe, sda_o, sda_2};
                                4'd12: csr_do <= {vga_sdc, sda_oe, sda_o, sda_2};
                        endcase
                        endcase
                end
                end
        end
        end
end
end
endmodule
endmodule
vgafb/test/0000755000175000017500000000000011411201677013306 5ustar  lekernellekernelvgafb/test/tb_pixelfeed.v0000644000175000017500000000250711411201677016133 0ustar  lekernellekernel/*
vgafb/test/0000755000175000017500000000000011411201677013306 5ustar  lekernellekernelvgafb/test/tb_pixelfeed.v0000644000175000017500000000250711411201677016133 0ustar  lekernellekernel/*
 * Milkymist VJ SoC
 * Milkymist VJ SoC
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
 *
 *
 * This program is free software: you can redistribute it and/or modify
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 * the Free Software Foundation, version 3 of the License.
 *
 *
 * This program is distributed in the hope that it will be useful,
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * GNU General Public License for more details.
 *
 *
 * You should have received a copy of the GNU General Public License
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 * along with this program.  If not, see .
 */
 */
module tb_pixelfeed();
module tb_pixelfeed();
reg sys_clk;
reg sys_clk;
initial sys_clk = 1'b0;
initial sys_clk = 1'b0;
always #5 sys_clk = ~sys_clk;
always #5 sys_clk = ~sys_clk;
reg sys_rst;
reg sys_rst;
reg vga_rst;
reg vga_rst;
wire pixel_valid;
wire pixel_valid;
wire fml_stb;
wire fml_stb;
wire [25:0] fml_adr;
wire [25:0] fml_adr;
initial begin
initial begin
        sys_rst = 1'b1;
        sys_rst = 1'b1;
        vga_rst = 1'b1;
        vga_rst = 1'b1;
        #20 sys_rst = 1'b0;
        #20 sys_rst = 1'b0;
        #20 vga_rst = 1'b0;
        #20 vga_rst = 1'b0;
end
end
vgafb_pixelfeed dut(
vgafb_pixelfeed dut(
        .sys_clk(sys_clk),
        .sys_clk(sys_clk),
        .sys_rst(sys_rst),
        .sys_rst(sys_rst),
        .vga_rst(vga_rst),
        .vga_rst(vga_rst),
        .nbursts(18'd100),
        .nbursts(18'd100),
        .baseaddress(26'd1024),
        .baseaddress(26'd1024),
        .baseaddress_ack(),
        .baseaddress_ack(),
        .fml_adr(fml_adr),
        .fml_adr(fml_adr),
        .fml_stb(fml_stb),
        .fml_stb(fml_stb),
        .fml_ack(fml_stb),
        .fml_ack(fml_stb),
        .fml_di(64'hcafebabedeadbeef),
        .fml_di(64'hcafebabedeadbeef),
        .pixel_valid(pixel_valid),
        .pixel_valid(pixel_valid),
        .pixel(),
        .pixel(),
        .pixel_ack(pixel_valid)
        .pixel_ack(pixel_valid)
);
);
always @(posedge sys_clk) $display("%x", fml_adr);
always @(posedge sys_clk) $display("%x", fml_adr);
initial #600 $finish;
initial #600 $finish;
endmodule
endmodule
vgafb/test/Makefile0000644000175000017500000000032411411201677014745 0ustar  lekernellekernelSOURCES_PIXELFEED=tb_pixelfeed.v ../rtl/vgafb_pixelfeed.v ../rtl/vgafb_fifo64to16.v
vgafb/test/Makefile0000644000175000017500000000032411411201677014745 0ustar  lekernellekernelSOURCES_PIXELFEED=tb_pixelfeed.v ../rtl/vgafb_pixelfeed.v ../rtl/vgafb_fifo64to16.v
all: pixelfeed
all: pixelfeed
pixelfeed: $(SOURCES_PIXELFEED)
pixelfeed: $(SOURCES_PIXELFEED)
        cver $(SOURCES_PIXELFEED)
        cver $(SOURCES_PIXELFEED)
clean:
clean:
        rm -f verilog.log
        rm -f verilog.log
.PHONY: clean pixelfeed
.PHONY: clean pixelfeed
vgafb/doc/0000755000175000017500000000000011422324710013070 5ustar  lekernellekernelvgafb/doc/Makefile0000644000175000017500000000041211411201677014531 0ustar  lekernellekernelTEX=vgafb.tex
vgafb/doc/0000755000175000017500000000000011431543453013077 5ustar  lekernellekernelvgafb/doc/Makefile0000644000175000017500000000041211411201677014531 0ustar  lekernellekernelTEX=vgafb.tex
DVI=$(TEX:.tex=.dvi)
DVI=$(TEX:.tex=.dvi)
PS=$(TEX:.tex=.ps)
PS=$(TEX:.tex=.ps)
PDF=$(TEX:.tex=.pdf)
PDF=$(TEX:.tex=.pdf)
AUX=$(TEX:.tex=.aux)
AUX=$(TEX:.tex=.aux)
LOG=$(TEX:.tex=.log)
LOG=$(TEX:.tex=.log)
all: $(PDF)
all: $(PDF)
%.dvi: %.tex
%.dvi: %.tex
        latex $<
        latex $<
%.ps: %.dvi
%.ps: %.dvi
        dvips $<
        dvips $<
%.pdf: %.ps
%.pdf: %.ps
        ps2pdf $<
        ps2pdf $<
clean:
clean:
        rm -f $(DVI) $(PS) $(PDF) $(AUX) $(LOG)
        rm -f $(DVI) $(PS) $(PDF) $(AUX) $(LOG)
.PHONY: clean
.PHONY: clean
vgafb/doc/vgafb.tex0000644000175000017500000001103511422303532014676 0ustar  lekernellekernel\documentclass[a4paper,11pt]{article}
vgafb/doc/vgafb.tex0000644000175000017500000001103511422303532014676 0ustar  lekernellekernel\documentclass[a4paper,11pt]{article}
\usepackage{fullpage}
\usepackage{fullpage}
\usepackage[latin1]{inputenc}
\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[T1]{fontenc}
\usepackage[normalem]{ulem}
\usepackage[normalem]{ulem}
\usepackage[english]{babel}
\usepackage[english]{babel}
\usepackage{listings,babel}
\usepackage{listings,babel}
\lstset{breaklines=true,basicstyle=\ttfamily}
\lstset{breaklines=true,basicstyle=\ttfamily}
\usepackage{graphicx}
\usepackage{graphicx}
\usepackage{moreverb}
\usepackage{moreverb}
\usepackage{url}
\usepackage{url}
\usepackage{amsmath}
\usepackage{amsmath}
\title{VGA framebuffer}
\title{VGA framebuffer}
\author{S\'ebastien Bourdeauducq}
\author{S\'ebastien Bourdeauducq}
\date{July 2010}
\date{July 2010}
\begin{document}
\begin{document}
\setlength{\parindent}{0pt}
\setlength{\parindent}{0pt}
\setlength{\parskip}{5pt}
\setlength{\parskip}{5pt}
\maketitle{}
\maketitle{}
\section{Specifications}
\section{Specifications}
The VGA framebuffer core enables a system-on-chip to support a VGA video output with the picture read from a memory framebuffer.
The VGA framebuffer core enables a system-on-chip to support a VGA video output with the picture read from a memory framebuffer.
The core directly drives a 3-channel 8-bit digital to analog converter and the horizontal and vertical synchronization signals.
The core directly drives a 3-channel 8-bit digital to analog converter and the horizontal and vertical synchronization signals.
The framebuffer is read with a 4x64 FastMemoryLink (FML) master; and a CSR interface is implemented for configuring the video output.
The framebuffer is read with a 4x64 FastMemoryLink (FML) master; and a CSR interface is implemented for configuring the video output.
\section{Registers}
\section{Registers}
\subsection{Control register, offset 0x00}
\subsection{Control register, offset 0x00}
This register enables or disables the video output by setting or clearing the reset bit 0. At reset, the default value is 0x1.
This register enables or disables the video output by setting or clearing the reset bit 0. At reset, the default value is 0x1.
\subsection{Horizontal video parameters, offsets 0x04, 0x08, 0x0c and 0x10}
\subsection{Horizontal video parameters, offsets 0x04, 0x08, 0x0c and 0x10}
Those registers set respectively:
Those registers set respectively:
\begin{itemize}
\begin{itemize}
\item the horizontal size of the active video area (the horizontal resolution)
\item the horizontal size of the active video area (the horizontal resolution)
\item the position of the beginning of the horizontal sync pulse in the scan line, in pixel clocks
\item the position of the beginning of the horizontal sync pulse in the scan line, in pixel clocks
\item the position of the end of the horizontal sync pulse in the scan line, in pixel clocks
\item the position of the end of the horizontal sync pulse in the scan line, in pixel clocks
\item the total length of the horizontal scan line minus one, in pixels
\item the total length of the horizontal scan line minus one, in pixels
\end{itemize}
\end{itemize}
The default values are for the standard VGA resolution of 640x480 at 60Hz with a 25MHz pixel clock.
The default values are for the standard VGA resolution of 640x480 at 60Hz with a 25MHz pixel clock.
\subsection{Vertical video parameters, offsets 0x14, 0x18, 0x1c and 0x20}
\subsection{Vertical video parameters, offsets 0x14, 0x18, 0x1c and 0x20}
Those registers set respectively:
Those registers set respectively:
\begin{itemize}
\begin{itemize}
\item the vertical size of the active video area (the vertical resolution)
\item the vertical size of the active video area (the vertical resolution)
\item the position of the beginning of the vertical sync pulse. The unit is the horizontal scan line.
\item the position of the beginning of the vertical sync pulse. The unit is the horizontal scan line.
\item the position of the end of the vertical sync pulse. Same unit as above.
\item the position of the end of the vertical sync pulse. Same unit as above.
\item the total count of horizontal scan lines minus one. Same unit as above.
\item the total count of horizontal scan lines minus one. Same unit as above.
\end{itemize}
\end{itemize}
The default values are for the standard VGA resolution of 640x480 at 60Hz with a 25MHz pixel clock.
The default values are for the standard VGA resolution of 640x480 at 60Hz with a 25MHz pixel clock.
\subsection{DMA control registers, offsets 0x24, 0x28 and 0x2c}
\subsection{DMA control registers, offsets 0x24, 0x28 and 0x2c}
The register 0x24 defines the base address of the framebuffer. That framebuffer is basic progressive scan buffer using the RGB565 pixel format.
The register 0x24 defines the base address of the framebuffer. That framebuffer is basic progressive scan buffer using the RGB565 pixel format.
When register 0x24 is written, the framebuffer address is not updated immediately. Instead, the VGA core waits for the end of the vertical active video area and only starts fetching data from the new framebuffer at the beginning of the next frame. This enables the use of multiple framebuffers without any tearing or flickering artifacts. The address from which the core is currently reading data is available in register 0x28.
When register 0x24 is written, the framebuffer address is not updated immediately. Instead, the VGA core waits for the end of the vertical active video area and only starts fetching data from the new framebuffer at the beginning of the next frame. This enables the use of multiple framebuffers without any tearing or flickering artifacts. The address from which the core is currently reading data is available in register 0x28.
When registers 0x24 and 0x28 have different values, a framebuffer address change is pending. When they have the same values, the frame being displayed is the latest that was asked for.
When registers 0x24 and 0x28 have different values, a framebuffer address change is pending. When they have the same values, the frame being displayed is the latest that was asked for.
The framebuffer must be aligned to the start of a FML burst ($\frac{4 \cdot 64}{8}$ bytes).
The framebuffer must be aligned to the start of a FML burst ($\frac{4 \cdot 64}{8}$ bytes).
Register 0x2c defines the number of FML bursts required to fill a complete screen. This is typically set to:
Register 0x2c defines the number of FML bursts required to fill a complete screen. This is typically set to:
\[
\[
\frac{\text{horizontal resolution} \cdot \text{vertical resolution} \cdot 16}{4 \cdot 64}
\frac{\text{horizontal resolution} \cdot \text{vertical resolution} \cdot 16}{4 \cdot 64}
\]
\]
The screen resolution must be set so that this number is integer. This is the case with common VGA resolutions.
The screen resolution must be set so that this number is integer. This is the case with common VGA resolutions.
\subsection{DDC register, offset 0x30}
\subsection{DDC register, offset 0x30}
This register controls the I2C pins of the VGA port using a bit-banged interface. It is meant to implement DDC.
This register controls the I2C pins of the VGA port using a bit-banged interface. It is meant to implement DDC.
\begin{tabular}{|l|l|}
\begin{tabular}{|l|l|}
\hline
\hline
\textbf{Bit} & \textbf{Description} \\
\textbf{Bit} & \textbf{Description} \\
\hline
\hline
0 & Current status of the SDA line. \\
0 & Current status of the SDA line. \\
\hline
\hline
1 & Bit driven to SDA if OE=1. \\
1 & Bit driven to SDA if OE=1. \\
\hline
\hline
2 & SDA output enable (OE). \\
2 & SDA output enable (OE). \\
\hline
\hline
3 & Bit driven to SDC. \\
3 & Bit driven to SDC. \\
\hline
\hline
\end{tabular}
\end{tabular}
\section{Connections}
\section{Connections}
The pixel clock is not generated internally and must be fed to the core using the \verb!vga_clk! port. No relationship is expected with the system clock (the two domains are entirely independent). That pixel clock should also be fed to the synchronous DAC.
The pixel clock is not generated internally and must be fed to the core using the \verb!vga_clk! port. No relationship is expected with the system clock (the two domains are entirely independent). That pixel clock should also be fed to the synchronous DAC.
The other ports should be self-explanatory.
The other ports should be self-explanatory.
\section*{Copyright notice}
\section*{Copyright notice}
Copyright \copyright 2007-2010 S\'ebastien Bourdeauducq. \\
Copyright \copyright 2007-2010 S\'ebastien Bourdeauducq. \\
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the LICENSE.FDL file at the root of the Milkymist source distribution.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the LICENSE.FDL file at the root of the Milkymist source distribution.
\end{document}
\end{document}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.