当前位置: 首页 > news >正文

verilog练习:i2c slave 模块设计

文章目录

  • 前言
  • 1. 结构
  • 2.代码
    • 2.1 iic_slave.v
    • 2.2 sync.v
    • 2.3 wr_fsm.v
      • 2.3.1 状态机状态解释
    • 2.4 ram.v
  • 3. 波形展示
  • 4. 建议
  • 5. 资料总结


前言

首先就不啰嗦iic协议了,网上有不少资料都是叙述此协议的。

下面将是我本次设计的一些局部设计汇总,如果对读者有借鉴意义那最好,如果没有的话也无所谓,互相交流而已。(这是我早期的版本,注释比较少,代码编写比较混乱,读者自便)

希望读者发现问题可在下方留言,我会及时回答或者修改。


1. 结构

顶层结构图在这里插入图片描述
master结构图
在这里插入图片描述
slave结构图
在这里插入图片描述

2.代码

2.1 iic_slave.v

`timescale 1ns/1psmodule iic_slave (input rstn,input clk,input scl,inout sda,input [7:0] q,  // RAM data to slaveoutput wen,output [7:0] d, // Slave data to RAMoutput [7:0] a  // Slave address to RAM
);// Internal signals
wire sync_scl_1;
wire sync_sda_1;
wire sda_posedge;
wire sda_negedge;
wire scl_posedge;
wire scl_negedge;
wire sda_out;
wire sda_oen;// Three-state gate for SDA
assign sda = (sda_oen) ? sda_out : 1'bz;// Instantiate sync module
sync sync (.clk(clk),.rstn(rstn),.scl(scl),.sda(sda),.sync_scl_1(sync_scl_1),.sync_sda_1(sync_sda_1),.sda_posedge(sda_posedge),.sda_negedge(sda_negedge),.scl_posedge(scl_posedge),.scl_negedge(scl_negedge)
);// Instantiate RAM module
ram ram (.clk(clk),.rstn(rstn),.d(d),.a(a),.q(q),.wen(wen)
);// Instantiate write FSM module
wr_fsm wr_fsm (.clk(clk),.rstn(rstn),.sync_scl_1(sync_scl_1),.sync_sda_1(sync_sda_1),.scl_posedge(scl_posedge),.scl_negedge(scl_negedge),.sda_posedge(sda_posedge),.sda_negedge(sda_negedge),.d(d),.a(a),.q(q),.wen(wen),.sda_out(sda_out),.sda_oen(sda_oen)
);endmodule

2.2 sync.v

`timescale 1ns/1ps
module sync (rstn,clk,scl,sda,sync_scl_1,sync_sda_1,sda_posedge,sda_negedge,scl_posedge,scl_negedge
);input rstn;input clk;input scl;input sda;output sync_scl_1;output sync_sda_1;output sda_posedge;output sda_negedge;output scl_posedge;output scl_negedge;reg sync_scl_1;reg sync_sda_1;reg sync_scl_0;reg sync_sda_0;always @(posedge clk or negedge rstn) beginif (!rstn) beginsync_scl_1 <= 1'b0;sync_sda_1 <= 1'b0;sync_scl_0 <= 1'b0;sync_sda_0 <= 1'b0;end else beginsync_scl_0 <= scl;sync_sda_0 <= sda;sync_scl_1 <= sync_scl_0;sync_sda_1 <= sync_sda_0;endendassign sda_posedge = (sync_sda_0) & (~sync_sda_1);assign sda_negedge = (~sync_sda_0) & (sync_sda_1);assign scl_posedge = (sync_scl_0) & (~sync_scl_1);assign scl_negedge = (~sync_scl_0) & (sync_scl_1);endmodule

2.3 wr_fsm.v

