news 2026/9/15 22:38:56

FPGA EEPROM读写测试:I2C时序与Verilog设计实战解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FPGA EEPROM读写测试:I2C时序与Verilog设计实战解析

简介:面向FPGA学习者的E2PROM读写测试Verilog HDL工程,基于Quartus 18.0设计,目标器件为Cyclone IV E系列EP4CE10F17C8,实现对AT24C16 EEPROM的I2C读写操作,并通过LED指示测试结果。工程采用模块化设计,包含顶层模块、读写控制模块、I2C驱动模块和LED告警模块;I2C驱动支持字节写、页写、当前地址读、随机读及顺序读等操作,读写控制模块则完成写入数据再读回比对,以检验存储与通信是否正确;顶层使用状态机调度,逻辑清晰且易于移植。压缩包内共263个文件,整体大小约6.57MB,除Verilog及VHDL源码外,还包含Quartus工程配置、编译报告、仿真数据库与可下载比特流文件,可直接打开工程编译并上板验证。目前已有388人学习下载。这一工程既适合初学者理解I2C协议与FPGA时序设计,也可作为课程设计或毕业设计中EEPROM读写模块的完整参考模板,节省搭建工程与调试驱动的时间。

1. 从 E2PROM 读写测试工程文件入手,先认清这套东西在验证什么

拿到“E2PROM读写测试Verilog HDL设计Quartus工程文件.zip”这类压缩包,多半是课设、毕设或者临时接手旧项目的场景。解压后最常见的动作是打开 .qpf、全编译、USB-Blaster 下载,然后板上 EEPROM 写进去的数据回读全是 0xFF。问题很少出在“测试逻辑”,而在那条很少被解释的链路:I2C 时序、器件地址、页边界和 tWR 写周期。这套 Verilog HDL 工程真正值钱的地方,是把你从“点亮一颗 LED”带到“跟一个真实器件完成协议握手”。它和 DDR4 读写测试那种靠时序训练和数据比对的方式完全是两套打法,读清协议才是关键。适合正在啃 Quartus 的新手,也适合想快速复用工程、不想在时序上栽跟头的工程师。

2. E2PROM 器件模型与 I2C 时序参数:读懂状态图再写 Verilog

2.1 先分清是哪种 E2PROM:并行 EEPROM 与 I2C EEPROM

标题里的 E2PROM 是 EEPROM 的常见写法,网上这类“读写测试”工程里九成以上都是 AT24C 系列 I2C 接口器件。它的物理接线很简洁:SCL 时钟线、SDA 双向数据线、WP 写保护,外加电源。但同样叫 E2PROM 的还有一批并行器件,比如 28C64、AT28C256,它们带 8 位数据总线,CE/OE/WE 控制线,写入时要求 WE 脉冲宽度不低于 100ns,读取时还要等 OE 到数据有效之间的延迟。两类的验证思路完全不同:并行器件是“给时序信号,看数据总线”,I2C 器件是“靠状态机在两根线上搬运字节”。

判断一个工程面向哪类,不用看文档,直接看顶层端口。如果顶层只有 scl、sda_in、sda_out 这类三线接法,就是 I2C;如果看到 data_i[7:0]、data_o[7:0] 和 we_n、ce_n、oe_n,说明工程带的是并行 EEPROM。后面所有讨论都按前者展开,这也是标题“读写测试”默认的常见做法。拿到工程先做这一步,能省掉后面一整天的迷茫。

2.2 AT24C 系列的器件地址与页结构:A2A1A0 怎么影响测试数据

I2C 总线上的第一个字节是器件地址。AT24C02 的地址字节固定格式为 1010 A2 A1 A0 R/W,A2/A1/A0 是芯片引脚电平,单芯片板上通常接地,所以写地址是 0xA0,读地址是 0xA1。到了 AT24C04 容量翻倍,A0 位被“内部块选择”占用,地址字节变成 0xA0 与 0xA2 两个;AT24C08 再吃掉 A1;AT24C16 则把 A2 也占掉。写测试前先查板上的丝印和原理图,确认器件地址没错,否则第一步就会卡在无应答上。

页结构是第二个容易坑人的地方。AT24C02 容量 256 字节,分成 8 页,每页 16 字节。页写(PAGE WRITE)一次最多写 16 字节,且不能跨页:写地址落在页边界附近时,内部地址计数器会回绕到本页开头,把数据覆盖到错误位置。读操作同样会回绕。测试序列如果从 0x0D 开始连续写 5 个字节,数据会被写到 0x0D、0x0E、0x0F、0x00、0x01,而不是用户直觉里的 0x12。这是读写测试“数据错乱”最常见的原因之一。

