FPGA project : uart232_ram_vga

news2024/12/25 1:02:13

重点学习:

本实验重点学习了双口ram解决多bit跨时钟域同步处理的问题。

其实signal port ram,它的输入口和输出口分别用不同的时钟,也可以解决这个问题。

让我意识到的比较重要的事情:

1,代码设计中,一些大于10的数字,尽量用parameter设定一些可以重传的参数来代替。因为这样方便仿真修改。我就是之前写uart_rx模块,数字啥的没用参数替代。这个实验中仿真时需要修改参数,然后重新修改了uart_rx代码。使得仿真时间大大缩短,很方便。

2,在vga_pic模块中模拟产生的ram,读完数据后,ram里面的数据并没有消失,还在。

写数据:在时钟上升沿,写使能拉高,与此同时要有对应的地址与数据。然后数据就写进对应的地址里面了。

读数据:在时钟上升沿,读使能拉高,与此同时给出地址,然后数据就都出来了。值得一提的是,数据会滞后一个时钟周期(相对于读使能与地址),说明ram内部用的时序逻辑嘛。

3, task input ...如果写在task内部了。那么在task name 后面就不要加括号了。否则modulism会报错。

 

module vga_pic (
    input       wire            clk_25  , // ram 的输出时钟,也是vga图像的时钟。
    input       wire            clk_50  , // ram 的输入时钟
    input       wire            rst_n   , // 经过系统复位和pll的locked相与后的复位。
    input       wire    [9:0]   pix_x   ,
    input       wire    [9:0]   pix_y   ,
    input       wire    [7:0]   po_data , // 写入的数据的数据
    input       wire            po_flag , // 用作ram的读使能。

    output      wire    [7:0]   pix_data
);
    // parameter 
    parameter   H_VALID = 10'd640    ,
                V_VALID = 10'd480    ;

    parameter   PIC_SIZE= 14'd1_0000 ,
                H_PIC   = 10'd100    ,
                V_PIC   = 10'd100    ;

    parameter   RED     = 8'b1110_0000 ,
                GREEN   = 8'b0001_1100 ,
                BLUE    = 8'b0000_0011 ,
                WHITE   = 8'b1111_1111 ,
                BLACK   = 8'b0000_0000 ;

    // reg signal define
    reg     [13:0]  wr_addr  ;  // ram 的写地址。
    reg     [ 7:0]  data_pix ;  // 彩条像素
    reg             pic_valid; // 图片有效
    wire    [ 7:0]  pic_data ; // 图片像素
    reg             rd_en    ; // ram读使能
    reg     [13:0]  rd_addr  ;

/************************************************************************/
    // reg     [13:0]  wr_addr  ;  // ram 的写地址。    
    always @(posedge clk_50 or negedge rst_n) begin
        if(~rst_n) begin
            wr_addr <= 14'd0 ;
        end else begin
            if(po_flag) begin
                if(wr_addr == 9999) begin // 记到最大的地址后归零。
                    wr_addr <= 14'd0 ;
                end else begin
                    wr_addr <= wr_addr + 1'b1 ;
                end
            end else begin
                wr_addr <= wr_addr ;
            end
        end
    end

    // reg     [ 7:0]  data_pix ;  // 彩条像素
    always @(posedge clk_25 or negedge rst_n) begin 
        if(~rst_n) begin
            data_pix <= BLACK ;
        end else begin
            if(pix_y >= 0 && pix_y <= (V_VALID / 5 - 1))
                data_pix <= RED ;
            else if((pix_y >= V_VALID / 5) && pix_y <= ((V_VALID / 5 ) * 2) - 1)
                data_pix <= GREEN ;
            else if((pix_y >= (V_VALID / 5) * 2) && pix_y <= ((V_VALID / 5 ) * 3) - 1)
                data_pix <= BLUE ;
            else if((pix_y >= (V_VALID / 5) * 3) && pix_y <= ((V_VALID / 5 ) * 4) - 1)
                data_pix <= WHITE ;
            else if((pix_y >= (V_VALID / 5) * 4) && pix_y <= (V_VALID  - 1))
                data_pix <= BLACK ;
            else 
                data_pix <= BLACK ;
        end // 先不写else 一会看编译是否会通过。
    end
    // reg             pic_valid; // 图片有效
    always @(posedge clk_25 or negedge rst_n) begin
        if(~rst_n) begin
            pic_valid <= 1'b0 ;
        end else begin
            if(pix_x >= 269 && pix_x <= 368 && pix_y >= 190 && pix_y <= 289) begin
                pic_valid <= 1'b1 ;
            end else begin
                pic_valid <= 1'b0 ;
            end
        end
    end
    // wire    [ 7:0]  pic_data ; // 图片像素
    // 图片像素存在了ram中,所以只需要取出来就是图片像素了。
    // reg             rd_en    ; // ram读使能
    always @(posedge clk_25 or negedge rst_n) begin
        if(~rst_n) begin
            rd_en <= 1'b0 ;
        end else begin
            if(pix_x >= 268 && pix_x <= 367 && pix_y >= 190 && pix_y <= 289) begin
                rd_en <= 1'b1 ;
            end else begin
                rd_en <= 1'b0 ;
            end
        end
    end
    // reg     [13:0]  rd_addr  ;
    always @(posedge clk_25 or negedge rst_n) begin
        if(~rst_n) begin
            rd_addr <= 14'd0 ;
        end else begin
            if(rd_en) begin
                if(rd_addr == 9999) begin
                    rd_addr <= 14'd0 ;
                end else begin
                    rd_addr <= rd_addr + 1'b1 ;
                end
            end else begin
                rd_addr <= rd_addr ;
            end
        end
    end