`timescale 1ns/1ps
module wr_fsm (rstn,clk,sync_scl_1,sync_sda_1,scl_posedge,scl_negedge,sda_posedge,sda_negedge,q,d,a,wen,sda_out,sda_oen
);input rstn, clk;input sync_scl_1;input sync_sda_1;input scl_posedge;input scl_negedge;input sda_posedge;input sda_negedge;input [7:0] q;output [7:0] d;output [7:0] a;output wen;output sda_out;output sda_oen;reg wen; // write and read flags regreg [7:0] scl_cnt; // clk delay counterreg [3:0] bit_cnt; // valid transfer bytereg [7:0] a; // a = save word addr, shift data to ramreg sda_out; // data out regreg sda_oen; // three state gate flag bitreg [7:0] save_ctrl; // store ctrl wordreg [7:0] save_q_data; // store data of qwire [7:0] q;parameter slave_addr = 7'b1101101; // parameter slave addrparameter scl_cnt_max = 60-1;reg [3:0] state; // state transformparameter idle       = 4'd0,w_start   = 4'd1,w_ctrl    = 4'd2,ack1      = 4'd3,w_addr    = 4'd4,ack2      = 4'd5,w_data    = 4'd6,ack3      = 4'd7,r_start   = 4'd8,r_ctrl    = 4'd9,ack4      = 4'd10,r_data    = 4'd11,ack5      = 4'd12,stop      = 4'd13;always @(posedge clk or negedge rstn)beginif (!rstn) beginstate <= idle;sda_oen <= 1'b0;sda_out <= 1'b1;scl_cnt <= 8'b0;bit_cnt <= 4'b0;sda_out <= 1'b0;end else begincase (state)idle: begin// Initialize state and signalsstate <= w_start;sda_oen <= 1'b0;sda_out <= 1'b1;scl_cnt <= 8'b0;bit_cnt <= 4'b0;sda_out <= 1'b0;endw_start: begin// Wait for start conditionif (sync_scl_1 && sda_negedge)beginstate <= w_ctrl;bit_cnt <= 4'd8;endelsestate <= w_start;endw_ctrl: begin// Control word transferif (scl_negedge)beginsave_ctrl <= {save_ctrl[6:0], sync_sda_1};bit_cnt <= bit_cnt - 1;if (bit_cnt == 4'd0)beginstate <= ack1;bit_cnt <= 4'd8;endelsestate <= w_ctrl;endelsestate <= w_ctrl;endack1: begin// Acknowledge control wordif (save_ctrl[7:1] == slave_addr)beginscl_cnt <= scl_cnt + 8'b1;if (scl_cnt == scl_cnt_max >> 2)beginsda_out <= 0;sda_oen <= 1;state <= ack1;endelse if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)beginstate <= w_addr;sda_oen <= 0;scl_cnt <= 8'b0;bit_cnt <= 4'd7;endelsestate <= ack1;endelsestate <= stop;endw_addr: begin// Write addressif (scl_negedge)beginbit_cnt <= bit_cnt - 4'b1;wen <= save_ctrl[0]; // write operationa <= {a[6:0], sync_sda_1};if (bit_cnt == 4'd0)beginbit_cnt <= 4'd7;state <= ack2;endelsestate <= w_addr;endelsestate <= w_addr;endack2: begin// Acknowledge addressscl_cnt <= scl_cnt + 8'b1;if (scl_cnt == scl_cnt_max >> 2)beginsda_out <= 1'b0;sda_oen <= 1'b1;state <= ack2;endelse if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)beginsda_oen <= 1'b0;scl_cnt <= 8'b0;if (wen == 0) // decide write or readstate <= w_data;elsestate <= r_start;endelsestate <= ack2;endw_data: begin// Write dataif (scl_negedge)begind <= {d[6:0], sync_sda_1};bit_cnt <= bit_cnt - 4'b1;if (bit_cnt == 4'd0)beginbit_cnt <= 4'd7;state <= ack3;endelsestate <= w_data;endelsestate <= w_data;endack3: begin// Acknowledge datascl_cnt <= scl_cnt + 8'b1;if (scl_cnt == scl_cnt_max >> 2)beginsda_out <= 0;sda_oen <= 1'b1;state <= ack3;endelse if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)beginsda_oen <= 1'b0;scl_cnt <= 8'b0;state <= stop;endelsestate <= ack3;endr_start: begin// Read start conditionif (sync_scl_1 && sda_negedge)beginsda_oen <= 1'b0;bit_cnt <= 4'd8;state <= r_ctrl;endelsestate <= r_start;endr_ctrl: begin// Read control wordif (scl_negedge)beginbit_cnt <= bit_cnt - 4'b1;save_ctrl <= {save_ctrl[6:0], sync_sda_1};if (bit_cnt == 4'd0)beginwen <= save_ctrl[0];bit_cnt <= 4'd7;state <= ack4;endelsestate <= r_ctrl;endelsestate <= r_ctrl;endack4: begin// Acknowledge control wordif (save_ctrl[7:1] == slave_addr)beginscl_cnt <= scl_cnt + 8'b1;if (scl_cnt == scl_cnt_max >> 2)beginsda_out <= 0;sda_oen <= 1;state <= ack4;endelse if (scl_cnt == (scl_cnt_max >> 2) + scl_cnt_max)beginsda_oen <= 1'b0;scl_cnt <= 8'b0;if (wen)beginstate <= r_data;sda_oen <= 1'b1;sda_out <= sync_sda_1;endelsestate <= w_data;endelsestate <= ack4;endelsestate <= stop;endr_data: begin// Read dataif (scl_negedge)beginsave_q_data <= q[7:0];bit_cnt <= bit_cnt - 4'b1;sda_out <= save_q_data[7];if (bit_cnt == 4'd0)beginstate <= ack5;bit_cnt <= 4'd7;sda_oen <= 0;endelsebeginstate <= r_data;sda_oen <= 1;save_q_data <= {save_q_data[6:0], 1'b0};endendelsestate <= r_data;endack5: begin// Acknowledge dataif (scl_posedge)beginif (sync_sda_1 == 1)state <= stop;elsestate <= idle;endelsestate <= ack5;endstop: begin// Stop conditionif (sync_scl_1 && sda_posedge)beginstate <= idle;sda_oen <= 1'b0;sda_out <= 1'b1;endelsestate <= stop;enddefault: state <= idle;endcaseendend
endmodule

2.3.1 状态机状态解释

当然可以!以下是优化后的代码中每个状态的作用解释:

reg [3:0] state; // state transform
parameter idle       = 4'd0,w_start   = 4'd1,w_ctrl    = 4'd2,ack1      = 4'd3,w_addr    = 4'd4,ack2      = 4'd5,w_data    = 4'd6,ack3      = 4'd7,r_start   = 4'd8,r_ctrl    = 4'd9,ack4      = 4'd10,r_data    = 4'd11,ack5      = 4'd12,stop      = 4'd13;

状态作用解释

  1. idle (4’d0):
  • 作用: 初始状态,等待复位信号或起始条件。
  • 描述: 在这个状态下,所有信号被初始化,状态机等待复位信号 rstn 或起始条件(sync_scl_1 和 sda_negedge)。
  1. w_start (4’d1):
  • 作用: 等待起始条件。
  • 描述: 在这个状态下,状态机检测起始条件(sync_scl_1 和 sda_negedge)。如果检测到起始条件,状态机进入 w_ctrl 状态。
  1. w_ctrl (4’d2):
  • 作用: 接收控制字。
  • 描述: 在这个状态下,状态机接收控制字(save_ctrl),并将其存储在寄存器中。控制字的接收通过 scl_negedge 信号完成。当接收到完整的控制字后,状态机进入 ack1 状态。
  1. ack1 (4’d3):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。如果接收到的控制字匹配从设备地址(slave_addr),状态机进入 w_addr 状态。否则,状态机进入 stop 状态。
  1. w_addr (4’d4):
  • 作用: 接收地址。
  • 描述: 在这个状态下,状态机接收地址数据(a),并将其存储在寄存器中。地址的接收通过 scl_negedge 信号完成。当接收到完整的地址后,状态机进入 ack2 状态。
  1. ack2 (4’d5):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。根据控制字中的写入标志(wen),状态机决定进入 w_data 状态(写入数据)或 r_start 状态(读取数据)。
  1. w_data (4’d6):
  • 作用: 写入数据。
  • 描述: 在这个状态下,状态机接收数据(d),并将其存储在寄存器中。数据的接收通过 scl_negedge 信号完成。当接收到完整的数据后,状态机进入 ack3 状态。
  1. ack3 (4’d7):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。然后状态机进入 stop 状态。
  1. r_start (4’d8):
  • 作用: 等待读取起始条件。
  • 描述: 在这个状态下,状态机检测读取起始条件(sync_scl_1 和 sda_negedge)。如果检测到起始条件,状态机进入 r_ctrl 状态。
  1. r_ctrl (4’d9):
  • 作用: 接收控制字。
  • 描述: 在这个状态下,状态机接收控制字(save_ctrl),并将其存储在寄存器中。控制字的接收通过 scl_negedge 信号完成。当接收到完整的控制字后,状态机进入 ack4 状态。
  1. ack4 (4’d10):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。如果接收到的控制字匹配从设备地址(slave_addr),状态机进入 r_data 状态。否则,状态机进入 stop 状态。
  1. r_data (4’d11):
  • 作用: 读取数据。
  • 描述: 在这个状态下,状态机读取数据(q),并将其存储在寄存器中。数据的读取通过 scl_negedge 信号完成。当读取完数据后,状态机进入 ack5 状态。
    13。 ack5 (4’d12):
  • 作用: 发送 ACK 信号。
  • 描述: 在这个状态下,状态机发送 ACK 信号(sda_out 和 sda_oen)。然后状态机进入 idle 状态。
  1. stop (4’d13):
  • 作用: 停止状态。
  • 描述: 在这个状态下,状态机等待停止条件(sync_scl_1 和 sda_posedge)。如果检测到停止条件,状态机进入 idle 状态。

每个状态的作用如下:

  • idle: 初始状态,等待复位或起始条件。
  • w_start: 等待起始条件。
  • w_ctrl: 接收控制字。
  • ack1: 发送 ACK 信号,确认控制字接收。
  • w_addr: 接收地址。
  • ack2: 发送 ACK 信号,确认地址接收。
  • w_data: 写入数据。
  • ack3: 发送 ACK 信号,确认数据写入。
  • r_start: 等待读取起始条件。
  • r_ctrl: 接收控制字。
  • ack4: 发送 ACK 信号,确认控制字接收。
  • r_data: 读取数据。
  • ack5: 发送 ACK 信号,确认数据读取。
  • stop: 停止状态,等待停止条件。

这些状态共同构成了一个完整的 I2C 从设备写入和读取的有限状态机,确保数据的正确传输和接收。

2.4 ram.v

`timescale 1ns/1ps
module ram (clk,rstn,d,a,q,wen
);// Input portsinput clk, rstn;input [7:0] a;  // Address inputinput [7:0] d;  // Data inputinput wen;      // Write enable// Output portsoutput [7:0] q; // Data output// Internal registersreg [7:0] ram [255:0]; // RAM arrayinteger i;             // Loop counterreg [7:0] q;           // Output data register// Always block for RAM operationsalways @(posedge clk or negedge rstn)beginif (!rstn) begin// Initialize RAM on resetfor (i = 0; i <= 255; i = i + 1)ram[i] <= 8'b0;end else beginif (!wen) begin// Write operation: wen = 0ram[a] <= d;end else begin// Read operation: wen = 1q <= ram[a];endendendendmodule

