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*[email protected]
    //***************vga mode***************  *********************
   //
   //   800         40     128      88     600   1      4    23
   //"[email protected]" 50.0 800 856 976 1040 600 637 643 666               --mod0
   //"[email protected]" 40.0 800 840 968 1056 600 601 605 628                 --mod1
   //"[email protected]" 25.2 640 656 752 800 480 490 492 525                --mod2
   //"[email protected]" 102.1 1280 1360 1496 1712 960 961 964 994        --mod3
   //"[email protected]" 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
时间: 2024-10-23 18:08:01

VGA显示SDRAM内容_1——DE1-SOC学习笔记(3)的相关文章

jQuery 取消事件冒泡 阻止后续内容执行 闭包函数 (学习笔记)

1.取消事件冒泡 <title>取消事件冒泡</title> <style> div { border:solid 1px black; } </style> <script src="js/jquery-3.1.1.js"></script> <script> $(function () { $("#big").click(function () { alert("点了大

cookies 显示用户上次访问的时间 学习笔记

Cookie.setMaxAge(72460*60) Cookie.setPath("/day0X"); Httpwatch观察 Cookie.setMaxAge(0)删除同名Cookie import java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.

这是三天的linux学习笔记,大神可以指教,别喷我,我新手。

20140825.学习笔记开启新终端    ctrl+shift+n关闭终端    alt+F4扩大终端    ctrl+shift+"+"缩小终端    ctrl+"-"开启新的终端标签    ctrl+shift+t关闭终端标签    ctrl+shift+w标签之间的切换    alt+标签对应的编号切换到真实终端tty3   ctrl+alt+F3tty回到图形     alt+F1或者F7 快捷键设置终端--->编辑--->键盘快捷键 设置终端

MySQL数据库学习笔记(十)----JDBC事务处理、封装JDBC工具类

首先需要回顾一下上一篇文章中的内容:MySQL数据库学习笔记(九)----JDBC的PreparedStatement接口重构增删改查 一.JDBC事务处理: 我们已经知道,事务的概念即:所有的操作要么同时成功,要么同时失败.在MySQL中提供了Commit.Rollback命令进行事务的提交与回滚.实际上在JDBC中也存在事务处理,如果要想进行事务处理的话,则必须按照以下的步骤完成. JDBC中事务处理的步骤: 1.要取消掉JDBC的自动提交:void setAutoCommit(boolea

javascript学习笔记——如何修改&lt;a href=&quot;#&quot;&gt;url name&lt;/a&gt;

0.前言 使用了一段时间javascript,再花了点时间学习了jquery,但是总是感觉自己很"迷糊",例如<a href="#">url name</a>中,如果修改href中的"#"应如何编写代码,如果修改url name应如何编写代码.再加上javascript和jquery操作方法略有不同,所以我就更"迷糊"了. [说明] 曾经使用关键词--"innerHTML和value区别&qu

HTML&CSS基础学习笔记7-高亮文本及组合使用

HTML提供了<mark>标签可以让你的文本高亮,这样看起来更加醒目.<mark>标签内的文本会呈现特殊的样式,它和<em>,<strong>一样也是一个带有语义的标签. 代码如下: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>高亮文本</title><

CAFFE学习笔记(五)用caffe跑自己的jpg数据

1 收集自己的数据 1-1 我的训练集与测试集的来源:表情包 由于网上一幅一幅图片下载非常麻烦,所以我干脆下载了两个eif表情包.同一个表情包里的图像都有很强的相似性,因此可以当成一类图像来使用.下载个eif解压包可以把eif文件解压成gif和jpg格式的文件,然后删除gif文件,只留下jpg格式的文件,这些图就是我的训练集与测试集了. 1-2 使用rename批量重命名图像 (1)对于一个存放了图像src.jpg的文件夹ROOT,在ROOT中新建一个test.txt文件,在里面写下"renam

Debussy学习笔记

学习FPGA以来,一直是用Modelsim作为仿真调试工具,前几天在同事那儿看到了一个新工具:Debussy,看她用的相当顺手,而且工具本身也相 当好用,有很多Modelsim不具有的功能,然后就立马上网下载了Debussy软件和相关教程学习了一下,从本文开始软件的学习笔记. Debussy 是NOVAS Software, Inc(思源科技)开发的HDL Debug & Analysis tool,这套软体主要不是用来跑模拟或看波形,它本身不具有仿真功能,需要调用Modelsim等仿真软件生成

《Linux学习并不难》Linux常用操作命令(1): cat命令显示文本文件内容

8.1  <Linux学习并不难>Linux常用操作命令(1): cat命令显示文本文件内容 使用cat命令可以显示文本文件的内容,也可以把几个文件内容附加到另一个文件中.如果没有指定文件,或者文件为"-",那么就从标准输入读取. 命令语法: cat [选项] [文件] 命令中各选项的含义如表所示. 选项 选项含义 -n 对输出的所有行编号 -b 对非空输出行编号 -s 当遇到有连续两行以上的空白行时,就替换为一行的空白行 -E 在每行结束处显示$ 例:显示/etc/ini