前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >大白话 mysql 之详细分析 mysql 事务日志

大白话 mysql 之详细分析 mysql 事务日志

作者头像
会玩code
发布于 2022-04-24 06:07:30
发布于 2022-04-24 06:07:30
79701
代码可运行
举报
文章被收录于专栏:会玩code会玩code
运行总次数:1
代码可运行
在后端面试中,mysql 是比不可少的一环,其中对事务和日志的考察更是 "重灾区", 大部分同学可能都知道 mysql 通过 redolog、binlog 和 undolog 保证了 sql 的事务性,也可以用于数据库的数据恢复,但再深入一点,如何保证事务性?更新时数据具体是如何写到磁盘的?这两个日志内容不一致怎么办?写日志也要将日志写到磁盘中,为什么会比直接写数据到磁盘效率更高?..., 这些如果一问三不知,面试官(尤其大厂面试)也差不多让你回去等消息了。

redo log 与 binlog

虽然可能大部分文章都有介绍过,但为了文章的完整性,我们还是从 redo log 和 binlog 的区别聊起。

位置不同

首先就是两个日志所处的位置不同了,mysql 的整体架构可分为 server 层和存储引擎层,mysql 采用插拔式的存储引擎,常见的存储引擎有 myisam、innodb、memory 等,在创建表时指定要使用的存储引擎 (create table .... engine=innodb)。

binlog 是存在于 server 层的日志,也就是无论使用哪种存储引擎,都能使用 binlog 记录执行语句。而 redolog 是 innodb 存储引擎特有的。

大小不同

binlog 分多个日志文件记录,单个文件的大小通过 max_binlog_size 设置,采用追加的方式写入,当 binlog 大小超过 max_binlog_size 设置的大小会创建新的日志文件,然后切换到新文件继续写入。此外,可通过 expire_logs_days 设置 binlog 日志保留的天数。

redolog 的大小是固定的,在 mysql 中可以通过修改配置参数 innodb_log_files_in_groupinnodb_log_file_size 配置日志文件数量和每个日志文件大小,采用循环写的方式记录,当写到结尾时,会回到开头循环写日志。

记录内容不同

binlog 记录操作的方法是逻辑性的语句。有 statement 和 row 两种记录格式, statement 格式记 sql 语句;row 格式会记录更新前和更新后行的内容.

而 redolog 记录的是数据库中每个页的修改。比如 “在某个数据页上做了什么修改”

二阶段更新流程

了解了两种日志的区别后,我们再来通过一条更新语句的执行流程来看看这两个日志分别如何写入的。语句内容为 update t set a = a + 1 where id = 1

  1. 执行器通过 innodb 引擎获取 id = 1 的数据,如果数据本身在内存中,会直接返回给执行器;否则,先从磁盘中读入内存,再返回。
  2. 执行器拿到引擎给的行数据,把这个值加上 1,得到新的一行数据,再调用引擎接口写入这行新数据。
  3. 引擎将这行新数据更新到内存中。然后将对内存数据页的更新内容记录在 redolog buffer 中,此时,buffer 中的这条语句状态为 prepare。然后告知执行器执行完成了,随时可以提交事务。
  4. server 层提交事务时,会先将这个操作的日志写入 binlog buffer 中,再调用引擎的事务提交接口,引擎会将刚写入的 redolog 记录状态修改为 commit。更新完成。

可以发现,一次更新后,不仅数据存在内存中,redolog 和 binlog 也是先写到内存中,之后再根据设定的落盘机制进行日志落盘。

日志落盘

binlog 落盘策略

mysql 通过 sync_binlog 参数来控制 binlog buffer 的日志落盘策略。

sync_binlog = 0, 表示 mysql 不控制 binlog 的刷新,使用文件系统的缓存刷新策略,这时性能最好,同时风险也是最大的,一旦系统 crash,binlog buffer 中的日志数据都将丢失。

sync_binlog = 1 表示每次提交事务都会将 buffer 中的日志数据同步刷到磁盘中,最安全但由于刷盘频率较高,性能也是最差的。

sync_binlog > 1 表示 binlog buffer 每写入 sync_binlog 次事务后,再刷日志数据到磁盘中。

redolog 落盘策略