3. 波形展示

在这里插入图片描述

4. 建议

必看
此设计还存在一些问题,后续有时间我会完善的。

在同步的时候我建议还是使用两个寄存器缓冲,而不是使用一个,使用多个更加的稳妥一些,我这个就是使用了较少的寄存器缓冲,所以波形中有问题。(我把这段字打个红色背景)。(是因为在边沿检测的时候无法确认信号是否同步还是异步所以在设计的时候还是使用双寄存器进行消除亚稳态)

5. 资料总结

练习时的一些思路。

https://blog.csdn.net/weixin_46163885/article/details/107170689

相关文章:

verilog练习:i2c slave 模块设计

文章目录 前言1. 结构2.代码2.1 iic_slave.v2.2 sync.v2.3 wr_fsm.v2.3.1 状态机状态解释 2.4 ram.v 3. 波形展示4. 建议5. 资料总结 前言 首先就不啰嗦iic协议了&#xff0c;网上有不少资料都是叙述此协议的。 下面将是我本次设计的一些局部设计汇总&#xff0c;如果对读者有…...

3.5 Go(特殊函数)

目录 一、匿名函数 1、匿名函数的特点&#xff1a; 2、匿名函数代码示例 2、匿名函数的类型 二、递归函数 1. 递推公式版本 2. 循环改递归 三、嵌套函数 1、嵌套函数用途 2、代码示例 3、作用域 & 变量生存周期 四、闭包 1、闭包使用场景 2、代码示例 五、De…...

