方法2—并行数据流转换为一种特殊串行数据流模块的设计

news2024/11/16 5:26:31

并行数据流转换为一种特殊串行数据流模块的设计,设计两个可综合的电路模块

    • 1,第一个可综合模块,M1。
    • 2,描述M2模块
    • 3,描述M0模块的Verilog代码
    • 4,描述顶层模块
    • 5,电路生成的门级网表,netlist
    • 6,前仿真波形验证

参考文献1
参考文献2

并行数据流转换为一种特殊串行数据流模块的设计:
设计两个可综合的电路模块,第一个模块(M1)能把4位的并行数据转换为符合以下协议的串行数据流,数据流用scl和sda两条线传输,sclk为输入的时钟信号,data[3:0]为输入数据,ack为M1请求M0发新数据信号。第二个模块(M2)能把串行数据流内的信息接收到,并转换为相应16条信号线的高电平,即若数据为1,则第一条线路为高电平,数据为n,则第N条线路为高电平。M0为测试用信号模块。该模块接收M1发出的ack信号,并产生新的测试数据[3:0].

在这里插入图片描述

1,第一个可综合模块,M1。

第一个模块M1能把4位的并行数据转换为符合以下协议的串行数据流,数据流用scl和sda两条线传输,sclk 为输入的时钟信号,data[3:0]为输入数据,ack为M1请求M0发新数据信号。

通信协议: scl为不断输出的时钟信号,如果scl为高电平时,sda由高变低时刻,串行数据流开始;如果scl为高电平时,sda由低变高时刻,串行数据结束。sda信号的串行数据位必须在scl为低电平时变化,若变为高则为1,否则为0.

模块功能,按照设计要求,把输入的 4位 并行数据转换为 协议要求的串行数据流,并由scl 和sda配合输出
本模块为RTL 可综合模块,已通过综合后 门级网表 仿真

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/11/21 11:25:20
// Design Name: 
// Module Name: ptosda
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


// 并行数据流转换为一种特殊串行数据流模块的设计
// 模块功能,按照设计要求,把输入的 4位 并行数据转换为 协议要求的串行数据流,
// 并由scl 和sda配合输出
// 本模块为RTL 可综合模块,已通过综合后 门级网表 仿真

module ptosda(rst, sclk, ack, scl, sda, data);
input  sclk, rst;
       // sclk,输入的时钟信号

input  [3:0] data;     // 并行口数据输入
output ack;            // 请求新的转换数据
output scl;            // 通信协议,scl为不断输出的时钟信号
                              // scl是1, sda由1变0,串行数据流开始;
                              // scl是0, sda由0变1,串行数据流结束;

output sda;            // 定义sda为单向的串行输出
// inout sda;

reg    scl, link_sda, ack, sdabuf;      // 不断输出时钟信号
                  // 连接 sda        // 设计 一个寄存器
               // ask_for_new_data
                    // sda 缓存器      // 设计 一个寄存器  

reg  [3:0] databuf;         // 数据 缓存器 ,用来接收 data 数据
reg  [7:0] state;           // 状态


out16hi m2(.scl(scl), .sda(sda), .outhigh());
assign sda = link_sda?sdabuf:1'b0;   // link_sda 控制 sdabuf 输出到串行总线上
// assign sda = link_sda?sdabuf:1'bz;  // link_sda 控制 sdabuf 输出到双向串行总线上

parameter  ready = 8'b0000_0000,     // 设计  9个  状态参数
            start = 8'b0000_0001,
            bit1  = 8'b0000_0010,
            bit2  = 8'b0000_0100,
            bit3  = 8'b0000_1000,
            bit4  = 8'b0001_0000,
            bit5  = 8'b0010_0000,
            stop  = 8'b0100_0000,
            idle  = 8'b1000_0000;
  
always@(posedge sclk or negedge rst)   // 由输入的  sclk时钟信号  产生串行输出时钟scl
  if(!rst)
          scl <= 1;
  else 
          scl <= ~scl;

