`include "VX_platform.vh" module VX_ipdom_stack #( parameter WIDTH = 1, parameter DEPTH = 1 ) ( input wire clk, input wire reset, input wire [WIDTH - 1:0] q1, input wire [WIDTH - 1:0] q2, output wire [WIDTH - 1:0] d, input wire push, input wire pop, output wire empty, output wire full ); localparam ADDRW = $clog2(DEPTH); reg is_part [DEPTH-1:0]; reg [ADDRW-1:0] rd_ptr, wr_ptr; wire [WIDTH-1:0] d1, d2; always @(posedge clk) begin if (reset) begin rd_ptr <= 0; wr_ptr <= 0; end else begin if (push) begin rd_ptr <= wr_ptr; wr_ptr <= wr_ptr + ADDRW'(1); end else if (pop) begin wr_ptr <= wr_ptr - ADDRW'(is_part[rd_ptr]); rd_ptr <= rd_ptr - ADDRW'(is_part[rd_ptr]); end end end VX_dp_ram #( .DATAW(WIDTH * 2), .SIZE(DEPTH), .RWCHECK(1), .FASTRAM(1) ) store ( .clk(clk), .waddr(wr_ptr), .raddr(rd_ptr), .wren(push), .byteen(1'b1), .rden(pop), .din({q2, q1}), .dout({d2, d1}) ); always @(posedge clk) begin if (push) begin is_part[wr_ptr] <= 0; end else if (pop) begin is_part[rd_ptr] <= 1; end end wire p = is_part[rd_ptr]; assign d = p ? d1 : d2; assign empty = ~(| wr_ptr); assign full = (ADDRW'(DEPTH-1) == wr_ptr); endmodule