码迷,mamicode.com
首页 > 其他好文 > 详细

VGA显示SDRAM内容_1——DE1-SOC学习笔记(3)

时间:2015-02-25 00:40:05      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:

      在这篇文以及下面几篇文里里使用HPS-FPGA-Slave实现HPS读取一张bmp图片,发送至SDRAM,然后由自定义的IP读取SDRAM输出至VGA显示。

      不妥当的地方还需多多指教

   IP逻辑设计

     VGA时序控制模块,选择mod控制输出不同的分辨率

//vga timing ctrl module
// systemverilog
//
//by Sorin
module vga_timctrl(
    input clk,//200MHz
     input [1:0] mod,
    //input rst,
    output hsync,//
    output vsync,//
    output logic [10:0] addr_x,//
    output  logic [10:0] addr_y,//
    output  video_on,//,
     output  logic clk_cycle//actule clock output
    );
    //800*600@72Hz
    //***************vga mode***************  *********************
   //
   //   800         40     128      88     600   1      4    23
   //"800x600@72" 50.0 800 856 976 1040 600 637 643 666               --mod0
   //"800x600@60" 40.0 800 840 968 1056 600 601 605 628                 --mod1
   //"640x480@60" 25.2 640 656 752 800 480 490 492 525                --mod2
   //"1280x960@60" 102.1 1280 1360 1496 1712 960 961 964 994        --mod3
   //"1280x1024@60" 108.0 1280 1328 1440 1688 1024 1025 1028 1066    --not surport
   logic[10:0] V_W=1280;//
   logic[10:0] V_H=1024;//
   logic[10:0] H_Sync_Start=1328;//
   logic[10:0] H_Sync_Stop=1440;//
   logic[10:0] H_Total=1688;//
   logic[10:0] V_Sync_Start=1025;//
   logic[10:0] V_Sync_Stop=1028;
   logic[10:0] V_Total=1066;//
    logic [3:0] CLK_DIV_CNT=0;
    logic  inner_clk;
    logic [2:0] clk_cnt=0;
    logic inner_clk_reg;
    //assign inner_clk=inner_clk_reg;
    //clk divider 
    always @(posedge clk)
        begin
        clk_cnt<=clk_cnt+1;
        end
    
   
    
   wire[10:0] V_Counter;
   wire[10:0] H_Counter;
   wire H_Video_On;
   wire V_Video_On;
   wire V_Clk;
   wire H_CLR;
   wire V_CLR;
   assign V_Clk=H_Video_On;
   assign video_on=H_Video_On&&V_Video_On;
   assign addr_x=video_on?H_Counter:V_W;
   assign addr_y=video_on?V_Counter:V_H;
   //assign inner_clk=clk;
   c_counter_binary Counter_H(.CLK(inner_clk),.SCLR(H_CLR),.Q(H_Counter),.CE(1));
   c_counter_binary Counter_V(.CLK(inner_clk),.SCLR(V_CLR),.Q(V_Counter),.CE(H_CLR));
   assign H_Video_On=(H_Counter<V_W)?1:0;
   assign V_Video_On=(V_Counter<V_H)?1:0;
   assign H_CLR=(H_Counter==H_Total-1)?1:0;
   assign V_CLR=((V_Counter==V_Total-1)&&H_CLR)?1:0;
   assign hsync=(H_Counter<H_Sync_Stop&&H_Counter>H_Sync_Start)?0:1;
   assign vsync=(V_Counter<V_Sync_Stop&&V_Counter>V_Sync_Start)?0:1;
   assign test=V_CLR;
    
    //modset 
    always_comb
    begin
            
            case(mod)
            b00:
                begin
                V_W=800;
                V_H=600;
                H_Sync_Start=856;
                H_Sync_Stop=976;
                H_Total=1040;
                V_Sync_Start=637;
                V_Sync_Stop=643;
                V_Total=666;
                //CLK_DIV_CNT=2;//200M/4=50M
                inner_clk=clk_cnt[1];
                end
            b01:
                begin
                V_W=800;
                V_H=600;
                H_Sync_Start=840;
                H_Sync_Stop=968;
                H_Total=1056;
                V_Sync_Start=601;
                V_Sync_Stop=605;
                V_Total=628;
                //CLK_DIV_CNT=2;//200M/4=50M
                inner_clk=clk_cnt[1];
                end
            b10:
                begin
                V_W=640;
                V_H=480;
                H_Sync_Start=656;
                H_Sync_Stop=752;
                H_Total=800;
                V_Sync_Start=490;
                V_Sync_Stop=492;
                V_Total=525;
                //CLK_DIV_CNT=4;//200M/8=25M
                inner_clk=clk_cnt[2];
                end
            b11:
                begin
                V_W=1280;
                V_H=960;
                H_Sync_Start=1360;
                H_Sync_Stop=1496;
                H_Total=1712;
                V_Sync_Start=961;
                V_Sync_Stop=964;
                V_Total=994;
                CLK_DIV_CNT=1;//200M/2=100M
                inner_clk=clk_cnt[0];
                end
            default:
                begin
                V_W=800;
                V_H=600;
                H_Sync_Start=856;
                H_Sync_Stop=976;
                H_Total=1040;
                V_Sync_Start=637;
                V_Sync_Stop=643;
                V_Total=666;
                CLK_DIV_CNT=2;
                inner_clk=clk_cnt[0];
                end
            endcase
     clk_cycle<=inner_clk;
    end