always@(posedge ack)   // 请求新数据时 存入 并行总线上 要转换的数据
          databuf <= data;

// 主状态机,产生控制信号,根据databuf 中保存的数据,按照协议产生sda串行信号

// always@(posedge sclk or negedge rst)
always@(negedge sclk or negedge rst)
  if(!rst)  begin
           link_sda <= 0;       // 把 sdabuf 与 sda 串行总线断开
           state    <= ready;
           sdabuf   <= 1;  
           ack      <= 0;       // 请求新数据置0
     end
  else begin
  	  case(state)
  	    ready: if(ack)    // 并行数据已经到达
  	           begin
  	                 link_sda <= 1;    // 把 sdabuf 与 sda 串行总线连接
  	                 state    <= start;    // 
  	            end
  	           else       // 并行数据尚未到达
  	            begin
  	                  link_sda <= 0;    // 把 sda 总线让出,若前面把 sda 定义成双向串行总线,
  	                                    // 则此时 sda 可作为输入

  	                  state    <= ready;
  	                  ack      <= 1;	  // 请求新数据信号置 1 
  	            end
  	    start: if(scl && ack)     // 产生 sda 的开始信号
  	            begin
  	           	      sdabuf   <= 0;    // 在 sda 连接的前提下,输出开始信号
  	           	      state    <= bit1;
  	            end
  	           else 
  	                  state   <= start;
  	    bit1:   if(!scl)          // 在 scl 为低电平时送出最高位 databuf[3]
  	             begin
  	              	   sdabuf <= databuf[3];
  	              	   state  <= bit2;
  	              	   ack    <= 0;
    	         end
    	        else 
    	                state <= bit1;
    	bit2:   if(!scl)          // 在 scl 为低电平时送出次高位 databuf[2]
    	          begin
    	          	   sdabuf <= databuf[2];
    	          	   state  <= bit3;
    	          end
    	        else 
    	               state  <= bit2;
        bit3:   if(!scl)          // 在 scl 为低电平时送出次低位 databuf[1]
                  begin
                  	   sdabuf <= databuf[1];
                  	   state  <= bit4;
                  end
                else 
                       state   <= bit3;
        bit4:   if(!scl)          // 在 scl 为低电平时送出最低位 databuf[0]
                  begin
                  	   sdabuf <= databuf[0];
                  	   state  <= bit5;
                  end
                else 
                       state  <= bit4;
        bit5:   if(!scl)          // 为产生结束信号做准备,先把 sda 变为低
                  begin
                  	   sdabuf <= 0;
                  	   state  <= stop;
                  end
                else 
                       state  <= bit5;
        stop:   if(scl)          // 在scl为高时,把 sda 由低变高 产生结束信号
                  begin
                  	   sdabuf <= 1;
                  	   state  <= idle;
                  end
                else 
                       state  <= stop;
        idle:     begin
        	            link_sda <= 0;        // 把 sdabuf 与 sda 串行总线脱开
        	            state    <= ready;
           	  //          sdabuf   <= 1;
                  end 
        default:  begin
                        link_sda <= 0;
                        sdabuf   <= 1;
                        state    <= ready;	
                  end
        endcase
     end

endmodule

2,描述M2模块

模块功能: 按照协议接收串行数据,进行处理并按照数据值在相应位输出高电平;
本模块为RTL可综合模块,已通过综合后门级网表仿真。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/11/21 11:29:07
// Design Name: 
// Module Name: out16hi
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

// 描述 M2 模块的Verilog 代码
// 模块功能,按照协议接收 串行数据,进行处理 并按照数据值 在相应位 输出高电平
// 本模块为 RTL可综合模块,已通过综合后 门级网表仿真

module out16hi(scl, sda, outhigh);