在讲 redolog 持久化之前,我们先了解下 write 和 fsync 两个系统调用,操作系统中,内存被划分为用户空间和内核空间,用户空间存放着应用程序的缓存数据,redolog buffer 就存在于用户空间中,要把用户空间的数据持久化到磁盘中,需要先调用 write 系统调用,把数据先写入内核空间,之后再调用 fsync 系统调用,将内核空间的数据写入到磁盘中。

mysql 通过 innodb_flush_log_at_trx_commit 参数控制 redo log buffer 写入磁盘的时机。

innodb_flush_log_at_trx_commit = 0 表示事务提交时,日志继续保存在 redolog buffer 中,根据 innodb_flush_log_at_timeout 设置的间隔调用 write 和 fsync 将日志持久化到磁盘中,innodb_flush_log_at_timeout 默认为 1,也就是日志每秒写入到磁盘中。批量写入,io 性能较好,但数据丢失风险较大。

innodb_flush_log_at_trx_commit = 1 表示事务提交时,都将调用 write 和 fsync 将日志写入磁盘。这种方式不会丢失任何数据,但 io 性能较差。

innodb_flush_log_at_trx_commit = 2 表示事务提交时,都会调用 write 将日志写入到内核缓存中,之后每秒调用 fsync 将日志写入磁盘。这种也比较安全,即使 mysql 程序奔溃了,os buffer 中的日志也不会丢失。当然,如果操作系统也奔溃了,这部分日志也就不见了。

Q&A

❝Q: 处于 prepare 状态的 redolog 会被刷新到磁盘中吗? A: 会的,例如同一时刻,有 a 和 b 两个事务,a 处于 prepare,b 进行 commit 触发日志刷盘,这时会把 a 的 redo 日志也刷到磁盘中。 ❞

❝Q: binlog 是否是多余的,可以使用 redolog 代替 binlog 吗? A: 首先,就支持事务方面,binlog 确实用处是不大的,在奔溃恢复的时候需要通过 binlog 确定事务是否该提交也只是避免 binlog 被应用到备库上了,如果主库直接回滚会导致主备数据不一致。 但 binlog 的” 归档 “功能是 redolog 不具备的。redolog 大小固定,采用循环写,较早的日志会被覆盖,无法持久保存,而 binlog 是不限制大小的,日志追加写入。只要有保留 binlog 日志,可以恢复数据库任何时刻的状态。 ❞

❝Q: binlog 和 redolog 的几种落盘策略,也是频繁写磁盘,与直接数据写磁盘有什么区别吗? A: 日志文件是存储在连续的若干个数据页中的,所以在写日志到磁盘时只需要进行一次寻址,属于顺序读写;而写数据时,一次事务可能需要改动的数据可能涉及好几个离散的数据页,写磁盘时需要进行多次「寻道 -> 旋转」的寻址过程,属于随机读写,速度比顺序读写差了好几个数量级。 ❞

数据落盘

为了避免频繁写入磁盘导致的性能瓶颈,数据页先在内存中修改,在内存中发生过修改的页称为脏页 (因为此时页中的数据与磁盘的不一致,是” 脏 “的), 改动的数据页需要找时间同步到磁盘中,这个过程称为” 刷脏页”。

LSN

在 innodb 中,每对一个数据页的修改,都会生成一个 8 字节的序列号 lsn 来标记版本,lsn 的值全局单调递增,随着日志的写入而逐渐增大,lsn 存在于数据页和 redo log 中。 在整个更新过程中,有几个 lsn 比较值得关注:

  1. 修改内存数据页中的数据时,会更新内存数据页中的 LSN,暂称为 data_in_buffer_lsn。
  2. 向 redolog buffer 写入日志时,会记录下对应的 LSN,暂称为 redo_log_in_buffer_lsn。
  3. 当触发到 redolog 的几种刷盘策略时,会将 redolog buffer 中的日志刷入磁盘中,并在该文件记下对应的 LSN,暂称为 redo_log_on_disk_lsn。
  4. 数据从内存中刷到磁盘时,会在磁盘上对应的数据页记录下当前的 LSN,暂称为 data_on_disk_lsn。
  5. innodb 会在适当的时候将 redolog 上记录的对应数据页的改动同步到磁盘中,同步进度也是通过 lsn 标示,称为 checkpoint_lsn。(后文会详细介绍)