Android的MQTT客户端实现

在 Android 平台上实现 MQTT 客户端的完整技术方案&#xff0c;涵盖基础实现、安全连接、性能优化和最佳实践&#xff1a; 一、技术选型与依赖配置 推荐库 Eclipse Paho Android Service&#xff08;官方维护&#xff0c;支持后台运行&#xff09; gradle 复制 // build.gradl…...

国产编辑器EverEdit - 编辑辅助功能介绍

1 编辑辅助功能 1.1 各编辑辅助选项说明 1.1.1 行号 打开该选项时&#xff0c;在编辑器主窗口左侧显示行号&#xff0c;如下图所示&#xff1a; 1.1.2 文档地图 打开该选项时&#xff0c;在编辑器主窗口右侧靠近垂直滚动条的地方显示代码的缩略图&#xff0c;如下图所示&…...

WPF 在后台使TextBox失去焦点的方法

在软件设计开发的时候&#xff0c;偶尔会遇到在后台xaml.cs后台中&#xff0c;要将TextBox控件的焦点取消或者使TextBox控件获取焦点&#xff0c;下面介绍讲述一种简单的“只让特定的 TextBox 失去焦点”方法: 前端xaml代码示例&#xff1a; <StackPanel Orientation"…...

工作案例 - python绘制excell表中RSRP列的CDF图