input         scl, sda;   // 串行数据输入
output [15:0] outhigh;   // 根据输入的串行数据设置高电平位
reg    [5:0]  mstate;    // synthesis preserve*/;
        // 本模块的主状态
        //  /* synthesis preserve*/ 为综合指令, 使综合器布局布线后仍能保留状态信号,
        // 以便于观察,不同的综合器综合指令并不相同,必须参考综合器的技术资料才能掌握
// 

reg [3:0] pdata,  pdatabuf;
                           // 记录串行数据位时, 用寄存器和最终数据寄存器

reg [15:0] outhigh;     // 输出 位寄存器;

reg  startflag, endflag; // 数据开始和结束标志

//   always@(posedge sda)
always@(negedge sda)
   if(scl)
           startflag <= 1;     // 串行数据开始标志
   else if(endflag)
           startflag <= 0;

always@(posedge sda)
   if(scl)  begin
                   endflag   <= 1;        //  串行数据 结束标志
                   pdatabuf  <= pdata;    // 把收到的 4位数据 存入寄存器
            end
   else 
                   endflag   <= 0;        // 数据接收还没有结束

parameter  ready = 6'b00_0000,
            sbit0 = 6'b00_0001,
            sbit1 = 6'b00_0010,
            sbit2 = 6'b00_0100,
            sbit3 = 6'b00_1000,
            sbit4 = 6'b01_0000;

//always@( padabuf)         // 把收到的数据变为相应位的高电平
always@(pdatabuf)        // 把收到的数据变为相应位的高电平
    begin
    	case(pdatabuf)
    	    4'b0001: outhigh = 16'b0000_0000_0000_0001;
    	    4'b0010: outhigh = 16'b0000_0000_0000_0010;
    	    4'b0011: outhigh = 16'b0000_0000_0000_0100;
    	    4'b0100: outhigh = 16'b0000_0000_0000_1000;

    	    4'b0101: outhigh = 16'b0000_0000_0001_0000;
    	    4'b0110: outhigh = 16'b0000_0000_0010_0000;
    	    4'b0111: outhigh = 16'b0000_0000_0100_0000;
    	    4'b1000: outhigh = 16'b0000_0000_1000_0000;

    	    4'b1001: outhigh = 16'b0000_0001_0000_0000;
    	    4'b1010: outhigh = 16'b0000_0010_0000_0000;
    	    4'b1011: outhigh = 16'b0000_0100_0000_0000;
    	    4'b1100: outhigh = 16'b0000_1000_0000_0000;

    	    4'b1101: outhigh = 16'b0001_0000_0000_0000;
    	    4'b1110: outhigh = 16'b0010_0000_0000_0000;
    	    4'b1111: outhigh = 16'b0100_0000_0000_0000;
    	    4'b0000: outhigh = 16'b1000_0000_0000_0000;
        endcase
    end

always@(posedge scl)    // 在检测到开始标志后, 每次 scl 正跳变 沿 时接收数据,共 4位
   if(startflag)
      case(mstate)
         sbit0:  begin
         	      mstate   <= sbit1;
         	      pdata[3] <= sda;
         	      $display("I am in sdabit0");
            end
         sbit1: begin
         	      mstate   <= sbit2;
                  pdata[2] <= sda;
                  $display("I am in sdabit1");
            end
         sbit2: begin
         	      mstate   <= sbit3;
         	      pdata[1] <= sda;
         	      $display("I am in sdabit2");
            end
        sbit3: begin
                  mstate   <= sbit4;
                  pdata[0] <= sda;
                  $display("I am in sdabit3");    	
            end
        sbit4: begin
        	      mstate   <= sbit0;
        	      $display("I am in sdastop");
            end
        default:  mstate <= sbit0;
       endcase
    else 
                   mstate <= sbit0;

endmodule

3,描述M0模块的Verilog代码

模块功能: 本模块产生测试信号对设计中的模块进行测试。
本模块只用于测试,不能通过综合转换为电路。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/11/21 14:03:48
// Design Name: 
// Module Name: sigdata
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