型号容量页大小写器件地址地址注意点
AT24C02256 B16 B0xA0页边界 0x0F/0x1F/...
AT24C04512 B16 B0xA0 / 0xA2P0 位替代 A0 参与寻址
AT24C081 KB16 B0xA0 / 0xA2 / 0xA4P1 位替代 A1
AT24C162 KB16 B0xA0 ~ 0xAEP2 位替代 A2

建议测试数据不要从 0 页的 0x00 开始写,因为许多板卡出厂会在这个区域烧录配置信息。我一般把测试地址选在 0x10,既跨过第一页边界附近,又不会撞上未初始化区域。

2.3 I2C 总线时序参数:START/STOP、ACK 与 tWR 写周期

I2C 协议只有两条线,却定义了完整的状态转换。主机把 SDA 在 SCL 高电平期间从 1 拉到 0,产生 START 条件;从 0 拉回 1 产生 STOP 条件。每个字节由 8 个 SCL 脉冲传输,第 9 个脉冲由从机拉低 SDA 表示应答 ACK。E2PROM 收到最后一个字节后会进入内部写周期,期间器件不响应任何命令,这段时间用 tWR 表示,AT24C 系列典型值是 5ms。

开始写 Verilog 之前,最好把数据手册里的时序参数表摆在手边。下面这组是 AT24C02 在 100kHz 标准模式下的关键值,400kHz 快速模式的参数明显收紧。

参数100kHz 标准模式400kHz 快速模式单位
SCL 时钟频率100400kHz
tSU:STA(起始条件建立时间)4.70.6us
tHD:STA(起始条件保持时间)4.00.6us
tSU:DAT(数据建立时间)250100ns
tHD:DAT(数据保持时间)00us
上升/下降时间30020ns

对 FPGA 来说,最容易违反的是 tSU:DAT:SDA 必须在 SCL 上升沿之前至少 100ns(快速模式)就稳定。不少初学者把 SDA 和 SCL 在同一拍翻转,结果器件读到的数据错位。设计控制器时,明确“SDA 在 SCL 低电平期间变化,在 SCL 高电平期间保持”,就能避开这个坑。

2.4 SCL 频率与分频系数:从系统时钟推导出 100kHz

常见开发板系统时钟是 50MHz,周期 20ns。要产生 100kHz 的 SCL,周期为 10us,半周期 5us,即 250 个系统时钟周期。分频系数可以参数化写成:

parameter SCL_FREQ_KHz = 100; // 目标 SCL 频率,单位 kHz parameter CLK_FREQ_MHz = 50; // 系统时钟,单位 MHz localparam WORD_CLK_DIV = (1_000_000 / (2 * SCL_FREQ_KHz)) / (1_000 / CLK_FREQ_MHz) - 1;

1_000_000 / (2 * SCL_FREQ_KHz)算出 SCL 半周期对应的纳秒数,对 100kHz 就是 5000ns;1_000 / CLK_FREQ_MHz算出单个系统时钟周期的纳秒数,对 50MHz 是 20ns;两者相除得到计数上限 250。时序状态机里每计满 250 拍翻转一次 SCL 输出,SDA 也在该时刻切换。把频率参数化而不是写死数值,后续要切到 400kHz 快速模式时只需改一行参数。用计数器的中间时刻切换 SDA、结束时刻翻转 SCL,就能天然满足前面说的数据建立时间。

3. Quartus 工程结构与 Verilog HDL 控制器实现:从模块划分到可综合代码

3.1 工程文件清单里到底有什么:.qpf / .qsf / .sdc / .v

解压 Quartus 工程后常见一堆文件,真正编译烧录需要的只有几类。.qpf 是 Quartus 项目文件,双击打开工程;.qsf 是设置文件,记录器件型号、顶层实体、引脚分配和综合选项,它决定工程能不能编译正确;.qsf 中如果带 .sdc 约束,说明工程在时序约束下工作,通常至少包含一条 create_clock 定义系统时钟。Verilog 源码通常有顶层、分频、I2C 控制器、显示模块几个角色。它们的分工可以用一张表概括。

文件作用编译时谁需要
.qpf项目入口Quartus 打开工程
.qsf器件型号、顶层、引脚分配全编译必须
.sdc时钟与输入输出延时约束TimeQuest 检查
.v设计源代码综合与布线