/**********************output signal define**************************************/
    // wire    [7:0]   pix_data ;
    assign pix_data = (pic_valid == 1'b1) ? pic_data : data_pix ;
/******************例化双口ram*******************/
ram_10000_double ram_10000_double_insert(
	.data                   ( po_data ) ,
	.inclock                ( clk_50  ) ,
	.outclock               ( clk_25  ) ,
	.rdaddress              ( rd_addr ) ,
	.wraddress              ( wr_addr ) ,
	.wren                   ( po_flag ) ,
	.q                      ( pic_data)
);

endmodule

 

module top(
    input       wire            sys_clk     ,
    input       wire            sys_rst_n   ,
    input       wire            rx          ,

    output      wire    [7:0]   rgb         ,
    output      wire            hsync       ,
    output      wire            vsync   
);

    // 例化间连线
    wire            rst_n       ;
    wire    [7:0]   po_data     ;
    wire            po_flag     ;
    wire    [7:0]   pix_data    ;
    wire    [9:0]   pix_x       ;
    wire    [9:0]   pix_y       ;
    wire            clk_25      ;
    wire            clk_50      ;

pll	pll_inst (
    .sys_rst_n              ( sys_rst_n     ) ,
	.areset                 ( ~sys_rst_n    ) ,
	.inclk0                 ( sys_clk       ) ,
	.c0                     ( clk_25        ) ,
	.c1                     ( clk_50        ) ,
	.locked                 ( rst_n         )
);

uart_rx uart_rx_inst(
    .sys_clk                ( clk_50        ) ,
    .sys_rst_n              ( rst_n         ) ,
    .rx                     ( rx            ) ,

    .po_data                ( po_data       ) ,
    .po_flag                ( po_flag       ) 
);

vga_ctrl vga_ctrl_inst(
    .vga_clk                ( clk_25        ) ,
    .vga_rst_n              ( rst_n         ) ,
    .pix_data               ( pix_data      ) ,

    .hsync                  ( hsync         ) ,
    .vsync                  ( vsync         ) ,
    .pix_x                  ( pix_x         ) ,
    .pix_y                  ( pix_y         ) ,
    .rgb                    ( rgb           )         
);

vga_pic vga_pic_inst(
    .clk_25                 ( clk_25        ) ,
    .clk_50                 ( clk_50        ) ,
    .rst_n                  ( rst_n         ) ,
    .pix_x                  ( pix_x         ) ,
    .pix_y                  ( pix_y         ) ,
    .po_data                ( po_data       ) ,
    .po_flag                ( po_flag       ) ,

    .pix_data               ( pix_data      )
);


endmodule
`timescale 1ns/1ns
module test_top();
    reg             sys_clk     ;
    reg             sys_rst_n   ;
    reg             rx          ;

    wire    [7:0]   rgb         ;
    wire            hsync       ;
    wire            vsync       ;

    reg     [7:0]   data_mem    [9999:0];


top top_insert(
    .sys_clk                ( sys_clk    ) ,
    .sys_rst_n              ( sys_rst_n  ) ,
    .rx                     ( rx         ) ,

    .rgb                    ( rgb        ) ,
    .hsync                  ( hsync      ) ,
    .vsync                  ( vsync      )   
);

    defparam    top_insert.uart_rx_inst.CLK_FREQ = 5 ;
    defparam    top_insert.uart_rx_inst.UART_BPS = 1  ;
    parameter   CYCLE = 20 ;
    initial begin
        sys_clk     = 1'b1 ;
        sys_rst_n   <=1'b0 ;
        #(CYCLE)           ;
        sys_rst_n   <=1'b1 ; 
    end
    always #(CYCLE / 2) sys_clk = ~sys_clk ;

    initial begin
        $readmemh ("D:/intel_FPGA/VScodedocument/EmbedFire/31 rs232_vga/matlab/data_test.txt",data_mem);
    end

    initial begin
        rx <= 1'b1 ;
        #(CYCLE * 10) ;
        rx_byte ;
    end

    task    rx_byte;
    integer j ; // j 是存储器的地址。
    for (j = 0;j < 10000 ;j = j + 1 ) begin
        rx_bit(data_mem[j]) ; // 没有输入端口,自然不需要输入参数。
    end
    endtask

    task    rx_bit;
    input [7:0]data ;
    integer i ;
    for (i = 0;i < 10 ;i = i + 1 ) begin
        case (i)
        0:rx    <= 1'b0;
        1:rx    <= data[0];
        2:rx    <= data[1];
        3:rx    <= data[2];
        4:rx    <= data[3];
        5:rx    <= data[4];
        6:rx    <= data[5];
        7:rx    <= data[6];
        8:rx    <= data[7];
        9:rx    <= 1'b1;
        default: rx    <= 1'b1;
        endcase
        #(5 * CYCLE) ;
    end
    endtask
endmodule

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1045164.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VEX —— Functions|Measure

目录 distance —— 返回两点间距离 distance2 —— 返回两点间距离平方 surfacedist —— 查找点到点组的距离&#xff08;沿几何体表面&#xff09; xyzdist —— 查找点到表面最近点的距离 uvdist —— 在uv空间查找uv坐标到几何体的距离 planepointdistance —— 计算…

【免费】2023云栖大会门票开抢啦!数量有限,先到先得!

&#x1f3ab; 报名方式&#xff1a;点击链接即可免费报名&#xff01; &#x1f517; 2023云栖大会-领票页 &#x1f4c5; 10月31日-11月2日&#xff0c;让我们齐聚云栖小镇&#xff01;

基于 Nginx 实现一个灰度发布系统

软件开发一般不会上来就是最终版本,而是会一个版本一个版本的迭代。新版本上线前都会经过测试,但就算这样,也不能保证上线了不出问题。所以,在公司里上线新版本代码一般都是通过灰度系统进行测试。并且,灰度系统可以把流量划分成多份,一份走新版本代码,一份走老版本代码…

数据通信——应用层(文件传输FTP)

引言 域名保证了在因特网中标识唯一的用户&#xff0c;而我们用户上网需求自然是发送信息以及共享文件&#xff0c;我们使用的很多传输工具&#xff0c;比如微信、QQ、百度等软件&#xff0c;在上传和下载文件时就会有FTP的参与。那么如何为文件提供收发渠道以完成的共享呢&…

一篇文章带你了解最近很火的RunnerGo测试平台

在当今这个数字化时代&#xff0c;应用程序的性能至关重要。一款可靠的性能测试工具&#xff0c;能够为企业带来无数的好处。最近&#xff0c;一款名为RunnerGo的开源性能测试工具备受瞩目。本文将详细介绍RunnerGo的特点、优势以及如何解决性能测试中的痛点。 RunnerGo产品介绍…

位运算符与高级操作

位运算符与高级操作 运算符 高级操作 左移实现乘法 左移n位等价于乘以2的n次方 int x; x 2; x x << 2; x x << 3;使用左移实现乘法运算仅限于乘以2的倍数 是不是只要左移就能够实现乘以2的倍数呢? char x 120; x x << 1;右移实现除法 右移n位等价于除…

ipad触控笔有必要买吗?比较好用的电容笔

如果你想用iPad画画&#xff0c;苹果Pencil会是个不错的选择。然而&#xff0c;苹果原装的电容笔价格却高得让很多人望而却步。所以&#xff0c;比较好的办法就是选用一个平替电容笔。我曾经使用过ipad&#xff0c;也是一个数码爱好者&#xff0c;最近两年我开始接触使用平替电…

Spring MVC 中的数据验证技术

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

cmdb运维管理平台在哪能看

cmdb运维管理平台功能你可以在云呐 进行查看  CMDB运维管理平台是一种IT资产管理工具&#xff0c;它可以帮助企业对IT资源进行有效的管理和监控。以下是一些常见的应用场景&#xff1a;  IT资产清单管理&#xff1a;通过CMDB运维管理平台可以对企业的IT资产进行全面的清单管…

微软考虑引入小型核反应堆;诺基亚推出“网络即代码”平台丨RTE开发者日报 Vol.58

开发者朋友们大家好&#xff1a; 这里是「RTE 开发者日报」&#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

CISSP,你值得拥有(我的学习之路)

&#xff08;只分享三点&#xff1a;怎么学、怎么练、怎么考。&#xff09; 我为啥去考CISSP 我是个在信安行业摸爬滚打将近20年的老油条&#xff0c;知道CISSP这个认证是很早前的事情了&#xff0c;但一直以来都觉得它有点难&#xff0c;加上人又懒得要命&#xff0c;也就始…

学会安装Redis数据库到服务器或计算机(Windows版)

Redis 是一个基于内存的开源数据库系统&#xff0c;被广泛应用于 Web 应用、消息队列、缓存、实时统计等领域。它支持多种数据结构&#xff0c;包括字符串、哈希表、列表、集合、有序集合等&#xff0c;并提供了多种操作命令。 Redis 的特点如下&#xff1a; 内存存储&#xf…

打开网站显示“不安全”怎么办?

在互联网世界中&#xff0c;安全是一个至关重要的问题。然而&#xff0c;当您尝试访问某些网站时&#xff0c;可能会看到“不安全”的警告。这通常是因为这些网站没有部署SSL证书。SSL证书是一种数字证书&#xff0c;可确保互联网通信的安全性和保密性。 “打开网站显示不安全”…

什么是城市坐标系,与国家坐标系的区别?

文章目录 先说国家坐标系什么是城市坐标系城市坐标系建设规范常见的城市坐标系 先说国家坐标系 先1954年我国建立了第一代国家大地坐标系统&#xff0c;即北京54坐标系&#xff0c;英文缩写BJ54&#xff0c;坐标原点在苏联&#xff0c;椭球参数直接拿苏联的。第一代坐标系的椭…

八大排序详解

目录 1.排序的概念及应用 1.1 排序的概念 1.2 排序的应用 1.3 常见的排序算法 2.常见排序算法的实现 2.1 直接插入排序 2.1.1 基本思想 2.1.2 动图解析 2.1.3 排序步骤&#xff08;默认升序&#xff09; 2.1.4 代码实现 2.1.5 特性总结 2.2 希尔排序 2.2.1 基本思…

基于Xilinx UltraScale+ MPSOC(ZU9EG/ZU15EG)的高性能PCIe数据预处理平台

PCIE707是一款基于PCIE总线架构的高性能数据预处理FMC载板&#xff0c;板卡具有1个FMC&#xff08;HPC&#xff09;接口&#xff0c;1路PCIe x4主机接口、1个RJ45千兆以太网口、2个QSFP 40G光纤接口。板卡采用Xilinx的高性能UltraScale MPSOC系列FPGA作为实时处理器&#xff0c…

苹果手机充电充不进去什么原因?尝试这些方法拯救!

虽然苹果手机价格比较昂贵&#xff0c;但也抵挡不了大家对它的喜爱与追捧。无论是在国内还是国外&#xff0c;苹果手机都拥有着十分庞大的用户群体。 一些使用过苹果手机的朋友表示&#xff0c;苹果手机耗电快并且还出现过充不进电的情况。那么&#xff0c;苹果手机充电充不进…

【面试高高手】——Spring(12题)

文章目录 1.Spring是什么&#xff1f;2.为什么需要Spring?3.说下你对Spring的AOP、IOC的理解&#xff1f;4.基于java的AOP实现有哪些&#xff1f;5.AOP的原理&#xff1f;6.如何使用Java实现动态代理?7. Spring AOP和AspectJ AOP有什么区别&#xff1f;8.SpringAOP通知类型&a…

518抽奖软件,支持半透明框,让界面布局更美观规整

518抽奖软件简介 518抽奖软件&#xff0c;518我要发&#xff0c;超好用的年会抽奖软件&#xff0c;简约设计风格。 包含文字号码抽奖、照片抽奖两种模式&#xff0c;支持姓名抽奖、号码抽奖、数字抽奖、照片抽奖。(www.518cj.net) 半透明框的用途 把零散的界面元素统一放置在…

3秒钟解析超买超卖和Renko图表关系

不管是刚进入市场中的外汇新手&#xff0c;还是已经在外汇市场中赚的盆满钵满&#xff0c;只要还是外汇市场中的一份子&#xff0c;一定在不止一次听说过超买和超卖。今天FPmarkets澳福和各位投资者一起探讨超买超卖和Renko图表的关系。 超买在FPmarkets看来就是指大部分市场参…