一级目录
二级目录
三级目录
1 乒乓简介
乒乓操作是FPGA设计中常用的一种技巧,两组或者多组相同或者类似的结构,通过并行工作,轮流输出的形式,提高处理性能的一种结构,此处以2组为例。
此处的乒乓都是不带存储的,即Buffer都是1个数据深度。先实现简单的,然后在基础上将Buffer换成两个FIFO,每个FIFO也可以各自加上握手·····等等。
有关FIFO、Valid—Ready握手相关请转至上一篇文章:同步Vaild-Ready握手FIFO机制链接:
链接: link
2 乒乓原理
如上图所示,有以下4点:
1、数据输入进来,2选1进Buffer;数据输出出去,2选1出Buffer。
2、写1时2读,写2时1读。
3、对Buffer的写与读都通过读写使能控制。
4、读写使能通过**状态机**控制。
3 状态机设置
电路只有两种状态,即**写1读2**,**写2读1**,故使用**一位信号不断取反**即可实现状态切换。
4 代码
模块代码:
module PingPang #(parameter WIDTH = 4) (
input clk,
input rst_n,
input [WIDTH-1:0] data_in,
output reg [WIDTH-1:0] data_out
);
//reg define
reg [WIDTH-1:0] buffer1; //ping
reg [WIDTH-1:0] buffer2; //pang
reg wr_buffer1; //buffer1写使能
reg wr_buffer2; //buffer2写使能
reg rd_buffer1; //buffer1读使能
reg rd_buffer2; //buffer2读使能
//state define
reg state;
parameter s0 = 1'b0,s1 = 1'b1;
always@(posedge clk or negedge rst_n)
begin
if (!rst_n)
state <= s0;
else
state <= ~state;
end
always@(*)
begin
case(state)
s0: //写1读2
begin
wr_buffer1 <= 1'b1;
rd_buffer2 <= 1'b1;
wr_buffer2 <= 1'b0;
rd_buffer1 <= 1'b0;
end
s1: //写2读1
begin
wr_buffer1 <= 1'b0;
rd_buffer2 <= 1'b0;
wr_buffer2 <= 1'b1;
rd_buffer1 <= 1'b1;
end
default: //写1读2
begin
wr_buffer1 <= 1'b1;
rd_buffer2 <= 1'b1;
wr_buffer2 <= 1'b0;
rd_buffer1 <= 1'b0;
end
endcase
end
//根据标志位写数据
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
buffer1 <= 4'b0;
buffer2 <= 4'b0;
end
else begin
if(wr_buffer1 && (!wr_buffer2))
buffer1 <= data_in;
else if (wr_buffer2 && (!wr_buffer1))
buffer2 <= data_in;
else begin
buffer1 <= 4'b0;
buffer2 <= 4'b0;
end
end
end
//根据标志位读数据
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
data_out <= 4'b0;
end
else begin
if(rd_buffer1 && (!rd_buffer2))
data_out <= buffer1;
else if (rd_buffer2 && (!rd_buffer1))
data_out <= buffer2;
else
data_out <= 4'b0;
end
end
endmodule
testbench代码:
`timescale 1ns/1ns
module tb_PingPang#(parameter WIDTH = 4);
reg clk;
reg rst_n;
reg [WIDTH-1:0] data_in;
wire [WIDTH-1:0] data_out;
PingPang PingPang_u0 (
.clk(clk),
.rst_n(rst_n),
.data_in(data_in),
.data_out(data_out));
initial begin
rst_n = 1'b0;
clk = 1'b0;
#20 rst_n = 1'b1;
#20 repeat(8) begin
@(posedge clk)begin
data_in <= $random;
end
end
end
always begin
#10 clk = ~clk;
end
endmodule
5 波形
输入的波形在Buffer1和Buffer2中来回切换,并且输出。
至此完结!!!
下面来考虑,如何把Buffer1和2都换成两个可以存储的FIFO呢?具体解决思路我过几天再更新。
最后一样,贴上邮箱:boyue8817505@163.com