如果拿到旧工程,Quartus 版本跨度大(比如 9.1 的工程用 16.0 打开)会提示升级,升级后 .qsf 会被重写,引脚分配一般能保留,但个别 IP 核需要重新生成。用文本编辑器打开 .qsf 看一段常见内容:

set_global_assignment -name FAMILY "Cyclone IV E" set_global_assignment -name DEVICE EP4CE6E22C8 set_global_assignment -name TOP_LEVEL_ENTITY e2prom_test_top set_location_assignment PIN_E10 -to clk_50m set_location_assignment PIN_E11 -to rst_n set_location_assignment PIN_F5 -to sda set_location_assignment PIN_F6 -to scl set_global_assignment -name SDC_FILE e2prom_test.sdc

FAMILY 和 DEVICE 两行指定芯片型号和封装,下载时选错器件会直接报 mismatch。TOP_LEVEL_ENTITY 必须和顶层模块名一致。set_location_assignment 的引脚号要按照自己板卡原理图改,不同开发板共用一套引脚的情况很少。新版 Quartus Prime 仍然兼容这套 qsf 语法,所以从 Quartus II 13.1 换到 Prime 18.0,工程文件可以沿用,只是第一次编译会慢一些。

3.2 分频与三态 IO:把 50MHz 转成 SCL 并处理双向 SDA

I2C 的 SDA 是双向端口,Verilog 里要用 inout,并靠三态门控制输出。分频模块只负责产生 SCL 半周期的 tick 信号,I2C 控制器在每个 tick 边界推进状态。常见做法是分频器输出一个单周期脉冲,而不是直接生成占空比 50% 的时钟,因为状态机需要在 SCL 下降沿、上升沿附近分别处理不同的操作。

module scl_tick_gen #( parameter CLK_FREQ_MHz = 50, parameter SCL_FREQ_KHz = 100 )( input wire clk, input wire rst_n, output reg tick ); localparam CNT_MAX = (1_000_000 / (2 * SCL_FREQ_KHz)) / (1_000 / CLK_FREQ_MHz) - 1; reg [15:0] cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin cnt <= 16'd0; tick <= 1'b0; end else if (cnt == CNT_MAX) begin cnt <= 16'd0; tick <= 1'b1; // 每 250 拍输出一个脉冲 end else begin cnt <= cnt + 1'b1; tick <= 1'b0; end end endmodule

tick 信号每 5us 出现一次,I2C 控制器把它当作“半拍”事件:第一个 tick 拉低 SCL 并改变 SDA 上的数据,第二个 tick 拉高 SCL 让从机采样。这样 SDA 天然是在 SCL 低电平期间改变的,tSU:DAT 得到保证。CNT_MAX 的推导和 2.4 节一致,只是这里把计数动作独立成模块,仿真时直接把 SCL_FREQ_KHz 改成 10000 就能加速波形观察。

3.3 I2C 控制器状态机:IDLE、START、发字节、ACK、STOP

控制器的核心是状态机。常见写法是六个状态:空闲、起始、发送字节、等待应答、等待写周期、停止。发送字节时用一个 bit_cnt 从 7 数到 0,第 8 拍结束后释放 SDA,第 9 拍读取从机 ACK。下面是状态定义和主转移的骨架,完整模块还要按 2.3 节的时序参数在状态切换处插入计数等待。

localparam S_IDLE = 3'd0; // 总线空闲,等待命令 localparam S_START = 3'd1; // 产生 START 条件 localparam S_BYTE = 3'd2; // 移位发送一个字节 localparam S_ACK = 3'd3; // 采样从机应答 localparam S_TWR = 3'd4; // 写周期等待 localparam S_STOP = 3'd5; // 产生 STOP 条件 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= S_IDLE; scl <= 1'b1; sda_out <= 1'b1; bit_cnt <= 3'd7; end else if (scl_tick) begin case (state) S_IDLE: if (start_cmd) state <= S_START; S_START: begin sda_out <= 1'b0; // SCL 高电平期间拉低 SDA state <= S_BYTE; bit_cnt <= 3'd7; tx_byte <= cmd_addr; // 载入器件地址 0xA0 end S_BYTE: begin scl <= 1'b0; sda_out <= tx_byte[bit_cnt]; // 高位在前 if (bit_cnt == 0) state <= S_ACK; else bit_cnt <= bit_cnt - 1'b1; end S_ACK: begin sda_out <= 1'bz; // 释放 SDA,让从机拉低 scl <= 1'b1; if (!sda_in_sync) state <= S_TWR; else state <= S_STOP; // 无应答按停止处理 end // S_TWR 中等待 twr_done,随即进入写地址或数据阶段 endcase end end