// 描述 M0 模块的 Verilog代码如下:
// 模块功能:本模块产生测试信号对设计中的模块进行测试
// 本模块只用于测试,不能通过综合转换为电路
`timescale 1ns/1ns
`define halfperiod 50
module sigdata(rst, sclk, data, ask_for_data
	);
output    rst;             // 复位信号
output    [3:0] data;      // 输出的数据信号
output    sclk;            // 输出的时钟信号
input     ask_for_data;    // 从并串转换器来的请求数据信号

reg       rst, sclk;
reg       [3:0] data;

initial  begin
                 	   rst = 1;
                 #10   rst = 0;
#(`halfperiod * 2 + 3) rst = 1;

end

initial  begin
	sclk = 0;
	data = 0;
#(`halfperiod * 1000) $stop;

end

always #(`halfperiod)  sclk = ~sclk;    // 产生第一个模块需要的输入时钟
// 每次请求新数据信号的整跳变沿,等一段时间后将输出数据增加1

always@(posedge ask_for_data)
  #(`halfperiod/2 + 3) data = data + 1;
endmodule

4,描述顶层模块

模块功能: 对所设计的两个可综合模块ptosdaout16hi进行联合测试。观察ptosda模块能否正确地把并行数据转换成符合协议要求的串行码流;串行码流能否通过out16hi模块的处理输出符合设计要求的信号。本模块是为教学需要专门设计的。为了使大家容易理解接口功能,作了许多简化,因此无实用价值。

模块说明: 本模块还可以用于综合或布局布线后的电路网表模块的测试。做后仿真时,把包括的文件改为布局布线后的门级电路文件,即由综合工具生成的ptosda.vmout16hi.vm文件,或布局布线工具产生的ptosda.voout16hi.vo文件。为了能使门级电路网表模块进行仿真,有时还需要包括一个布线所用的FPGA或ASIC基本元件仿真库模块

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/11/21 14:05:43
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


// 描述顶层模块的 Verilog代码如下:
// top.v

// 模块功能:对所设计的两个可综合模块 ptosda 和 out16hi 进行联合测试
// 观察 ptosda 模块能否正确地把 并行数据转换成 符合协议要求的串行码流;
// 串行码流能否通过 out16hi 模块的处理输出符合设计要求的信号。
// 本模块是为教学需要专门设计的。
// 为了使大家容易理解接口功能,作了许多简化,因此无 实用价值

// 模块说明:本模块还可以用于综合或布局布线后的电路网表模块的测试。
// 做后仿真时, 把包括的文件 改为 布局布线后的 门级电路网表文件,即由综合工具生成的
// pstosda.vo 和 out16hi.vo 文件。
// 为了能使门级电路网表模块进行仿真,有时还需要包括一个布线所用的FPGA 或 ASIC 
// 基本元件仿真库模块

// `timescale 1ns/1ns

