Infrastructure projects (7) walk through to parallel programming and explain

Written on the front of the words

Serial / parallel to serial conversion is an important skill FPGA design process, is often used in high-speed data stream processing, especially important aspects of the communication interface. The UART serial protocol , the SPI serial port protocol, IIC serial protocols need to use serial / parallel to serial conversion. In this section, we dream wing brothers and learn together serial implementation / parallel-serial conversion.

demand analysis

And forwarding string design is as follows: First prepare a set of registers, the data (parallel data) needs to be sent into the register set inside, and then by splicing the shift mode bit parallel data to one bit of this sent to the receiver, while pulled flag signal en, when after completion of all the data transmitted in the flag signal en down.

Top frame design

 

 

Top-level module port description

Port Name

Port Description

clk

50MHz system clock input

rst_n

System Reset Low

in

Data conversion flag signal

sda

Serial data output

Code

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

 * Engineer:    Dream Brother Wing

 *   QQ             :   761664056

 * The module function: and -serial module

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

01  module para_serial(

02 // system input

CLK 03 ,     // 50M system clock input

Rst_n 04 ,   // system reset

05 // system output

Sda 06 ,     // serial data bus

07 en // data conversion flag signal

08            );

09 // ------------- system input --------------

10   INPUT  CLK ;   // 50M system clock input

. 11   INPUT  RST_N ; // reset

12 // ------------- system output --------------

13 is   Output  REG  SDA ;  // serial data bus

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是完全相同的,说明我们设计是正确的。

 

Guess you like

Origin www.cnblogs.com/mengyi1989/p/11521050.html