这段代码的关键点有两个。第一个是 S_START 和 S_BYTE 之间的 SCL 电平衔接:START 条件要求 SCL 为高时 SDA 产生负跳变,之后 SCL 必须拉低才能开始传数据,所以进 S_BYTE 的第一个动作是把 SCL 置 0。第二个是 ACK 采样:SDA 释放为高阻后要先同步打两拍,消除亚稳态,再判断从机是否应答。AT24C 无应答时 SDA 会被上拉电阻保持为高,状态机最好进 STOP 而不是死锁。

3.4 读写测试主控:写入固定序列再回读比较,用 LED 展示结果

有了 I2C 控制器,剩下的是测试主控逻辑。我的习惯是设计成按键触发单次测试:按下按键后,主控按“合并写 3 字节 → 等待 5ms → 随机读回 3 字节 → 逐字节比较”的流程工作,结果用 LED 指示。合并写可以一次 PAGE WRITE 完成,也可以写成三次单字节写,测试工程用三次单字节写更直观,方便用示波器观察完整地址序列。

reg [1:0] st; reg ok_flag; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin st <= 2'd0; ok_flag <= 1'b0; end else case (st) 2'd0: if (key_neg) begin // 按键下降沿触发 i2c_dev_addr <= 8'ha0; // 器件写地址 i2c_word_addr <= 8'h10; // 写入起始地址 i2c_wdata <= 8'ha5; // 测试数据 A5 st <= 2'd1; end 2'd1: begin start_write; // 发写命令脉冲给控制器 if (write_done) st <= 2'd2; end 2'd2: begin start_read; // 回读同一地址 if (read_done) begin ok_flag <= (i2c_rdata == 8'ha5); st <= 2'd0; end end endcase end

start_writestart_read在完整工程里是发给 I2C 控制器的命令脉冲,控制器完成后回 write_done/read_done。比较时只比较读回的最后一个字节,因为前面命令字节会先出现在总线上,有效数据对应读序列的最后一拍。若 ok_flag 为 1,LED 常亮几次;为 0 则闪烁,不用串口也能一眼看出测试结果。测试地址选 0x10 正是 2.2 节说的,避开出厂占用的首页。

4. ModelSim 仿真与 Quartus 联合调试:上板之前先让波形说话

4.1 testbench 怎么搭:模拟从机响应和按键信号

仿真环境有两个任务:产生时钟、复位、按键信号,以及模拟 E2PROM 从机回波。AT24C 行为模型可以简化成:收到器件地址字节后,若匹配 0xA0/0xA1 就回 ACK,写操作把地址和数据存进一个数组,读操作把数组内容移出。下面是 testbench 的关键结构,重点看从机握手回写。

module tb_e2prom; reg clk = 1'b0; always #10 clk = ~clk; // 50MHz,周期 20ns reg rst_n, key_n; wire scl, sda; e2prom_test_top dut ( .clk_50m (clk), .rst_n (rst_n), .key_n (key_n), .scl (scl), .sda (sda) ); i2c_slave_model #(.DEV_A2A1A0(3'b000)) u_slave ( .scl(scl), .sda(sda) ); initial begin rst_n = 0; key_n = 1; #200 rst_n = 1; // 复位释放 #5000 key_n = 0; #100 key_n = 1; // 模拟按键按下 #20_000_000 $finish; // 覆盖 tWR 与读操作 end endmodule

#10翻转一次产生 20ns 周期,正好对应 50MHz。按键用“拉低 100ns 再释放”模拟,真实按键在工程里要加消抖。从机模型内部用一个数组做存储,每个字节的第九拍采样 SDA 判断 ACK。仿真时间要覆盖完整流程:一次单字节写、tWR 5ms、一次读,至少 20ms,#20_000_000是 20ms,这个时间必须给够,否则看不到回读结果。

4.2 波形上盯哪几个点:START、ACK 与第九个 SCL 上升沿

仿真跑完先看整体结构,再放大局部。第一眼看 scl 和 sda 上是否有 START/STOP 边界;第二眼看每个字节的第 9 个 SCL 上升沿,SDA 是否被从机拉低;第三眼看写入完成后主控是否等待了 tWR 再发起读。用 ModelSim 的 cursor 直接对比 scl 和 sda 的电平关系,能快速定位“SDA 在 SCL 高电平时翻转”这类非法时序。