可以通过 show engine innodb status 查看各 lsn 的值。

❝lsn 可以理解为数据库从创建以来产生的 redo 日志量,这个值越大,说明数据库的更新越多,也可以理解为更新的时刻。此外,每个数据页上也有一个 lsn,表示最后被修改时的 lsn,值越大表示越晚被修改。比如,数据页 A 的 lsn 为 100,数据页 B 的 lsn 为 200,checkpoint lsn 为 150,系统 lsn 为 300,表示当前系统已经更新到 300,小于 150 的数据页已经被刷到磁盘上,因此数据页 A 的最新数据一定在磁盘上,而数据页 B 则不一定,有可能还在内存中。 ❞

下面我们来讨论下 innodb 中发生刷脏页的几种时机。

数据落盘时机

定时刷新

innodb 的主线程会定时将一定比例的脏页刷新到磁盘中,这个过程是异步的,不会影响到查询 / 更新等其他操作。

系统内存不够用

innodb 会维护一个内存数据页的 lru 列表,并通过一个单独的 page clear 线程来保证一定的空闲数据页,当空闲页不足时,会将 lru 尾部的内存页淘汰掉,如果淘汰的页中有脏页,会先将脏页数据刷新到磁盘中。

脏页比例过高

innodb 中,有个 innodb_max_dirty_pages_pct 参数,用于控制脏页在内存中的占比,当脏页比例超过设置的比例后,会刷新一部分脏页到磁盘中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show variables like 'innodb_max_dirty_pages_pct';
+----------------------------+-----------+
| Variable_name              | Value     |
+----------------------------+-----------+
| innodb_max_dirty_pages_pct | 90.000000 |
+----------------------------+-----------+

数据库正常关闭

参数 innodb_fast_shutdown 控制着数据库关闭时的落盘策略,当设置为 1 时,会将所有的日志脏页和数据脏页都刷新到磁盘中;设置为 2 时,仅保证日志落盘。

redo log checkpoint 刷盘

再回顾下更新的流程,更新操作记录到 redolog,数据更新到内存中,整个更新操作就算结束了。 如果数据库异常关闭了,下次启动时,我们需要根据 redolog 将相应的数据页的数据改动恢复回来。

但 redolog 大小是固定的,采用循环写的模式,写到结尾时,会回到开头循环写日志。 所以,随着更新操作次数的积累,redolog 上的记录会被覆盖掉,有些改动也就丢失了。

那不限制 redolog 的大小可以吗? 可以试想下,redolog 达到 1TG,数据库数据量有 10TG,异常重启时,为了恢复数据页的改动。我们需要读取 1T 的日志进行恢复。如果全部的数据页都发生了修改,我们还需要将 10TG 的数据全部载入到内存中。 所以,不限制 redolog 大小后,会出现另外两个问题:

  1. 恢复速度较慢;
  2. 内存无法缓存数据库所有的数据。

redolog 采用 checkpoint 策略,会定期将 redolog 上的数据修改逐渐刷新到磁盘中,同步进度用 lsn 标示,称为 checkpoint_lsn。redolog 根据 checkpoint_lsn 可以划分为两部分,小于 checkpoint_lsn 的日志对应的数据页改动已经刷新到磁盘中,这部分日志可被覆盖重新写入;大于 checkpoint_lsn 部分日志对应改动还未同步到磁盘。

redolog checkpoint 刷盘分为异步刷盘和同步刷盘。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
checkpoint_age = redo_lsn - checkpoint_lsn
async_water_mark = 75% * total_redo_log_file_size
sync_water_mark = 90% * total_redo_log_file_size

checkpoint_age < async_water_mark, 表示当前脏页数据较少,不会触发 redolog checkpoint 刷盘。

async_water_mark < checkpoint_age < sync_water_mark, 会异步将一定量的脏页刷新到磁盘中,使得满足 checkpoint_age < async_water_mark。异步刷新不会影响其他更新操作。

checkpoint_age > sync_water_mark, 当 redolog 容量设置的较小,同时进行大量的更新操作,导致剩余可使用的日志较少,会触发同步刷新,将脏页刷新到磁盘中,直到满足 checkpoint_age < async_water_mark,同步刷新会阻塞用户的更新操作。

Q&A

