IIC 随机写+多次写 可以控制写几次

在这里插入图片描述


```verilog
module icc_tx#(
    parameter SIZE   = 2          , //用来控制写多少次 比如地址是0000 一个地址只能存放8bit数据 超出指针就会到下一个地址0001
    parameter CLK_DIV= 50_000_000 ,
    parameter SPEED  = 100_000    ,
    parameter LED    = 50
)( 
    input     wire                clk     ,//系统层
    input     wire                rst_n   ,
    inout     wire                sda     ,//物理侧
    output    wire                scl     ,
    input     wire                valid   ,//用户侧(写使能)
    input     wire [15:0]         addr    ,
    input     wire [8*SIZE-1:0]   data    ,
    output    wire                led     ,
    output    wire                a        //ASK状态 1的时候就是该状态否则不是该状态
);
reg                 scl_r  ;
reg                 sda_o  ;
reg                 sda_i  ;
reg [5:0]           state  ; 
reg [((SIZE+3)*8-1):0]  data_r ;//SIZE+1 因为还有带上地址加写命令0  不减一是为了产生空白的位不然移位会多移一位
reg [9:0]           cunt_0 ;//开始位的计数器 记到500 start
reg [9:0]           cunt_1 ;//BUSY与ASK的计数器  用来产生时钟 也方便cunt_2也就是cunt_bit计数
reg [9:0]           cunt_2 ;//每一bit数据维持的时间 只在BUSY状态下计数
reg [3:0]           cunt_3 ;// 每一次应答加一 计数发了多少数据
reg [30:0]          cunt_4 ;//计数小灯点亮时间 1s
reg [9:0]           cunt_5 ;
parameter  CUNT_MAX=CLK_DIV/SPEED ;
parameter  ADDR    =7'b101_0000   ;//地址
parameter  IDEL    =6'b000_001    ;
parameter  START   =6'b000_010    ;
parameter  BUSY    =6'b000_100    ;
parameter  ASK     =6'b001_000    ;
parameter  ERROR   =6'b010_000    ;
parameter  STOP    =6'b100_000    ;

assign scl=scl_r                  ;
assign a  =(state==ASK)?1'b1:1'b0 ;  
assign sda=(state==ASK)?1'bz:sda_o;
//assign sda = sda_o;
//错误状态下led一直亮
assign led=(state==ERROR)?1:0      ;


//
always @(posedge clk ) begin
    if(state==ASK&&cunt_1==(CUNT_MAX/4*3))
    sda_i<=sda;
    else
    sda_i<=sda_i;
    
end
//数据的缓存 加移位
always @(posedge clk ) begin 
    if(state==IDEL&&valid==1)
    data_r<={ADDR,1'b0,addr,data}; //单次写
    else  if(cunt_1==4&&state==BUSY)  ///
    data_r<=(data_r<<1);  //先赋值再移位了
    else
    data_r<=data_r; 
end
//开始位的 start计数器 记到500
always @(posedge clk ) begin
    if(state==START)
    cunt_0<=cunt_0+1;
    else
    cunt_0<=0;
end
//cunt_1
always @(posedge clk ) begin
    if(state==BUSY||state==ASK)begin
        if(cunt_1==CUNT_MAX-1)
        cunt_1<=0;
        else
        cunt_1<=cunt_1+1;
    end
    else
    cunt_1<=0;
end
//cunt_2
always @(posedge clk ) begin
    if(state==BUSY)begin
        if(cunt_1==CUNT_MAX-1)
        cunt_2<=cunt_2+1;
        else 
        cunt_2<=cunt_2;
    end
    else
    cunt_2<=0;
end
//cunt_3 计数发送了几个bit数据
always @(posedge clk ) begin
    if(state==ASK)begin
    if(cunt_1==66)
    cunt_3<=cunt_3+1;
    else
    cunt_3<=cunt_3;
    end
    else if(state==BUSY)
    cunt_3<=cunt_3;
    else
    cunt_3<=0;
end
//cunt_4 
always @(posedge clk ) begin
    if(state==ERROR)
    cunt_4<=cunt_4+1;
    else
    cunt_4<=0;
end
//结束位计数 cunt_5
always @(posedge clk ) begin
    if(state==STOP)
    cunt_5<=cunt_5+1;
    else
    cunt_5<=0;
end
//状态的转移
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        state<=IDEL;
    else  begin
        case (state)
            IDEL :begin
                if(valid==1)
                state<=START;
                else
                state<=state;
            end
            START:begin
                if(cunt_0==CUNT_MAX-1)
                state<=BUSY;
                else
                state<=state;
            end
            BUSY : begin
                if(cunt_2==10'd7&&cunt_1==CUNT_MAX-1)
                state<=ASK;
                else
                state<=state;
            end
            ASK  :begin
                if(cunt_1==CUNT_MAX-1)begin
                    if(sda_i==0)begin
                        if(cunt_3==(SIZE+3))
                        state<=STOP;
                        else
                        state<=BUSY;
                    end
                    else
                    state<=ERROR;
                end
                else
                state<=state;
            end
            ERROR :begin
                if(cunt_4==LED)
                state<=IDEL;
                else
                state<=state;
            end
            STOP  :begin
                if(cunt_5==CUNT_MAX-1)
                state<=IDEL;
                else
                state<=state;
            end
            default: state<=state;
        endcase
    end
end
//时钟线scl的描述
always @(posedge clk ) begin
        if(state == IDEL || state == START)
            scl_r <= 1'b1;
        else if(state == BUSY || state == ASK)begin
            if(cunt_1 >=0 && cunt_1 <= (CUNT_MAX / 2)) 
                scl_r <= 1'b0;
            else 
                scl_r <= 1'b1;
        end
        else if(state == STOP)begin
                scl_r <= 1'b1;
        end
        else 
            scl_r <= 1'b1;
end
//数据线sda的描述
always @(posedge clk ) begin
    case (state)
        IDEL : sda_o<=1'b1;
        START: begin
            if(cunt_0<CUNT_MAX/2)    //也可以起始位状态直接置低置低时间就是cunt_0==250 
            sda_o<=1;
            else
            sda_o<=0;
        end
        BUSY :begin
            if(cunt_1==1)   ///一定要等于0//*************
            sda_o<=data_r[((SIZE+3)*8-1)];
            else
            sda_o<=sda_o;
        end
        ASK  :begin
            if(cunt_1==CUNT_MAX-1)
            sda_o<=1'b0;           //给0才可以 因为busy中的保持导致给1会在结束位sda也是一个脉冲1
            else
            sda_o<=1'bz;
        end
        ERROR:sda_o<=1'b1;
        STOP :begin
            if(cunt_5<CUNT_MAX/2)
            sda_o<=1'b0;
            else
            sda_o<=1'b1;
        end
        default: sda_o<=1'b1;
    endcase
end
endmodule

仿真

`timescale 1ns / 1ps