常见问题在波形上特征很明显。ACK 永远为高,说明器件地址没对上,检查 2.2 节的 A2A1A0。数据错位,说明 SDA 在 SCL 上升沿附近变化,回到 3.3 状态机里检查“tick 后半拍才更新 SDA”这个节奏。波形里写命令重复发送,说明主控误判 write_done,往往是状态机出口条件多打了一个 tick。把状态寄存器和 bit_cnt 一起加进波形列表,比单看总线更容易定位是哪个状态停住。

4.3 Quartus II 无法启动 ModelSim 与仿真设置:一组对照排查

Quartus 调用外部 ModelSim 最常报的就是 “cannot launch ModelSim”,原因集中在路径与仿真工具绑定。先到 Tools -> Options -> EDA Tool Options 里检查 ModelSim 安装路径;再到 Assignments -> Settings -> EDA Tool Settings -> Simulation 把仿真工具设为 ModelSim-Altera,并指定 Test Bench 文件。

报错现象常见原因处理步骤
cannot launch ModelSim路径没配置或版本位数不匹配指定 modelsim.exe 完整路径,64 位对 64 位
仿真波形空白仿真工程缺少顶层模块Settings 里重新 Add Test Bench,绑定测试模块
报找不到 IP 核.qsf 版本升级后 IP 路径失效重新 Generate IP,或把工程放到原路径
仿真数据为 Xtestbench 未给 rst_n 初始值initial 块先拉低复位再释放

老版本 Quartus II 13.1 自带 ModelSim-Altera 10.1d,新版 Quartus Prime 的仿真设置入口稍有变化,但排查顺序不变。仿真通过了再上板,板级调试才有意义。

5. 上板调试的排错清单:写入不生效、回读 0xFF 与烧录链路问题

5.1 写入后读回总是 0xFF:九成是没等 tWR 或地址不对

上板之后第一个经典现象是写完立刻读会读到 0xFF。原因基本是内部写周期冲突:AT24C 在 tWR 期间对总线命令无响应,读请求落在写周期里,器件自然给不出数据。先看主控里有没有“写完成后再延时 5ms”的步骤;没有就加,在地址、数据都正确的前提下插一个 6ms 延时再发读命令,问题通常当场消失。第二个原因是 WP 引脚被拉高,整个芯片进入写保护,写操作全部丢弃。查原理图里 WP 接法,开发板上通常接地或由跳线控制,被跳线拉高时会犯这个毛病。

排错顺序建议固定成:先读固定地址(比如 0x10),读出来若是 0xFF 且地址正确,基本排除器件供电;用示波器看写波形,确认 STOP 条件之后的确等了足够时间;再看 WP 是低还是高。这套顺序能覆盖绝大多数写入不生效的场景。

注意:GPIO 直连的 SCL/SDA 走线通常没有端接,调试时用杜邦线越短越好,手捏着线头看波形没有参考价值。

5.2 回读数据与写入不一致:页边界、SCL 速率和总线竞争

数据写进去了但读回来对不上,按三件事排查。第一件是页边界回绕,参考 2.2 节,把测试数据控制在页内。第二件是 SCL 频率过高,400kHz 快速模式对线缆和上拉电阻要求高,杜邦线悬空连接时边沿过缓容易造成数据采样错误,先降到 100kHz 验证。第三件是总线竞争,少数开发板的 SCL/SDA 与板上其他 I2C 器件共享,从机地址冲突或总线被另一主机占用都会造成回读错乱,断电后用万用表量两个引脚的电平,再查原理图确认是否与 EEPROM 之外的外设复用。

// 回读比较时的延时控制,6ms 延时计数器 reg [19:0] twr_cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) twr_cnt <= 20'd0; else if (state == S_TWR) twr_cnt <= twr_cnt + 1'b1; // 0.02us 一拍,计满 6ms end assign twr_done = (twr_cnt >= 20'd300000);

20 位计数器最大值约 100 万,对 50MHz 时钟能计到 20ms。这里把 tWR 等待做成显式状态而不是敷衍的延时,是为了让波形能直接看出等待时间,调试时把 twr_cnt 加进波形列表,一眼就能判断控制器是否给了器件足够的时间。

5.3 下载与烧录的杂项:USB-Blaster 驱动、Programmer 卡顿和引脚分配