什么是CDF图 CDF&#xff08;Cumulative Distribution Function&#xff09;就是累积分布函数&#xff0c;是概率密度函数的积分。CDF函数是一个在0到1之间的函数&#xff0c;描述了随机变量小于或等于一个特定值的概率。在可视化方面&#xff0c;CDF图表明了一个随机变量X小于…...

CTF SQL注入学习笔记

部分内容来自于SQL注入由简入精_哔哩哔哩_bilibili SQL语句 1.mysqli_error()&#xff1a;返回最近调用函数的最后一个错误描述 语法&#xff1a;mysqli_error(connection) 规定要使用的Mysql连接; 返回一个带有错误描述的字符串。如果没有错误发生则返回 "" 2…...

element-plus el-tree-select 修改 value 字段

element-plus el-tree-select 修改 value 字段 &#xff0c;不显示label 需要注意两个地方&#xff1a; <el-tree-select v-model"value" :data"data" multiple :render-after-expand"false" show-checkbox style"width: 240px" …...

基于javaweb的SpringBoot小区智慧园区管理系统(源码+文档+部署讲解)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 运行环境开发工具适用功能说明 运行环境 Java≥8、MySQL≥5.7、Node.js≥14 开发工具 后端&#xff1a;eclipse/idea/myeclipse…...

SpringBoot学习之shardingsphere实现分库分表(基于Mybatis-Plus)(四十九)

一、shardingsphere介绍 ShardingSphere是一款起源于当当网内部的应用框架。2015年在当当网内部诞生,最初就叫ShardingJDBC。2016年的时候,由其中一个主要的开发人员张亮,带入到京东数科,组件团队继续开发。在国内历经了当当网、电信翼支付、京东数科等多家大型互联网企业的…...

23.PPT:校摄影社团-摄影比赛作品【5】