module tb_icc_tx(
    );
reg          clk  ;///
reg          rst_n;///
wire         sda  ;
wire         scl  ;
reg          valid;///
reg  [15:0]  data ;///
wire         led  ;
wire         a    ;
reg  [15:0]  addr ;        
initial begin
    clk   =1;
    rst_n<=0;
    valid<=0;
    data <=0;

    #100
    rst_n<=1;
    #100
    valid<=1;
    data <=16'b1111_0000_0000_1111;   
    addr <=16'b1111_0000_0000_0000;
    #20
    valid<=0;
    data <=0; 
end


assign sda= (a==1)?1'b0:1'bz;//从机发的
always #10  clk=~clk;
icc_tx#(
    /*parameter */. SIZE   (2          ),
    /*parameter */. CLK_DIV(50_000_000 ),
    /*parameter */. SPEED  (100_000    ),
    /*parameter */. LED    (50         )
)u_icc_tx( 
    /*input     wire              */ .clk  (clk  ),//系统层
    /*input     wire              */ .rst_n(rst_n),
    /*inout     wire              */ .sda  (sda  ),//物理侧
    /*output    wire              */ .scl  (scl  ),
    /*input     wire              */ .valid(valid),//用户侧
    /*input     wire [8*SIZE-1:0] */ .data (data ),
    /*output    wire              */ .led  (led  ),
    /*input     wire [15:0] */       .addr (addr )   ,

    /*output    wire              */ .a    (a    ) //ASK状态 1的时候就是该状态否则不是该状态
);
endmodule


