乒乓操作问题
是不是顶层文件对每个RAM的地址进行判断,如果写满则跳转到下一个RAM?
要是这样的话两个片上RAM的地址线该如何区分呢?
例化2个RAM单元以供顶层调用,乒乓操作由控制器来实现,写RAM A的时候读RAM B,写RAM B的时候读RAM A, 地址、读写、片选以及数据信号用两套
楼上的能麻烦指点一下这两个FIFO如何能实现乒乓操作啊。
我用Mega弄了两个FIFO,但都没有使能端,怎样写逻辑才能让其实现乒乓操作呢?
我考虑过用full_0, full_1来实现(当full_0 == 0 时,写第一个,当full_1 == 0 时,写第二个),但是初始状态的时候两个都是0,
就没法处理了。
fifo fifo_0 (
.clock(clk),
.data(data_0),
.rdreq(rd_0),
.wrreq(wr_0),
.empty(),
.full(full_0),
.q(dout_0)
);
fifo fifo_1 (
.clock(clk),
.data(data_0),
.rdreq(rd_1),
.wrreq(wr_1),
.empty(),
.full(full_1),
.q(dout_1)
);
可以用一个counter计录两个fifo里的数据量,当写入的数据达到你预期的值,并且把另一个fifo读空后,就可以切换了。这个切换可以单独拿一个模块来控制。
什么应用要用fifo做pingpong切换呢?我之前都是用ram做的pingpong
小编,乒乓一般做法是用BRAM去做,比如,用两个地址位宽都是10bit的BRAM去做的话,外面就需要一根11bit位宽的地址线,然后用地址最高位做ping pang选择,就是cs。
楼上的能指教一下么,我用双口RAM做了个乒乓结构,写入是没问题,但是我想实现在写A的时候读B该怎么操作呢?
module ram ( clk, rst_n, idin, dout_a, dout_b);
input clk;
input rst_n;
input [7:0] idin;
output [7:0] dout_a, dout_b;
reg rd_a, rd_b;
reg wr_a, wr_b;
reg [4:0] addr_a, addr_b;
reg [7:0] data_a, data_b;
wire a ,b;
assign a = addr_a == 'b1_1111 ? 1 : 0;
assign b = addr_b == 'b1_1111 ? 1 : 0;
always @ (posedge clk or negedge rst_n)
if (!rst_n)
begin
wr_a <= 1'b1; //A的写使能
wr_b <= 1'b0; //B的写使能
rd_a <= 1'b0; //A的读使能
rd_b <= 1'b1; //B的读使能
end
else if (a)
begin
wr_a <= 1'b0;
wr_b <= 1'b1;
rd_a <= 1'b1;
rd_b <= 1'b0;
end
else if (b)
begin
wr_a <= 1'b1;
wr_b <= 1'b0;
rd_a <= 1'b0;
rd_b <= 1'b1;
end
always @ (posedge clk or negedge rst_n)
if (!rst_n)
begin
data_a <= 'b0;
addr_a <= 'b0;
data_b <= 'b0;
addr_b <= 'b0;
end
else if (wr_a) // 这里想在写A的时候同时读B,不知道该怎么写了
begin
data_a <= idin;
addr_a <= addr_a + 1'b1;
end
else if (wr_b) // write. b read a
begin
data_b <= idin;
addr_b <= addr_b + 1'b1;
end
dualram ram (
// input
.address_a(addr_a),
.address_b(addr_b),
.clock(clk),
.data_a(data_a),
.data_b(data_b),
.rden_a(rd_a),
.rden_b(rd_b),
.wren_a(wr_a),
.wren_b(wr_b),
//output
.q_a(dout_a),
.q_b(dout_b)
);
endmodule