目录 NO12345​ NO6 NO7/8/9/10​ 单元格背景填充表格背景填充文本框背景填充幻灯片背景格式设置添加考生文件夹下的版式 NO12345 插入幻灯片和放入图片☞快速&#xff1a;插入→相册→新建相册→文件→图片版式→相框形状→调整边框宽度左下角背景图片&#xff1a;视图→…...

Baumer工业相机堡盟相机的相机传感器芯片清洁指南

Baumer工业相机堡盟相机的相机传感器芯片清洁指南 Baumer工业相机1.Baumer工业相机传感器芯片清洁工具和清洁剂2.Baumer工业相机传感器芯片清洁步骤2.1、准备步骤2.2、清洁过程1.定位清洁工具2.清洁传感器3&#xff0e;使用吹风装置 Baumer工业相机传感器芯片清洁的优势设计与结…...

Spring Boot 整合 JPA 实现数据持久化

目录 前言 一、JPA 核心概念与实体映射 1. 什么是 JPA&#xff1f; 2. JPA 的主要组件 3. 实体映射 4. 常见的字段映射策略 二、Repository 接口与自定义查询 1. 什么是 Repository 接口&#xff1f; 2. 动态查询方法 3. 自定义查询 4. 分页与排序 三、实战案例&…...

快速在wsl上部署学习使用c++轻量化服务器-学习笔记

知乎上推荐的Tinywebserver这个服务器&#xff0c;快速部署搭建&#xff0c;学习c服务器开发 仓库地址 githubhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServerhttps://link.zhihu.com/?targethttps%3A//github.com/qinguoyi/TinyWebServer 在…...

【R语言】数据操作

一、查看和编辑数据 1、查看数据 直接打印到控制台 x <- data.frame(a1:20, b21:30) x View()函数 此函数可以将数据以电子表格的形式进行展示。 用reshape2包中的tips进行举例&#xff1a; library("reshape2") View(tips) head()函数 查看前几行数据&…...

MariaDB MaxScale实现mysql8主从同步读写分离

一、MaxScale基本介绍 MaxScale是maridb开发的一个mysql数据中间件&#xff0c;其配置简单&#xff0c;能够实现读写分离&#xff0c;并且可以根据主从状态实现写库的自动切换&#xff0c;对多个从服务器能实现负载均衡。 二、MaxScale实验环境 中间件192.168.121.51MaxScale…...

【python】简单的flask做页面。一组字母组成的所有单词。这里的输入是一组字母,而输出是所有可能得字母组成的单词列表

目录结构如下&#xff1a; https://github.com/kaede316/Pythons_pj.git 效果&#xff1a; 后续可扩展为工具网站&#xff1a; 更新 2025.02.09 1、增加等间距制作人 时间信息 2、增加判断润年的功能...

单片机之基本元器件的工作原理

一、二极管 二极管的工作原理 二极管是一种由P型半导体和N型半导体结合形成的PN结器件&#xff0c;具有单向导电性。 1. PN结形成 P型半导体&#xff1a;掺入三价元素&#xff0c;形成空穴作为多数载流子。N型半导体&#xff1a;掺入五价元素&#xff0c;形成自由电子作为多…...

吴恩达深度学习——卷积神经网络的特殊应用

内容来自https://www.bilibili.com/video/BV1FT4y1E74V&#xff0c;仅为本人学习使用。 文章目录 人脸识别相关定义Similarity函数使用Siamese网络实现函数d使用Triplet损失学习参数 神经风格迁移深度卷积网络可视化神经风格迁移的代价函数内容损失函数风格损失函数 人脸识别 …...

安宝特方案 | AR助力制造业安全巡检智能化革命!

引言&#xff1a; 在制造业中&#xff0c;传统巡检常面临流程繁琐、质量波动、数据难以追溯等问题。安宝特AR工作流程标准化解决方案&#xff0c;通过增强现实AR技术&#xff0c;重塑制造业安全巡检模式&#xff0c;以标准化作业流程为核心&#xff0c;全面提升效率、质量与…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...