在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序+Vant-自定义选择器组件(多选

实现效果 无筛选&#xff0c;如有需要可参照单选组件中的方法.json文件配置"component": true,columns需要处理成含dictLabel和dictValue字段&#xff0c;我是这样处理的&#xff1a; let list arr.map(r > {return {...r,dictValue: r.xxxId,dictLabel: r.xxx…

基于边缘智能网关的机房安全监测应用

随着我国工业互联网的扎实推进&#xff0c;越来越多地区积极建设信息基础设施&#xff0c;以充沛算力支撑产业物联网的可持续发展&#xff0c;数据机房就是其中的典型代表。而且随着机房规模的扩大&#xff0c;对于机房的安全管理难题挑战也日益增加。 面向数据机房安全监测与管…

HarmonyOS 应用跨团队 Debug 协作

文章目录 前言案例背景与问题分析问题背景问题分析工具 方法与代码实现前端模块的优化&#xff1a;日志记录与网络监听日志记录代码示例代码解析实现逻辑实际应用场景 网络状态监听代码示例代码解析实现逻辑实际应用场景 后端模块的优化&#xff1a;接口性能与容错机制接口性能…

《UnityShader 入门精要》更复杂的光照

代码&示例图见&#xff1a;zaizai77/Shader-Learn: 实现一些书里讲到的shader 到了这里就开启了书里的中级篇&#xff0c;之后会讲解 Unity 中的渲染路径&#xff0c;如何计算光照衰减和阴影&#xff0c;如何使用高级纹理和动画等一系列进阶内容 Unity 中的渲染路径 在U…

Ubuntu20.04安装kalibr

文章目录 环境配置安装wxPython下载编译测试报错1问题描述问题分析问题解决 参考 环境配置 Ubuntu20.04&#xff0c;python3.8.10&#xff0c;boost自带的1.71 sudo apt update sudo apt-get install python3-setuptools python3-rosinstall ipython3 libeigen3-dev libboost…

P1198 [JSOI2008] 最大数

P1198 [JSOI2008] 最大数https://www.luogu.com.cn/problem/P1198 牵制芝士&#xff1a;单调队列 思路&#xff1a; 我们的任务是找出一个区间最大值的 因为插入的数与上一次的答案有关 所以它是强制在线的&#xff08;真无语了&#xff09; 我们可以在每次插入时整一个叫…

宠物电商对接美团闪购:实现快速配送与用户增值

随着宠物行业的快速发展&#xff0c;宠物电商市场也在不断扩张。消费者的需求不再局限于传统的线上购物模式&#xff0c;越来越多的人开始追求更快捷的配送服务和更优质的购物体验。为了适应这一趋势&#xff0c;许多宠物电商平台开始寻求与本地配送平台合作&#xff0c;以提供…

阿里云oss转发上线-实现不出网钓鱼

本地实现阿里云oss转发上线&#xff0c;全部代码在文末&#xff0c;代码存在冗余 实战环境 被钓鱼机器不出网只可访问内部网络包含集团oss 实战思路 若将我们的shellcode文件上传到集团oss上仍无法上线&#xff0c;那么就利用oss做中转使用本地转发进行上线&#xff0c;先发送…

新型大语言模型的预训练与后训练范式,阿里Qwen

前言&#xff1a;大型语言模型&#xff08;LLMs&#xff09;的发展历程可以说是非常长&#xff0c;从早期的GPT模型一路走到了今天这些复杂的、公开权重的大型语言模型。最初&#xff0c;LLM的训练过程只关注预训练&#xff0c;但后来逐步扩展到了包括预训练和后训练在内的完整…

C#结构体排序(数组)

结构体排序&#xff08;数组&#xff09; 1 示例1.1 以PointF为例展示效果1.2 运行结果展示 2实际运用2.1 创建结构体2.2 调用示例2.3 运行结果展示 1 示例 1.1 以PointF为例展示效果 private void button1_Click(object sender, EventArgs e) {Random random new Random();…

前端高频面试题-并发请求

面试题中&#xff0c;有一道题经常会出现&#xff0c;咱们下面讲一下思路以及写法写一个方法&#xff0c;传入一个请求地址数组&#xff0c;以及一个并发数量&#xff0c;根据并发数量&#xff0c;一起发送请求。如果一个发送完&#xff0c;那么从数组中拿出来一个接着发送&…

RabbitMQ7:消息转换器

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

螺旋矩阵(java)

题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 代码思路&#xff1a; class Solution {public List<Integer> spiralOrder(int[][] matrix) {List<Integer> list new ArrayList<>(); …

Jenkins的使用

文章目录 一、Jenkins是什么\有什么用\与GitLab的对比二、Jenkins的安装与配置Jenkins的安装方式在Linux上安装Jenkins&#xff1a;在Windows上安装Jenkins&#xff1a;配置Jenkins&#xff1a; &#xff08;可选&#xff09;配置启动用户为root&#xff08;一定要是root吗??…

[在线实验]-ActiveMQ Docker镜像的下载与部署

镜像下载 下载ActiveMQ的Docker镜像文件。通常&#xff0c;这些文件会以.tar格式提供&#xff0c;例如activemq.tar。 docker的activemq镜像资源-CSDN文库 加载镜像 下载完成后&#xff0c;您可以使用以下命令将镜像文件加载到Docker中&#xff1a; docker load --input a…

【AI绘画】Midjourney进阶:色调详解(下)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AI绘画 | Midjourney 文章目录 &#x1f4af;前言&#x1f4af;Midjourney中的色彩控制为什么要控制色彩&#xff1f;为什么要在Midjourney中控制色彩&#xff1f; &#x1f4af;色调纯色调灰色调暗色调 &#x1f4af…

YOLO系列论文综述(从YOLOv1到YOLOv11)【第3篇:YOLOv1——YOLO的开山之作】

YOLOv1 1 摘要2 YOLO: You Only Look Once2.1 如何工作2.2 网络架构2.3 训练2.4 优缺点 YOLO系列博文&#xff1a; 【第1篇&#xff1a;概述物体检测算法发展史、YOLO应用领域、评价指标和NMS】【第2篇&#xff1a;YOLO系列论文、代码和主要优缺点汇总】 ——————————…

数字图像处理(9):VGA接口及其时序

&#xff08;1&#xff09;特点&#xff1a;成本低、结构简单、应用灵活 VGA接口需要五个信号&#xff1a;R、G、B、Hsync、Vsync &#xff08;2&#xff09;VGA的工作原理&#xff1a; 设定一个高速时钟信号&#xff08;像素时钟&#xff09;来控制每个像素的传输速率&#…

微信小程序按字母顺序渲染城市 功能实现详细讲解

在微信小程序功能搭建中&#xff0c;按字母渲染城市会用到多个ES6的方法&#xff0c;如reduce&#xff0c;map&#xff0c;Object.entries()&#xff0c;Object.keys() &#xff0c;需要组合熟练掌握&#xff0c;才能优雅的处理数据完成渲染。 目录 一、数据分析 二、数据处理 …

DVWA靶场通过——文件上传漏洞

File Upload漏洞 它允许攻击者通过上传恶意文件来执行任意代码、窃取数据、获取服务器权限&#xff0c;甚至完全控制服务器。为了防止文件上传漏洞&#xff0c;开发者需要对文件上传过程进行严格的验证和处理。 1. 文件上传漏洞概述 文件上传漏洞发生在Web应用程序允许用户通过…