endmodule

//counter module
module c_counter_binary #(parameter DATAWIDTH=11 )(
    input logic CLK,
    input logic SCLR,
    output  logic [DATAWIDTH-1:0] Q,
    input logic CE
);
logic [DATAWIDTH-1:0] cnt=0;
always @(posedge CLK)
    begin
    if(SCLR)
        cnt=0;
    else
        begin
            if(CE==b1)
            begin
                cnt=cnt+1;
            
            end
        end
    Q<=cnt;
    end

endmodule

     顶层模块

面对sdram,使用pipeline方式读取,sdram controller支持的读取方式可以在它的datasheet中找到。

这里说明一下,avalon_slave控制有2个 words的地址空间,第一个words为sdram的基址寄存器,第二个words为控制寄存器。

控制寄存器由高至低:6位颜色模式控制 2位分辨率控制 12位height 12位width

颜色控制:

//vgacolormod 000000 stop, black

//vgacolormod 000001 8 bit gray-ram

//vgacolormod 000010 24 bit RGB888

 //vgacolormod 000011 16 bit RGB565

//vgacolormod other black

//ram vgadisp
//systemverilog
//by Sorin

module ramvgadisp(
//avalone slave to hps
 input logic clk_s,reset_s,chipselect_s,
 input logic  addr_s,//reg0 rambaseaddr 
 input logic write_s,
 input logic [31:0] writedata_s,
//avalone master to sdram controller
 input logic clk_m,reset_m,//clk_m 100MHz
 output logic read_m,
 input logic [63:0] readdata_m,
 output logic [31:0] readaddr_m,
 input waitrequest_m,
 input readdatavalid_m,
 //output logic[10:0] burstcount,
//output to vgadisplay
 input logic vga_clk,
  output logic[23:0] vgaout_rgb,
  output logic vgaout_hsync,vgaout_vsync,
  output logic vgaout_sync_n,vgaout_clk,
  //
  output logic datareading 
 
);
wire logic [10:0]width,height,addr_x,addr_y;
wire logic [1:0] vga_mod;
logic video_on;
logic [31:0] rambaseaddr,dispsetting;
logic [5:0] vgacolormod;
 logic [22:0] ramoffsetaddr;//ram offset address counter
logic [22:0] scalar_counter;//scalar counter 
logic vga_cycle;//vga pixel clk output 

assign vgaout_clk=vga_cycle;
assign vgaout_sync_n=video_on;

//always_comb//depart register data 
//begin
    assign width=dispsetting[10:0];
    assign height=dispsetting[22:12];
    assign vga_mod=dispsetting[25:24];
    assign vgacolormod=dispsetting[31:26];
//end

vga_timctrl timctrl( //vga time cotrol module 
.clk(vga_clk),
.mod(vga_mod),
.hsync(vgaout_hsync),
.vsync(vgaout_vsync),
.video_on(video_on),
.addr_x(addr_x),
.addr_y(addr_y),
.clk_cycle(vga_cycle)
);

