热门标签 | HotTags
当前位置:  开发笔记 > 人工智能 > 正文

串并串转换(1)整体介绍+并到串

大纲整体过程程序说明整体过程目的:接收其他CPU(here用.vt文件给)传过来的并行数据,并转为串行数据输出(之后有接收串行数据并转化为并行数据的例子);流程:.vt给一个启动脉

大纲

    • 整体过程
    • 程序说明

整体过程

  • 目的:接收其他CPU(here用.vt 文件给)传过来的并行数据,并转为串行数据输出(之后有接收串行数据并转化为并行数据的例子);
  • 流程:.vt 给一个启动脉冲,在.v文件中接收此异步信号并处理为同步信号(点here跳转);对sys_clk分频,产生4个分频脉冲(点here跳转),进而模拟产生SCL控制时钟信号,并控制并行数据一位位输出为串行SDA数据。

程序说明

  • 并行数据接收
    像单片机、DSP那样,通过好多个输出引脚来输出一个数据的高位到低位,接收端接收到的就是并行数据,即一个data的各位都一起接收到了。
    here不管并行数据什么时候来,都每个时钟来把它锁存一下,赋给reg r_cpu_data保存一下。

    //.v
    always @(posedge i_sys_clk or negedge i_rst_n) begin
    if(!i_rst_n) begin
    r_cpu_data <= 32'd0; end
    else begin
    r_cpu_data <= i_cpu_data; end
    end

    仿真信号直接在某个时间给 i_cpu_data赋值就行:#10 i_cpu_data = 32'h55aa55aa;

    想法:程序中我是直接判断启动脉冲来了就去状态跳转、转换数据,所以仿真限号得设置i_cpu_data 的在启动脉冲前赋值。 觉得状态的切换可以再设置一点东西,判断一下这是的r_cpu_data 是不是被赋值了(可能数据i_cpu_data 还没来,r_cpu_data 还全是零)。 得看实际情况怎么用,收发应该沟通好了就没问题。

  • 判断启动脉冲 (点here跳回去)
  1. 启动脉冲来到时间提前不知道,相较系统时钟而言是异步信号,一般需要处理成同步信号来使用这个启动脉冲。这里一开始疑惑一个脉冲只是用一位数据的高低电平表示,又不是一串数据,那它怎么会通过取反、与操作来对齐波形呢?其实不需要是一串数据也可以就行取反、与操作等,assign是阻塞赋值,所以等式右边码值一变,等式左边码值就变,所以不是理解为一串数据与一串数据的操作,而是一位与一位的操作。
  2. 当以上升沿的脉冲做启动脉冲时,沿同步的结果应为:(下降沿的脉冲做启动脉冲不同,另一个取反,具体见串并转换时)
    assign startpulse_align = i_startpulse &&(~startpulse_dl);
    延迟锁存如下:

    always @(posedge i_sys_clk or negedge i_rst_n) begin
    if(!i_rst_n) begin
    startpulse_dl <= 1'd0; end
    else begin
    startpulse_dl <= i_startpulse; end
    end

    波形示意如下:
    《串并串转换(1)---- 整体介绍+并到串》(其中需要startpulse的持续时间不能太短,否则sys_clk还没检测到;)

  3. 在状态切换程序块中判断startpulse_align是不是为高来判断是否切换到下一状态,这里注意,状态切换程序块也是在sys_clk上升沿进行的判断,而由于非阻塞赋值,这里的startpulse_dl还为低(所有always块完了再一起更新值),所以startpulse_align还为高,所以判断若startpulse_align为高则跳转状态可以正常进行。
  • 时钟分频,设置4个phase脉冲 (点here跳回去)
  1. 通过sys_clk设置了4个分频脉冲,四个脉冲走完相当于SCL一个周期走完(对应SCL的上升沿、高电平中间、下降沿、低电平中间),所以可以认为它们分别对应相位0/1/2/3。在各个脉冲到来时干特定的任务(觉得有点像时间片轮转法),而不是直接去判断SCL、SDA的沿(觉得这里考虑到传输协议,直接判断沿可能不好做,第一次接触到这种用法,不知道适用性怎么样);
  2. always @(posedge i_sys_clk or negedge i_rst_n) begin
    if(!i_rst_n) begin
    //都初始化为0
    end
    else begin
    if(phase_cnt == 10'd39) begin//这里判断是不是40个sys_clk过去了
    phase_cnt <= 10'b0; end
    else begin
    phase_cnt <= phase_cnt + 10'b1;
    end

    if(phase_cnt == 10'd39) begin//这里判断phase0是不是可以到了,并在一个sys_clk后置会0;
    phase0 <= 1'd1; end
    else begin
    phase0 <= 1'd0;
    end
    //另几个phase同理
    end
    end

  3. 这里判断条件的值还是注意非阻塞赋值;
    ps:程序设置的4个phase共走40个sys_clk,这只是随便取的,差不多保证对应上面提到的SCL、SDA的四个特殊位置就行,怎么方便清楚怎么来。
  4. pahse0的判断条件不是用的phase_cnt =0,而是phase_cnt =尾,其他三个phase的判断仍按顺序就行。
  • 根据四个分频脉冲,产生SCL信号时钟
    在phase0~1之间(指phase0来后到phase2来前)设置SCL信号为高电平;phase2-3(指phase2来后到phase0来前)之间为低电平;

    if(phase0 == 1'b1) begin
    o_scl_clk <= 1'b1; end
    else if(phase2 == 1'b1) begin
    o_scl_clk <= 1'b0; end
    else o_scl_clk <= o_scl_clk;

    ps:同样由于非阻塞赋值,所以后面仿真可以看到波形上SCL是变沿是phase脉冲的尾部;

  • 串行传输协议
  1. 这里用的是I2C:模拟产生SCL控制时钟线、SDA数据线;
    SCL为高时,SDA由高到低:数据传输开始;(1)
    SCL为低时,SDA由高到低 或 由低到高:传输码值;
    两个SCL低电平之间SDA码值不变;(2)
    SCL为高时,SDA由低到高:数据传输结束;
    即SCL为低时,SDA变的是数据码值;SCL为高时,SDA变是开始或结束传输。如下:
    《串并串转换(1)---- 整体介绍+并到串》对于接收方来说,则以(1)做为启动脉冲,在(2)时读取稳定数据,这就只需要在SCL的上升沿读数据就行,也就不需要phase信号
  2. 结合4个分频脉冲,有:
    phase1为高 且 SCL为高时:若SDA由高到低,则开始传输数据,跳到TRANS状态;若 SDA由低到高,则结束传输,跳到IDLE;
    ps:这里得加一个“且SCL为高”,因为实际程序是先产生的phase1,之后才出现的phase0,所以防止SCL还没变高就开始传输数据了;
    phase3为高 (即SCL为低)时:接收数据并存储;
  • 状态机切换&#8212;-结合传输协议
  1. IDLE:变量初始化;判断startpulse_align来没,来了去START;

  2. START:判断 SCL为高 且 phase1为高 不,是的去TRANS;

  3. TRANS:判断phase3为高不,为再判断数据个数够没有(一般收发双方会说好),够了去DELAY,不够继续接收;

    r_data_cnt <= r_data_cnt + 10'b1;//非阻塞赋值,so这两行位置欧克
    o_sda_data_com <= r_cpu_data[31 - r_data_cnt];

    这里并行数据 r_cpu_data 一开始就保存下来了,这里把它一位位的输出成串行数据;

  4. DELAY:延迟几个时钟单元(确保上个输出数据输出完整之类的),再把SDA线拉低(因为之后结束传输SDA需要由低到高);再去STOP;

    o_sda_data_com <= 1'b0;

  5. STOP:判断phase1为高不,为则把SDA拉高,并去IDLE;否则等phase1来;

  • 仿真结果
    《串并串转换(1)---- 整体介绍+并到串》

推荐阅读
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • qt学习(六)数据库注册用户的实现方法
    本文介绍了在qt学习中实现数据库注册用户的方法,包括登录按钮按下后出现注册页面、账号可用性判断、密码格式判断、邮箱格式判断等步骤。具体实现过程包括UI设计、数据库的创建和各个模块调用数据内容。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • 无损压缩算法专题——LZSS算法实现
    本文介绍了基于无损压缩算法专题的LZSS算法实现。通过Python和C两种语言的代码实现了对任意文件的压缩和解压功能。详细介绍了LZSS算法的原理和实现过程,以及代码中的注释。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
author-avatar
孤独中残存的幸福_627
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有