❝Q: 除了 redolog checkpoint,其他几种情况刷脏页会推动 checkpoint_lsn 吗? A: 不会。缓冲池会维护一个管理脏页的 flush_list, 一个数据页因修改了数据成为脏页后,会添加到 flush_list 中,脏页在刷新到磁盘中后,会从 flush_list 中去掉。 flush_list 按数据页的最早修改 lsn (oldest_modifcation) 从小到大排序。比如一个干净页变为脏页后,data_in_buffer_lsn=100,在 flush_list 的位置为 1,当数据页再次发生改动时,data_in_buffer_lsn 变为 120,但在 flush_list 的位置不变。 进行 redo checkpoint 时,选择的日志只需要与 flush_list 上最老的页 (拥有 flsuh_list 上最小的 lsn) 进行比较即可:

  1. page_noflush_list != page_noredo, 表示该脏页数据已被同步到磁盘中,推进 checkpoint_lsn。
  2. page_noflush_list == page_noredo, 将该脏页刷新到磁盘中,推进 checkpoint_lsn。

❝Q: checkpoint 信息存在哪?如何存储? A: checkpoint 信息存储在第一个 redo 日志文件的文件头中。储存采用双份存储,轮流读写的方式。 在第一个 redo 日志文件的文件头中有两个地方用于存储 checkpoint 信息,记录时来回读取这两个 checkpoint 域。假设只有一个 checkpoint 域,当更新 checkpoint 一半时,服务器也挂了,会导致整个 checkpoint 域不可用。这样数据库将无法做崩溃恢复,从而无法启动。如果有两个 checkpoint 域,那么即使一个写坏了,还可以用另外一个尝试恢复,虽然有可能这个时候日志已经被覆盖,但是至少提高了恢复成功的概率。两个 checkpoint 域轮流写,也能减少磁盘扇区故障带来的影响。 ❞

奔溃恢复

用户修改数据并成功提交了事务,此时数据改动在内存中还未落盘,如果这个时候数据库挂了,重启后,需要从日志中将成功提交的事务数据改动恢复后重新写入磁盘,保证数据不丢失,同时还要回滚没有提交的事务。奔溃恢复中,除了需要 redolog 和 binlog 日志,还离不开 undo 日志的支持。

undo log

进行更新操作时,都会产生 undo 日志:当 delete 一条记录时,会记录一条对应的 insert 日志。当 update 一条记录时,会记录一条对应相反的 update 日志。当 insert 一条记录时,会记录一条 delete 日志。

需要回滚事务时,只需要执行对应的 undo 操作,就可以将数据恢复。此外,通过 undo 日志,可以保证事务的隔离性。假设隔离级别设为读提交,当未提交的事务 A 修改了 id=1 对应的行数据,此时事务 B 想要读取 id=1 的数据,可以先拿着最新版本的数据,顺着 undo 日志找到满足其可见性的记录。

undo 日志与普通的数据页一样,对于 undo 页的修改,需要先写 redo 日志。也可能会由于 lru 的规则被淘汰出内存,之后再从磁盘中读取。

奔溃恢复流程

整个奔溃恢复流程可以分为 redo前滚undo回滚两部分。

redo 前滚

对于 checkpoint_lsn 之前的日志,对应改动已经落盘,不需要关心。首先初始化一个 hash_table,扫描 checkpoint_lsn 之后的日志,将同一个数据页的日志分发到 hash_table 的相同位置,并按日志的 lsn 从小到大排序。扫描后,遍历整个哈希表,依次应用每个数据页的日志。应用完后,内存中数据页的状态就恢复到了奔溃之前。

undo 回滚

接着,初始化 undo 日志,按操作类型分为 undo_insert_list 和 undo_update_list,遍历两个链表,根据日志中记录的事务的状态重建事务状态,TRX_ACTIVE 表示需要回滚,TRX_STATE_PREPARED 表示可能需要回滚。然后将事务加入到 trx_list 链表中,之后,遍历 trx_list,按照事务的不同状态回滚或提交。对于 TRX_ACTIVE 状态的事务,利用 undo 日志直接回滚;对于 TRX_STATE_PREPARED 状态的事务,根据 server 层的 binlog 来决定是否回滚,如果 binlog 已经写了并且日志是完整的,则提交该事务,否则就回滚。

Q&A