`include "sigdata.v"
`include "ptosda.v"
`include "out16hi.v"


// 可用综合后产生的 门级 Verilog网表(netlist)文件 和 布局布线后产生的带延迟参数的Verilog 网表
// (netlist)文件来代替上面两个文件。 分别进行门级后仿真和布线后仿真。
// 这两种文件的扩展名不同,但都是Verilog门级模块

module top;
wire   [3:0] data;
wire   sclk;
wire   scl;
wire   sda;
wire   rst;
wire  [15:0] outhigh;

sigdata m0(.rst(rst), .sclk(sclk), .data(data), .ask_for_data(ack));
ptosda  m1(.rst(rst), .sclk(sclk), .ack(ack), .scl(scl), .sda(sda), .data(data));
out16hi m2(.scl(scl), .sda(sda), .outhigh(outhigh));


endmodule 

5,电路生成的门级网表,netlist

在这里插入图片描述

6,前仿真波形验证

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Camtasia2023简单易用的电脑录屏视频剪辑软件

教学、演示、培训视频轻松制作!Camtasia非常容易学习 你不需要一个大的预算或花哨的视频编辑技能。只需录制屏幕并添加一些特效即可。无论您是有经验还是这是第一次制作视频 Camtasia都会为您提供制作高质量视频所需的一切。创建观看者实际观看的内容。视频将为您提供更多的互动…

军队文职丨2022年武警部队面向社会公开招聘351名文职人员公告!高中学历可报,11月25日前报名!

2022年武警部队面向社会公开招聘 专业技能岗位文职人员公告 根据《军队专业技能岗位文职人员聘用管理暂行规定》及有关政策规定&#xff0c;现就2022年武警部队面向社会公开招聘专业技能岗位文职人员有关事项公告如下&#xff1a; 一、招聘岗位 武警部队所属用人单位运输投送…

前后端分类 (增加,查询)

目录 一&#xff0c;后台代码 二&#xff0c;前台代码 一&#xff0c;后台代码 一&#xff0c;配置文件 application.yml server:port: 8080servlet:context-path: /spboot spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.j…

隧道HTTP API使用教程

华科隧道HTTP格式为&#xff1a;ip:port username password 隧道代理分钟2种模式&#xff1a; 固定时间更改新IP&#xff08;比如5分钟&#xff0c;10分钟&#xff0c;初次开通的时候可设定&#xff09;请求一次更换一个新IP&#xff08;可通过浏览器或者curl&#xff09; 1、…

图_图的存储_添加边_图的遍历_DFS_树的重心_BFS_图中点的层次

文章目录图有向图的存储添加遍历1.DFS例题&#xff1a;树的重心题目分析使用DFS遍历2.BFS例题&#xff1a;图中点的层次图 树是特殊的图&#xff08;无环连通图&#xff09; 有向图&#xff08;a -> b&#xff09; 无向图&#xff08;a -> b, b -> a&#xff09; …

ffmpeg源码阅读之avformat_alloc_output_context2

整体结构流程 核心逻辑 通过读源码发现核心的处理逻辑是av_guess_format函数&#xff0c;这里就根据核心逻辑来阅读&#xff0c;其余的基本是是在做判断和赋值 av_guess_format阅读分析 步骤1(先看头文件) /*** Return the output format in the list of registered output…

wy的leetcode刷题记录_Day46

wy的leetcode刷题记录_Day46 声明 本文章的所有题目信息都来源于leetcode 如有侵权请联系我删掉! 时间&#xff1a;2022-11-19 前言 补 目录wy的leetcode刷题记录_Day46声明前言1732. 找到最高海拔题目介绍思路代码收获106. 从中序与后序遍历序列构造二叉树题目介绍思路代码…

【Java毕设】基于SpringBoot实现新冠疫情统计系统(Idea+Navicat)

推荐学习专栏&#xff1a; Java基础学习专栏&#xff1a;java基础知识学习Java进阶学习专栏&#xff1a;java编程进阶学习 前言 疫情在我们的生活中反反复复&#xff0c;为了方便我们更直观的清楚新冠疫情数据&#xff0c;通过Java编程可以统计疫情信息&#xff0c;更好管控。…

CSC公派|在读博士赴新加坡南洋理工大学联合培养

我们先助O同学取得了英国牛津大学的邀请函&#xff0c;并成功获批CSC项目。由于该校办理T5签证所需的COS担保证书迟迟未果&#xff0c;考虑到其毕业及CSC延期时限&#xff0c;我们又为O同学申请到新加坡南洋理工大学&#xff0c;顺利改派并签证出国。 O同学背景&#xff1a; 申…

【数据库09】数据库系统体系结构

前 言 &#x1f349; 作者简介&#xff1a;半旧518&#xff0c;长跑型选手&#xff0c;立志坚持写10年博客&#xff0c;专注于java后端 ☕专栏简介&#xff1a;相当硬核&#xff0c;黑皮书《数据库系统概念》读书笔记&#xff0c;讲解&#xff1a; 1.数据库系统的基本概念(数据…

WPF之MVVM模式

1.MVVM模式 MVVM即模型-视图-视图模型 &#xff0c;是用于解耦 UI 代码和非 UI 代码的 设计模式。 借助 MVVM&#xff0c;可以在 XAML 中以声明方式定义 UI&#xff0c;将 UI使用数据绑定标到包含数据和命令的其他层。 数据绑定提供数据和结构的松散耦合&#xff0c;使 UI 和链…

内联函数详解

文章目录前言正文知识点一&#xff1a;内联1、内联函数的诞生2、内联函数概念3、内联函数的特性结语前言 这里vince将要进入C的学习了&#xff0c;C学习将是一个漫长的过程&#xff0c;当然在学习这里的基础上前面的知识也不能不复习。也有很多人说C有多难有多难的&#xff0c…

零代码—0代码—无代码平台是什么?怎么选?

那么&#xff0c;零代码平台究竟是什么&#xff1f;我们该是不是优先选择呢&#xff1f;为方便大家理解&#xff0c;本文将从零代码平台的原因、特点、优势、应用实例、局限性、选择要点六个角度分析&#xff1a;零代码平台到底是什么&#xff1f;到底适不适合你来用&#xff1…

Java理清JDK、JRE、JVM之间什么关系?如何做到一次编译到处执行的?

在理解Java基础知识或者有一定编程基础后&#xff0c;看此文章会深有体会。 JDK、JRE、JVM之间什么关系 包含关系 开发环境&#xff08;jdk&#xff09;,执行环境&#xff08;jre&#xff09; 源程序通过Javac编译成字节码文件 这个字节码文件是可以被各个操作系统通用的文…

【Nginx】在Linux上如何安装Nginx教程+Nginx基本命令的使用

目录1. Nginx下载2. 系统准备3. Nginx安装3.1 安装方式3.2 依赖准备1&#xff09;GCC编译器2&#xff09;PCRE3&#xff09;zlib4&#xff09;OpenSSL3.3 源码下载3.4 解压编译3.5 Nginx目录结构3.6 配置环境变量4. Nginx基本命令4.1 检查配置文件的正确性4.2 查看Nginx配置文件…

qt example plugandpaint 插件 动态库 pnp_extrafiltersd.dll无法加载问题

使用版本windows qt5.12.0vs2015编译器。 运行plugandpaint工程的时候发现pnp_extrafiltersd.dll在load的时候失败了&#xff0c;经过调试&#xff0c;发现qlibrary.cpp中的findPatternUnloaded()的qt_find_pattern()无法通过。&#xff08;release 版的pnp_extrafilters.dll是…

Java基础深化和提高 ---- 网络编程

网络编程基本概念 计算机网络 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其 外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软 件及网络通信协议的管理和协调下&#xff0c;实现资源共享和信息传递的计 算机系统。 …

Linux系统下文件的压缩与打包

压缩和解压缩 压缩数据或者解压数据&#xff1a; 为什么要移出数据信息前面的 / 目录 -P --absolute-paths 不要从文件名中去除 /1 compress和uncompress 格式 compress Options [file ...]常用选项 -d 解压缩&#xff0c;相当于uncompress-c 结果输出至标准输出…

Spring 事务失效的场景

1、private、final、static 方法 被 Transactional 注解标注的方法的访问权限必须是 public&#xff1b; 被 Transactional 注解标注的方法不能被 final、static 修饰&#xff0c;被标注的方法必须是可覆盖的。这是因为事务底层使用的是 aop&#xff0c;而 aop 使用的是代理模…

嵌入式为何钟爱SourceInsight,主要因为这个功能~

已剪辑自: https://mp.weixin.qq.com/s/F-gafwbZswpnY8EaCz8HxQ 不管是玩单片机还是嵌入式linux&#xff0c;只要是与硬件结合比较紧密的部分目前基本上还是C语言&#xff0c;当然了&#xff0c;不知道以后C语言会不会被取代&#xff0c;即便哪天被某种更加优秀的语言取代&…