下载环节三个高频问题。第一是设备管理器里找不到 USB-Blaster,Quartus II 安装目录下通常有 64 位驱动,手动指向 inf 文件安装即可;Quartus Prime 安装包驱动路径有变化,找不到时用 WinUSB 工具更换驱动也能解决。第二是 Quartus Programmer 打开文件时卡顿,常见原因是工程目录在机械盘或杀毒软件实时扫描,把 .sof 复制到本地临时目录再加载通常就顺畅;Programmer 界面卡住时不要反复点,等几秒或直接重启软件。第三是引脚分配遗漏,FPGA 的 JTAG 可以正常下载,但功能不跑,先看 Assignment Editor 里 scl/sda 是否都分配了引脚且电平标准与板卡一致。

现象处置
找不到 USB-Blaster 设备手动安装 inf 驱动或更换 WinUSB 驱动
Programmer 打开文件卡顿把 .sof 复制到本地临时目录再加载
下载正常但功能不跑检查 Assignment Editor 引脚与电平标准

6. 把读写测试工程改造成可靠模块:连续写读与自校验

6.1 参数化总线频率与命令队列,让控制器可复用

前面手写状态机已经能完成单字节读写,要变成可复用 IP,第一步把所有频率常数和地址参数化。器件地址、起始地址、每次读写的字节数都用 parameter 暴露出来,顶层例化时只需改参数。第二步把主控的状态机改成“接受命令帧”的模式,主控侧定义取指令接口,I2C 控制器侧定义 read_req / write_req 请求和 done、error 响应,两个模块用寄存器握手。这样同一套 I2C 控制器既能服务 E2PROM,也能服务温度传感器或 RTC 芯片。

6.2 给命令加超时与重试:从演示工程走向可靠模块

AT24C 在写周期里收到的任何命令都不会应答,如果主控没有等待机制,重试逻辑会和器件内部写周期打架。可靠做法是发起命令前先确认总线空闲,发送后等 ACK 超时,超时则重新发送 START 并重试一次;重试两次仍失败就进入 ERROR 状态。超时计数可以直接借用 5.2 的 twr_cnt 寄存器,把 error_flag 和状态编码映射到板载 LED。调试时看到 LED 闪烁次数不同,就能判断是器件无应答还是写周期等待不够,这一招比一根一根量波形快得多。

6.3 最后留一个验证清单,测试工程才算闭环

改造完成后按下面的顺序自测:第一次上电全读写一遍验证掉电保持;单字节写读验证寻址;跨页连续写 20 字节验证页边界处理;把 SCL 参数改成 400kHz 验证高速模式是否稳定;人为把 WP 拉高验证错误上报路径。每一步都记录写入地址和数据,回读不一致时回到第 5 章的排错顺序。走到这里,标题里的那套工程文件已经被消化成自己手里的可复用模块,下一次再做带电可擦除存储的板卡,直接例化即可,不用回头翻数据手册。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 22:37:55

精通MySQL的Sql编写优化及索引优化,理解Sql执行流程,理解底层各类锁、索引和日志机制,MVCC与事务控制,可进行主备搭建,配置优化,异构数据同步。并熟悉ClickHouse和TDengine

Sql执行流程Server层 1.连接器&#xff0c;负责处理客户端的连接请求&#xff0c;分配一个线程来处理该连接&#xff0c;每个连接线程会创建一个会话&#xff08;session&#xff09;&#xff0c;在这个会话中&#xff0c;客户端可以发送SQL语句进行增删改查等操作。 2.解析器&…

作者头像 李华
网站建设 2026/9/15 22:34:22

光伏电站泄流效应与配电网无功优化MATLAB实现

1. 项目背景与核心问题光伏电站并网运行时产生的泄流效应是影响配电网无功优化的关键因素之一。当光伏渗透率超过一定阈值时&#xff0c;传统以负荷为中心的无功补偿方案往往会导致节点电压越限、网损增加等问题。这个项目要解决的正是如何在IEEE 33节点系统中&#xff0c;建立…

作者头像 李华
网站建设 2026/9/15 22:32:24

Halcon芯片缺角检测:亚像素几何验证与产线稳定实践

1. 项目概述&#xff1a;为什么芯片缺角检测必须用 Halcon 而不是 OpenCV 或传统阈值法&#xff1f;在半导体封装产线的实际运行中&#xff0c;“检测、分选、固晶”这三个工序是环环相扣的硬性流水节拍。其中“缺角检测”看似只是图像识别中的一个子任务&#xff0c;但它的误判…

作者头像 李华