// -----------------------------------------------------------------------------
// Copyright (c) 2014-2025 All rights reserved
// -----------------------------------------------------------------------------
// Author : lvjitao lvjitao_o@163.com
// File : ram_pingpang.v
// Create : 2025-10-08 09:29:06
// Revise : 2025-10-08 14:02:27
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
`timescale 1ns/1ps
module ram_pingpang(
input wire clk,
input wire rst_n,
input wire data_valid,
input wire signed [9:0] data ,
output reg [9:0] po_data,
output reg po_data_valid
);
//write ram a enable
reg wr_ena;
reg [9:0] wr_addra;
reg signed [9:0] wr_dataa;
reg signed [19:0] a_add_rlst;
reg avg_a_vlaid;
reg signed [9:0] avg_a;
reg rd_ena;
reg [9:0] rd_addra;
wire [9:0] rd_dataa;
reg rd_dataa_v;
//write ram b enable
reg wr_enb;
reg [9:0] wr_addrb;
reg signed [9:0] wr_datab;
reg signed [19:0] b_add_rlst;
reg avg_b_vlaid;
reg signed [9:0] avg_b;
reg rd_enb;
reg [9:0] rd_addrb;
wire [9:0] rd_datab;
reg rd_datab_v;
always @(posedge clk) begin
if (rst_n == 1'b0) begin
wr_ena <= 1'b0;
end
else if (wr_addra == 'd1023) begin
wr_ena <= 1'b0;
end
else if (wr_addrb == 'd1023 && data_valid == 1'b1) begin
wr_ena <= 1'b1;
end
else if (wr_ena == 1'b0 && wr_enb == 1'b0 && data_valid == 1'b1) begin
wr_ena <= 1'b1;
end
end
always @(posedge clk) begin
if (rst_n == 1'b0) begin
wr_addra <= 'd0;
end
else if (wr_ena == 1'b1 && wr_addra == 'd1023) begin
wr_addra <= 'd0;
end
else if (wr_ena == 1'b1) begin
wr_addra <= wr_addra + 1'b1;
end
end
always @(posedge clk) begin
wr_dataa <= data;
end
always @(posedge clk ) begin
if (rst_n == 1'b0) begin
a_add_rlst <='d0;
end
else if (avg_a_vlaid == 1'b1) begin
a_add_rlst <='d0;
end
else if (wr_ena == 1'b1 ) begin
a_add_rlst <= a_add_rlst + wr_dataa;
end
end
always @(posedge clk) begin
if (rst_n == 1'b0) begin
avg_a_vlaid <= 1'b0;
end
else if (wr_addra == 'd1023) begin
avg_a_vlaid <= 1'b1;
end
else begin
avg_a_vlaid <= 1'b0;
end
end
always @(posedge clk )begin
if (rst_n == 1'b0) begin
avg_a <='d0;
end
else if (avg_a_vlaid == 1'b1) begin
avg_a <= a_add_rlst[19:10];
end
end
//read ram a
always @(posedge clk) begin
if (rst_n == 1'b0) begin
rd_ena <= 1'b0;
end
else if (rd_addra == 'd1023) begin
rd_ena <= 1'b0;
end
else if (avg_a_vlaid == 1'b1) begin
rd_ena <= 1'b1;
end
end
always @(posedge clk) begin
if (rst_n == 1'b0) begin
rd_addra <='d0;
end
else if (rd_addra == 'd1023) begin
rd_addra <='d0;
end
else if (rd_ena == 1'b1) begin
rd_addra <= rd_addra + 1'b1;
end
end
sdp_blk_wr10x1024 sdp_blk_wr10x1024_inst_rama (
.clka(clk), // input wire clka
.wea(wr_ena), // input wire [0 : 0] wea
.addra(wr_addra), // input wire [9 : 0] addra
.dina(wr_dataa), // input wire [9 : 0] dina
.clkb(clk), // input wire clkb
.addrb(rd_addra), // input wire [9 : 0] addrb
.doutb(rd_dataa) // output wire [9 : 0] doutb
);
always @(posedge clk) begin
if (rst_n == 1'b0) begin
wr_enb <= 1'b0;
end
else if (wr_addrb == 'd1023) begin
wr_enb <= 1'b0;
end
else if (wr_ena == 1'b1 && data_valid == 1'b1 && wr_addra =='d1023) begin
wr_enb <= 1'b1;
end
end
always @(posedge clk) begin
if (rst_n == 1'b0) begin
wr_addrb <= 'd0;
end
else if (wr_enb == 1'b1 && wr_addrb == 'd1023) begin
wr_addrb <= 'd0;
end
else if (wr_enb == 1'b1) begin
wr_addrb <= wr_addrb + 1'b1;
end
end
always @(posedge clk) begin
wr_datab <= data;
end
always @(posedge clk ) begin
if (rst_n == 1'b0) begin
b_add_rlst <='d0;
end
else if (avg_b_vlaid == 1'b1) begin
b_add_rlst <='d0;
end
else if (wr_enb == 1'b1 ) begin
b_add_rlst <= b_add_rlst + wr_datab;
end
end
always @(posedge clk) begin
if (rst_n == 1'b0) begin
avg_b_vlaid <= 1'b0;
end
else if (wr_addrb == 'd1023) begin
avg_b_vlaid <= 1'b1;
end
else begin
avg_b_vlaid <= 1'b0;
end
end
always @(posedge clk )begin
if (rst_n == 1'b0) begin
avg_b <='d0;
end
else if (avg_b_vlaid == 1'b1) begin
avg_b <= b_add_rlst[19:10];
end
end
//read ram b
always @(posedge clk) begin
if (rst_n == 1'b0) begin
rd_enb <= 1'b0;
end
else if (rd_addrb == 'd1023) begin
rd_enb <= 1'b0;
end
else if (avg_b_vlaid == 1'b1) begin
rd_enb <= 1'b1;
end
end
always @(posedge clk) begin
if (rst_n == 1'b0) begin
rd_addrb <='d0;
end
else if (rd_addrb == 'd1023) begin
rd_addrb <='d0;
end
else if (rd_enb == 1'b1) begin
rd_addrb <= rd_addrb + 1'b1;
end
end
sdp_blk_wr10x1024 sdp_blk_wr10x1024_inst_ramb (
.clka(clk), // input wire clka
.wea(wr_enb), // input wire [0 : 0] wea
.addra(wr_addrb), // input wire [9 : 0] addra
.dina(wr_datab), // input wire [9 : 0] dina
.clkb(clk), // input wire clkb
.addrb(rd_addrb), // input wire [9 : 0] addrb
.doutb(rd_datab) // output wire [9 : 0] doutb
);
always @(posedge clk) begin
if (rst_n == 1'b0) begin
rd_dataa_v <='d0;
rd_datab_v <='d0;
end
else begin
rd_dataa_v <= rd_ena;
rd_datab_v <= rd_enb;
end
end
always @(posedge clk) begin
if (rst_n == 1'b0) begin
po_data <= 'd0;
end
else if (rd_dataa_v == 1'b1) begin
po_data <= rd_dataa - avg_a;
end
else if(rd_datab_v == 1'b1)begin
po_data <= rd_datab - avg_b;
end
else begin
po_data <='d0;
end
end
always @(posedge clk) begin
if (rst_n == 1'b0) begin
po_data_valid <= 1'b0;
end
else begin
po_data_valid <= rd_dataa_v | rd_datab_v;
end
end
endmodule
// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : youkaiyuan v3eduyky@126.com
// Wechat : 15921999232
// File : tb_ram_pingpang_avg.v
// Create : 2023-11-19 10:55:39
// Revise : 2023-11-19 11:01:31
// Editor : sublime text3, tab size (4)
// -----------------------------------------------------------------------------
`timescale 1ns/1ps
module tb_ram_pingpang_avg();
reg clk,rst_n;
reg d_v;
reg [9:0] d;
wire [9:0] po_data;
wire po_data_valid;
reg [9:0] mem [8191:0];
initial begin
clk =0;
rst_n =0;
repeat(10) @(posedge clk);
rst_n =1;
end
always #5 clk = ~clk;
initial begin
$readmemh("./data_src.mif",mem);
d=0;
d_v=0;
end
initial begin
repeat(20) @(posedge clk);
gen_data();
end
task gen_data;
integer i;
begin
for(i=0;i<8192;i=i+1) begin
@(posedge clk);
d <= mem[i];
d_v <= 1'b1;
end
@(posedge clk);
d <= 0;
d_v <= 1'b0;
end
endtask
ram_pingpang_avg inst_ram_pingpang_avg
(
.clk (clk),
.rst_n (rst_n),
.data_valid (d_v),
.data (d),
.po_data (po_data),
.po_data_valid (po_data_valid)
);
endmodule