//fifo definitions
//logic  [31:0]fifoRam_1[3];
logic [5:0][63:0] fifoRam_0,fifoRam_1;
logic  fifo_rpart,fifo_upart;
//fifo_rpart reading from sdram;fifo_upart using by vga
// rpart means this part  should be full(fill it after turn to it )
// upart means this part is using 
logic [3:0] fifopore;//
logic datarequest;
logic datarequest1;//a clock later
logic datarequestxor;//when datarequest give an effective signal
logic [3:0] fifo_readed_cnt;//readed count 
logic fifo_rst;
logic datarequestlock;//lock the request signal 
typedef enum logic{idle,busy} fifostatedef;
typedef enum logic [1:0]{ridle,rwait,rreading}fiforstatedef;
//scalar_counter  
//fatch data from sdram,and display 
//vgacolormod 000000 stop, black
//vgacolormod 000001 8 bit gray-ram
//vgacolormod 000010 24 bit RGB888 
//vgacolormod 000011 16 bit RGB565
//vgacolormod other  black        
//typedef union packed{
//   logic [5:0][31:0] raw;
//    logic [23:0][7:0] gray;
//    logic [7:0][23:0] rgb888;
//} fifoformat;
 logic [5:0][63:0]curdata_raw;
 logic [383:0] curdata_raw_c;
 logic [47:0][7:0]curdata_gray;
 logic [15:0][23:0]curdata_rgb888;
 logic [11:0][31:0]curdata_rgba;
 
//wire[5:0] curdata;//current use fifo data 
//wire logic [23:0][7:0] curgray;
//wire logic [8:0][23:0] currgb888;

always_comb
begin
 case(fifo_upart)
 b0:curdata_raw=fifoRam_0;
 b1:curdata_raw=fifoRam_1;
 default:curdata_raw=0;
 endcase
end
/*
genvar i;
generate 
    for(i=0;i<6;i++)
        begin:gen1
        curdata_raw_c[i*64]
        end
 endgenerate 
 */
 
assign curdata_gray=({curdata_raw});
assign curdata_rgb888=({curdata_raw});
assign curdata_rgba=({curdata_raw});
logic [5:0]pix_cnt;
logic offsetAddrStep;//1 add 6, 0 add 0
always_comb//for display
begin
if(video_on==b1)
    begin
    case(vgacolormod)
        b000000:
            vgaout_rgb<=hffff00;
        b000001:
            begin
            vgaout_rgb<={curdata_gray[pix_cnt],curdata_gray[pix_cnt],curdata_gray[pix_cnt]};
            //vgaout.rgb.G<=curdata_gray[pix_cnt];
            //vgaout.rgb.B<=curdata_gray[pix_cnt];
            end
        b000010:
            begin
            vgaout_rgb<=curdata_rgb888[pix_cnt];
    
            end
        b000011:
            begin
            vgaout_rgb<=curdata_rgba[pix_cnt][23:0];
            end
        default:
            begin
            vgaout_rgb<=0;
            end
        endcase
    
    end
else
    vgaout_rgb<=0;

end

//for corlor data 
logic [11:0] cntx,cnty;
always@(posedge vga_cycle) 
begin
    if(~vgaout_vsync)//vsync is effective
        begin //read the first fifo part from ram and  reset the output module 
        pix_cnt<=0;
        cntx<=0;
        cnty<=0;
        datarequest<=0;
        fifo_upart<=0;
        fifo_rpart<=1;
        ramoffsetaddr=0;
        //offsetAddrStep=0;
        //vgaout_rgb<=0;
        end
    if(~vgaout_hsync)
        begin
        if(cntx>=width)
            begin
            cnty<=cnty+1;
            cntx<=0;
            end
        else
            begin
            cntx<=0;
            cnty<=cnty;
            end
        end
    if((video_on==b1)&(cntx<width)&(cnty<height))//video_on should be effective,addr_x and addr_y should 
    begin
        cntx<=cntx+1;
        case(vgacolormod)
        b000001:
            begin
            if(pix_cnt<47)
                begin
                pix_cnt<=pix_cnt+1;
                offsetAddrStep=0;
                datarequest<=0;
                ramoffsetaddr=ramoffsetaddr;
                
                end
            else
                begin//turn to the other fifo part to read 
                pix_cnt<=0;
                fifo_upart<=~fifo_upart;
                fifo_rpart<=~fifo_rpart;
                datarequest<=1;
                ramoffsetaddr=ramoffsetaddr+6;
                offsetAddrStep=1;
                end
            end
        b000010:
            if(pix_cnt<15)
                begin
                pix_cnt<=pix_cnt+1;
                offsetAddrStep=0;
                datarequest<=0;
                ramoffsetaddr=ramoffsetaddr;
                
                end
            else
                begin//turn to the other fifo part to read 
                pix_cnt<=0;
                fifo_upart<=~fifo_upart;
                fifo_rpart<=~fifo_rpart;
                datarequest<=1;
                ramoffsetaddr=ramoffsetaddr+6;
                offsetAddrStep=1;
                end
         b000011:
            if(pix_cnt<11)
                begin
                pix_cnt<=pix_cnt+1;
                offsetAddrStep=0;
                datarequest<=0;
                ramoffsetaddr=ramoffsetaddr;
                end
            else
                begin
                pix_cnt<=0;
                fifo_upart<=~fifo_upart;
                fifo_rpart<=~fifo_rpart;
                datarequest<=1;
                ramoffsetaddr=ramoffsetaddr+6;
                offsetAddrStep=1;
                end
        default:
            begin
            datarequest<=b0;
            end
        endcase
        //case(offsetAddrStep)
        //1:ramoffsetaddr<=ramoffsetaddr+6;
        //0:ramoffsetaddr<=ramoffsetaddr;
        //default:ramoffsetaddr<=ramoffsetaddr;
        //endcase
        //ramoffsetaddr<=ramoffsetaddr+offsetAddrStep;
    end
    else
        begin
        datarequest<=0;
        end 
