zoukankan      html  css  js  c++  java
  • VGA显示SDRAM内容_1——DE1-SOC学习笔记(3)

          在这篇文以及下面几篇文里里使用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
  • 相关阅读:
    js debounce防抖技术
    我在项目中es6中数组的常用方法
    windows 部署Nginx转发http2.0协议
    AES加密,C#和java相同
    asp:Button js弹出提示框信息
    服务器不重启安装Asp.net Core 程序包
    C# string.Join的用法
    IIS部署asp.net core webapi
    ASP.net 加载不了字体Failed to load resource: the server responded with a status of 404 (Not Found)
    Windows Redis 取消保护模式C#进行访问
  • 原文地址:https://www.cnblogs.com/blinkingstar/p/4299046.html
Copyright © 2011-2022 走看看