❝Q: undo 日志什么时候会删除? A: undo 按操作类型可分为 update/delete/insert, insert 操作在事务提交前只对当前事务可见,产生的 Undo 日志可以在事务提交后直接删除。而 update/delete 操作,其他事务可能需要老版本数据,需要保留到 undo 操作对应的事务 id 比数据库当前所有的事务快照都小(此时数据库所有事务对此次改动均可见),才可以删除。 ❞

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 会玩code 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
FPGA基础知识极简教程(6)UART通信与移位寄存器的应用
相关博文1单独介绍了各种类型的移位寄存器,其中就包括串行输入并行输出移位寄存器(SIPO)以及并行输入串行输出移位寄存器 (PISO)。移位寄存器有如下功能:
Reborn Lee
2020/06/29
1.4K0
源码系列:基于FPGA的数字电压表(AD)设计
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。
FPGA技术江湖
2020/12/29
1.5K0
源码系列:基于FPGA的数字电压表(AD)设计
FPGA零基础学习:UART协议驱动设计
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
FPGA技术江湖
2021/03/23
9000
FPGA零基础学习:UART协议驱动设计
FPGA零基础学习之Vivado-UART驱动教程
本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
FPGA技术江湖
2023/07/19
6030
FPGA零基础学习之Vivado-UART驱动教程
VCS与Verdi的联合仿真
Verdi主要用于生成fsdb模型,同VCS使用的vcd文件相比,verdi使用的fsdb相当于vcd文件经过霍夫编码压缩之后的精简版,可用于查看fsdb波形并追踪RTL代码。
根究FPGA
2020/07/28
9.3K0
VCS与Verdi的联合仿真
UART
UARTRS232 RS485 RS422区别RS232物理接口RS485物理接口RS422物理接口UART通信协议UART设计波特率产生模块发送模块接收模块顶层模块串口驱动下载
瓜大三哥
2020/05/29
1.3K0
FPGA实现uart_FPGA的EMU接口
UART即通用异步收发传输接口(Universal Asynchronous Receiver/Transmitter),简称串口,是一种常用的通信接口,其协议原理就不赘述了,不了解的可以自己查阅资料。(不赘述不代表不重要,相反,对于每一个FPGA设计,充分理解原理是基础和前提,而FPGA和Verilog只是工具。)用FPGA来实现UART,关键就是要将UART收发数据时的时序用Verilog描述出来。
全栈程序员站长
2022/10/05
7240
FPGA实现uart_FPGA的EMU接口
FPGA综合项目——SDRAM控制器
再者就是通信处理模块,具体的通信设置,发送什么命令是写?什么命令是读?发的什么数据?等等。
全栈程序员站长
2022/09/16
6320
FPGA综合项目——SDRAM控制器
跨时钟域传输总结(包含verilog代码|Testbench|仿真结果)
快时钟域相比慢时钟域采样速度更快,也就是说从慢时钟域来到快时钟域的信号一定可以被采集到。既然快时钟一定可以采集到慢时钟分发的数据,那么考虑的问题就只剩下如何保证采样到的信号质量!最常用的同步方法是双级触发器缓存法,俗称延迟打拍法。信号从一个时钟域进入另一个时钟域之前,将该信号用两级触发器连续缓存两次,可有效降低因为时序不满足而导致的亚稳态问题。
Loudrs
2023/06/08
5.2K1
跨时钟域传输总结(包含verilog代码|Testbench|仿真结果)
详解串行通信协议及其FPGA实现(二)
基于Verilog实现标准串口协议发送8位数据:起始位 + 8位数据位 + 校验位 + 停止位 = 11位,每1位的时间是16个时钟周期,所以输入时钟应该为:波特率*16,带Busy忙信号输出。实现方法比较简单,数据帧的拼接、计数器计时钟周期,每16个时钟周期输出一位数据即可。
单片机点灯小能手
2020/07/16
7450
源码系列:基于FPGA的PS2通信电路设计(附源码)
今天给大侠带来基于FPGA的PS2通信电路设计,附源码,获取源码,请在“FPGA技术江湖”公众号内回复“PS2源码”,可获取源码文件。话不多说,上货。
FPGA技术江湖
2020/12/30
7720
源码系列:基于FPGA的数模转换(DA)设计
大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。
FPGA技术江湖
2020/12/29
2.8K0
源码系列:基于FPGA的数模转换(DA)设计
串并转换(串入并出、并入串出、移位寄存器法和计数器法|verilog代码|Testbench|仿真结果)
经典电路设计是数字IC设计里基础中的基础,盖大房子的第一部是打造结实可靠的地基,每一篇笔者都会分门别类给出设计原理、设计方法、verilog代码、Testbench、仿真波形。然而实际的数字IC设计过程中考虑的问题远多于此,通过本系列希望大家对数字IC中一些经典电路的设计有初步入门了解。能力有限,纰漏难免,欢迎大家交流指正。快速导航链接如下:
Loudrs
2023/05/17
6.9K0
串并转换(串入并出、并入串出、移位寄存器法和计数器法|verilog代码|Testbench|仿真结果)
xilinx原语详解及仿真—ISERDESE2
前面在讲解HDMI接口之前,讲解过IDDR、ODDR、OSERDESE2、IBUF等原语,之后一直有读者在问什么时候更新ISERDESE2这个原语。前文讲解过这些原语都在HDMI或者RGMII中使用过,但是ISERDESE2这个原语目前我的板子除了HDMI输入,其余并不会使用到,所以当时就没有出。
FPGA技术江湖
2025/03/10
1260
xilinx原语详解及仿真—ISERDESE2
九种移位寄存器原理与设计(循环(左、右、双向)移位寄存器、逻辑和算术移位寄存器、串并转换移位寄存器、线性反馈移位寄存器LFSR)
经典电路设计是数字IC设计里基础中的基础,盖大房子的第一部是打造结实可靠的地基,每一篇笔者都会分门别类给出设计原理、设计方法、verilog代码、Testbench、仿真波形。然而实际的数字IC设计过程中考虑的问题远多于此,通过本系列希望大家对数字IC中一些经典电路的设计有初步入门了解。能力有限,纰漏难免,欢迎大家交流指正。快速导航链接如下:
Loudrs
2023/05/16
12.8K0
九种移位寄存器原理与设计(循环(左、右、双向)移位寄存器、逻辑和算术移位寄存器、串并转换移位寄存器、线性反馈移位寄存器LFSR)
【FPGA——基础篇】同步FIFO与异步FIFO——Verilog实现「建议收藏」
FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据, 其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
全栈程序员站长
2022/07/28
6K0
【FPGA——基础篇】同步FIFO与异步FIFO——Verilog实现「建议收藏」
串口通信控制器的Verilog HDL实现(一) 顶层模块
本设计采用分层设计思想,主要由顶层模块、波特率发生器、接收模块和发送模块这4个模块组成,强调功能划分明确,便于系统设计和调试。 本系统要求在Xilinx Spartan 3E Starter开发板上实现波特率为9600,停止位为1比特、不带校验位并且具备复位功能的串口通信控制器,并要求和PC机通过超级终端完成双向通信。不仅要求将板极发送数据显示在PC机的超级终端上,还要求用PC发送数据的ASCII码来驱动电路板的8个LED灯。为了便于测试,要求当按下开发板上的button_s时,板级发送的数值恢复到48,对
瓜大三哥
2018/02/24
1.7K0
串口通信控制器的Verilog HDL实现(一) 顶层模块
FPGA计算3行同列数据之和
本文介绍了如何利用FPGA实现Sobel边缘检测算法,通过仿真实验证明该方法可以大幅提高边缘检测的实时性,从而在嵌入式系统中得到广泛应用。
NingHeChuan
2018/01/05
1.4K0
FPGA计算3行同列数据之和
FPGA系统性学习笔记连载_Day13【简易计时器实验】之【Xilinx Spartan-6实现】篇
本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群联系群主。
FPGA技术江湖
2021/04/06
7720
FPGA系统性学习笔记连载_Day13【简易计时器实验】之【Xilinx Spartan-6实现】篇
基于FPGA的实时图像边缘检测系统设计(下)
今天给大侠带来基于FPGA的实时图像边缘检测系统设计,由于篇幅较长,分三篇。今天带来第三篇,下篇,话不多说,上货。
FPGA技术江湖
2021/04/19
7200
基于FPGA的实时图像边缘检测系统设计(下)
推荐阅读
相关推荐
FPGA基础知识极简教程(6)UART通信与移位寄存器的应用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验