zoukankan      html  css  js  c++  java
  • 基础项目(7)串行转并行程序设计及讲解

    写在前面的话

    串并/并串转换是FPGA设计过程中的一个重要技巧,经常被用在高速数据流处理中,特别是在通信接口方面尤为重要。如UART串口协议SPI串口协议、IIC串口协议都需要用到串并/并串转换。本节,梦翼师兄和大家一起来学习串并/并串转换的实现方法。

    需求分析

    并转串的设计思想是这样的:首先准备好一组寄存器,把需要发送的数据(并行数据)放到这个寄存器组里面,然后通过位拼接的移位方式把这个并行数据一位一位地发送给接收端,同时拉高标志信号en,当全部数据发送完之后,在把标志信号en拉低。

    顶层框架设计

    顶层模块端口介绍

    端口名

    端口说明

    clk

    系统50MHz时钟输入

    rst_n

    系统低电平复位

    en

    数据转换标志信号

    sda

    输出的串行数据

    代码实现

    /****************************************************          

     *   Engineer      :   梦翼师兄

     *   QQ             :   761664056

     *   The module function : 转串模块

    *****************************************************/

    01  module para_serial(

    02              //系统输入

    03              clk,    //50M系统时钟输入

    04              rst_n,  //系统复位

    05              //系统输出

    06              sda,    //串行数据总线

    07              en      //数据转换标志信号

    08            );

    09  //-------------系统输入--------------

    10  input clk;  //50M系统时钟输入

    11  input rst_n;//系统复位

    12  //-------------系统输出--------------

    13  output reg sda; //串行数据总线

    14  output reg en;  //数据转换标志信号

    15  //------------寄存器定义-------------

    16  reg [7:0]sda_buf;   //并行数据寄存器

    17  reg [3:0]counter;   //移位计数器

    18  //-----------并串转换逻辑------------

    19  always@(posedge clk or negedge rst_n)

    20      begin

    21          if(!rst_n)

    22              begin

    23                  sda<=0; //串行数据总线赋初值

    24                  sda_buf<=8'b1001_1101; //并行数据寄存器赋初值

    25                  counter<=0; //移位计数器赋初值

    26                  en<=0; //数据转换标志信号赋初值

    27              end

    28          else

    29              begin

    30                  if(counter<8)//控制移位次数

    31                      begin

    32                          en<=1;  //转换使能打开

    33                          counter<=counter+1'b1;

                                //通过位拼接方式实现并串转换

    34                          sda_buf<={sda_buf[6:0],sda_buf[7]}; 

    35                          sda<=sda_buf[7]; //sda_buf一位位的发送出去

    36                      end

    37                  else

    38                      begin

    39                          counter<=0;//移位结束,计数器清零

    40                          sda<=0;

    41                          en<=0;     //转换完成

    42                      end

    43              end 

    44      end 

    45      

    46  endmodule

    代码分析我们首先定义了一个8数据寄存器sda_buf和一个控制移位的计数器counter,然后在电路复位的时候给sda_buf写入了一个8的并行数据8’b1001_1101;第30~35行,我们拉高数据转换标志信号en,把并行数据sda_buf的最高位输出到sda同时sda_buf进行左移操作,sda_buf中的数据就会以串行的方一位一位的发送出去39~41移位结束同时,计数器清零,数据转换标志信号en变为低电平,完成了一次数据并行数据的转换

    编写的测试代码如下:

    /****************************************************          

     *   Engineer      :   梦翼师兄

     *   QQ             :   761664056

     *   The module function : 转串测试模块

    *****************************************************/

    01  `timescale 1ns/1ps 

    02  module tb;

    03

    04  //------------被测试模块输入------------

    05  reg clk;    //50M系统时钟输入

    06  reg rst_n;  //系统复位

    07  //------------被测试模块输出-------------

    08  wire sda;  //串行数据总线

    09  wire en;   //数据转换标志信号

    10  //------------设置测试激励---------------

    11  initial

    12      begin

    13          clk=0;

    14          rst_n=0;

    15          # 1000.1 rst_n=1;

    16      end 

    17      

    18  always #10 clk=~clk; //周期为20ns的时钟

    19

    20  //-------------模块实例化----------------

    21  para_serial para_serial  (

    22              .clk(clk),

    23              .rst_n(rst_n),

    24              .sda(sda),

    25              .en(en)

    26            );

    27  endmodule

    仿真波形如下所示:

    观察波形可以看到当数据转换标志信号en为高电平的时候,sda_buf中的数据从最高位开始输出,也就是sda开始输出串行数据,当sda_buf的全部数据输出后的同时,数据转换标志信号en变为低电平。

    接下来,我们来学习串行数据转换成并行数据的设计实现技巧,由于我们已经有一个并转串的模块来输出串行数据,所以我们可以巧妙的利用这个模块。

    我们在测试代码中加入一个串行数据转换成并行数据的模块,它部件架构图如下(下面测试代码第24~41行):

    修改后的测试代码如下:

    /****************************************************          

     *   Engineer      :   梦翼师兄

     *   QQ             :   761664056

     *   The module function :转并测试模块

    *****************************************************/

    01  `timescale 1ns/1ns 

    02  module tb;

    03

    04  //------------被测试模块输入------------

    05  reg clk;    //50M系统时钟输入

    06  reg rst_n;  //系统复位

    07  //------------被测试模块输出-------------

    08  wire sda;  //串行数据总线

    09  wire en;   //数据转换标志信号

    10  //------------设置测试激励---------------

    11  initial

    12      begin

    13          clk=0;

    14          rst_n=0;

    15          # 1000 rst_n=1;

    16      end 

    17      

    18  always #10 clk=~clk; //周期为20ns的时钟

    19

    20  //------------串并转换模块---------------

    21  reg [7:0]sda_reg;   //串行数据接收寄存器

    22  wire en;

    23

    24  always@(posedge clk or negedge rst_n)

    25      begin

    26          if(!rst_n)

    27              begin

    28                  sda_reg<=0;

    29              end

    30          else

    31              begin

    32                  if(en)    //检测到数据转换标志信号为高电平

    33                      begin //将输入的串行数据sda转换为并行数据sda_reg

    34                          sda_reg<={sda_reg[6:0],sda}; 

    35                      end 

    36                  else    //检测到en为低电平,不采取任何操作

    37                      begin

    38                          sda_reg<=0;

    39                      end 

    40              end 

    41      end

    42  //-------------模块实例化----------

    43  para_serial para_serial  (

    44              .clk(clk),

    45              .rst_n(rst_n),

    46              .sda(sda),

    47              .en(en)

    48            );

    49  endmodule

    代码分析:我们首先定义了一个串行数据接收寄存sda_reg,检测数据转换标志信号en有效时,sda_reg通过位拼接的方式依次将并转串模块输出的串行数据sda移入到sda_reg的每一位(从低位到高位),从而实现串行数据向并行数据的转换。

    仿真波形如下所示:

     

    观察波形可以看到当数据转换标志信号en为高电平的时候,sda_reg开始串行数据sda当数据转换标志信号en为低电平的时数据向并行数据的转换刚好结束,我们可以出转换得到的并行数据sda_reg和发送的并行数据sda_buf是完全相同的,说明我们设计是正确的。

  • 相关阅读:
    第五周
    第三章 程序的机器级表示
    第二章 信息的表示和处理
    嵌入式Linux应用开发——Linux下的C编程基础
    Linux基础入门(20135207 王国伊)
    Java实验报告(实验四)
    linux系统之pam模块
    linux 从入门到跑路-时间,日期问题
    linux 从入门到跑路-Shell和部分命令
    linux 从入门到跑路-挂载,命令的执行顺序
  • 原文地址:https://www.cnblogs.com/mengyi1989/p/11521050.html
Copyright © 2011-2022 走看看