博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FPGA之乒乓操作
阅读量:6555 次
发布时间:2019-06-24

本文共 4464 字,大约阅读时间需要 14 分钟。

1.乒乓操作原理
  乒乓操作是一个主要用于数据流控制的处理技巧,典型的乒乓操作如图所示:
  外部输入数据流通过“输入数据选择控制”模块送入两个数据缓冲区中,数据缓冲模块可以为任何存储模块,比较常用的存储单元为双口RAM(Dual RAM),SRAM,SDRAM,FIFO等。
 
       在第1个缓冲周期,将输入的数据流缓存到“数据缓冲1”模块,在第2个缓冲周期,“输入数据选择控制”模块将输入的数据流缓存到“数据缓冲2”模块的同时,“输出数据选择控制”模块将“数据缓冲1”模块第一个周期缓存的数据流送到“后续处理”,模块进行后续的数据处理,在第三个缓冲周期,在“输入数据选择控制”模块的再次切换后,输入的数据流缓存到“数据缓冲1”模块,与此同时,“输出数据选择控制”模块也做出切换,将“数据缓冲2”模块缓存的第二个周期的数据送到“后续处理模块”,如此循环。
  这里正是利用了乒乓操作完成数据的无缝缓冲与处理,乒乓操作可以通过“输入数据选择控制”和“输出数据选择控制”按节拍,相互配合地进行来回切换,将经过缓冲的数据流没有停顿的送到“后续处理模块”。

 

  比如将乒乓操作运用在液晶显示的控制模块上,如图所示。

  对于外部接口传输的图像数据,以一帧图像为单位进行SDRAM的切换控制,当SDRAM1缓存图像数据时,液晶显示的是SDRAM2的数据图像;反之,当SDRAM2缓存图像数据时,液晶显示的是SDRAM1的数据图像,如此反复,这样出路的好处在于液晶显示图像切换瞬间完成,掩盖了可能比较缓慢的图像数据流变换过程。
2.FPGA乒乓操作代码
2.1 FPGA设计代码
1 module pingpang 2     ( 3         input            clk        , 4         input            rst_n      , 5         input      [7:0] data_in    ,    // 输入数据 6         output reg [7:0] data_out        // 输出数据 7     ); 8      9 // ------------------------------------------------------ //10     reg [7:0]    buffer1    ;    // 缓存111     reg [7:0]    buffer2    ;    // 缓存212     reg          wr_flag    ;    // 写标志,wr_flag=0,写buffer1,wr_flag=1,写buffer213     reg          rd_flag    ;    // 读标志,rd_flag=0,读buffer2,rd_flag=1,读buffer114     reg          state      ;    // 状态机,0:写1读2,1:写2读1,状态转移和输出分开编码15 // ------------------------------------------------------ //    16     // 状态转移17     always @ (posedge clk or negedge rst_n)18     begin19         if(rst_n == 1'b0)20         begin21             state <= 'b0;22         end23         else24         begin25             state <= !state;26             //case(state)27             //    1'b0    : state <= 1'b0;    // 写1读2->写2读128             //    1'b1    : state <= 1'b1;    // 写2读1->写1读229             //    default : state <= 1'b0;30             //endcase31         end32     end33 // ------------------------------------------------------ // 34     // 状态输出35     always @ (state)36     begin37         case(state)38             1'b0:39             begin40                 wr_flag = 1'b0; // 写141                 rd_flag = 1'b0; // 读242             end43             1'b1:44             begin45                 wr_flag = 1'b1; // 写246                 rd_flag = 1'b1; // 读147             end48             default:49             begin50                 wr_flag = 1'b0;51                 rd_flag = 1'b0;52             end53         endcase54     end55 // ------------------------------------------------------ //  56     // 写buffer数据   57     always @ (posedge clk or negedge rst_n)58     begin59         if(rst_n == 1'b0)60         begin61             buffer1 <= 8'b0;62             buffer2 <= 8'b0;63         end64         else65         begin66             case(wr_flag)67                 1'b0    : buffer1 <= data_in;  // wr_flag = 0,写buffer168                 1'b1    : buffer2 <= data_in;  // wr_flag = 1,写buffer269                 default    :70                 begin71                     buffer1 <= 8'b0;72                     buffer2 <= 8'b0;73                 end74             endcase75         end76     end    77 // ------------------------------------------------------ // 78     // 读buffer数据79     always @ (posedge clk or negedge rst_n)80     begin81         if(rst_n == 1'b0)82         begin83             data_out <= 8'b0;84         end85         else86         begin87             case(rd_flag)88                 1'b0    : data_out <= buffer2;   // rd_flag=0,读buffer289                 1'b1    : data_out <= buffer1;   // rd_flag=1,读buffer190                 default : data_out <= 8'b0;91             endcase92         end93     end94 // ------------------------------------------------------ //     95 endmodule

 

2.2 FPGA仿真代码

`timescale 1ns / 1psmodule pingpang_tb();    reg            clk        ;    reg            rst_n    ;        reg    [7:0]    data_in    ;        wire[7:0]    data_out;            always #10 clk = ~clk;        initial    begin        rst_n    <= 1'b0    ;        clk        <= 1'b0    ;        #2010;        rst_n    <= 1'b1    ;    end        always @(posedge clk or negedge rst_n)    begin        if(!rst_n)            data_in    <= 'd0;        else            data_in    <= data_in + 1'b1;    end        pingpang dut    (        .clk            (clk        ),        .rst_n            (rst_n        ),        .data_in        (data_in    ),                             .data_out        (data_out    )    );    endmodule

 

3.仿真结果

  

转载于:https://www.cnblogs.com/lai-jian-tao/p/10796248.html

你可能感兴趣的文章
java 代理
查看>>
数据库设计三范式
查看>>
Eclipse插件开发- view to view drag drop
查看>>
Linux 技巧:让进程在后台可靠运行的几种方法
查看>>
ORACLE特殊字符的处理方法
查看>>
根据Servlet的Filter自定义实现字符编码过滤器
查看>>
shiro之Remembered vs. Authenticated
查看>>
碉堡了!又一只会跑酷的狗狗!
查看>>
python入门(一)-- 简介与基本语法
查看>>
oh-my-zsh安装与配置
查看>>
pyramid学习笔记整理
查看>>
common lisp asdf
查看>>
git修改远程仓库地址
查看>>
Guess the number
查看>>
iscsi网络存储
查看>>
团队随笔
查看>>
Java内存块说明
查看>>
List集合具体对象的特点
查看>>
网络信息安全之防火墙***检测方法 (五)
查看>>
怎样为用户写“招标书”
查看>>