end



//as a slave, setting register
always @(posedge clk_s)
    begin
    if(reset_s==b1)
        begin
        dispsetting<=0;
        end
    
    if(chipselect_s==b1)
        begin
            if(write_s==b1)
            begin
                case(addr_s)
                0:
                    begin
                    rambaseaddr<=writedata_s;
                    dispsetting<=dispsetting;
                    end
                1:
                    begin
                    dispsetting<=writedata_s;
                    rambaseaddr<=rambaseaddr;
                    end
                default:
                    begin
                    rambaseaddr<=rambaseaddr;
                    dispsetting<=dispsetting;
                    end
                endcase
            end
        end
    
 end
    
    
    
//logic  [31:0]fifoRam_0[3]; //store burst data received
//fifo block
fifostatedef fifostate;
logic [3:0] fifo_addrsent_cnt;
fiforstatedef fiforstate=ridle;
logic [31:0] fiforeadaddr;
assign fiforeadaddr=rambaseaddr+ramoffsetaddr+fifo_addrsent_cnt;
assign datarequestxor=datarequest&(~datarequest1);
always @(posedge clk_m)
begin
    datarequest1<=datarequest;
    
    datareading<=0;
    if((fiforstate==ridle)&datarequestxor)
        begin
        fifo_readed_cnt<=0;
        fifo_addrsent_cnt<=0;
        fiforstate<=rreading;
        read_m<=b1;
        readaddr_m<=fiforeadaddr;
        //burstcount<=‘h0006;
        end
    else if(fiforstate==rreading)
        begin
            if(waitrequest_m)
                begin
                read_m<=b1;
                readaddr_m<=(rambaseaddr+ramoffsetaddr+fifo_addrsent_cnt)<<6;
                //burstcount<=‘h0006;
                end
            else
                begin
                    if(fifo_addrsent_cnt<5)//address haven‘t sent all yet
                        begin
                            fifo_addrsent_cnt=fifo_addrsent_cnt+1;
                            read_m<=b1;
                            //burstcount<=‘h0006;
                            readaddr_m<=(rambaseaddr+ramoffsetaddr+fifo_addrsent_cnt)<<6;
                        end
                    else
                        begin
                        read_m<=b0;//stop senting request 
                        end
                end
            if(readdatavalid_m)//data is valid
                begin
                case(fifo_rpart)
                            0:
                            //fifoRam_0[fifo_readed_cnt]<=readdata_m; 
                            fifoRam_0[fifo_readed_cnt]<=readdata_m;
                            1:
                            //fifoRam_1[fifo_readed_cnt]<=readdata_m;
                            fifoRam_1[fifo_readed_cnt]<=readdata_m;
                endcase
                if(fifo_readed_cnt<5)
                    begin
                    fifo_readed_cnt<=fifo_readed_cnt+1;
                    end
                else
                    begin
                    fifo_readed_cnt<=0;
                    fiforstate<=ridle;
                    end
                
                end
        
        end
    else
        begin
        fiforstate<=ridle;
        end
        

end

endmodule

VGA显示SDRAM内容_1——DE1-SOC学习笔记(3)

标签:

原文地址:http://www.cnblogs.com/blinkingstar/p/4299046.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!