109 lines
3.1 KiB
Systemverilog
109 lines
3.1 KiB
Systemverilog
// Copyright © 2019-2023
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
`include "VX_platform.vh"
|
|
|
|
module VX_ipdom_stack #(
|
|
parameter WIDTH = 1,
|
|
parameter DEPTH = 1,
|
|
parameter OUT_REG = 0,
|
|
parameter ADDRW = `LOG2UP(DEPTH)
|
|
) (
|
|
input wire clk,
|
|
input wire reset,
|
|
input wire [WIDTH-1:0] q0,
|
|
input wire [WIDTH-1:0] q1,
|
|
output wire [WIDTH-1:0] d,
|
|
output wire d_set,
|
|
input wire push,
|
|
input wire pop,
|
|
output wire empty,
|
|
output wire full
|
|
);
|
|
reg slot_set [DEPTH-1:0];
|
|
|
|
reg [ADDRW-1:0] rd_ptr, wr_ptr;
|
|
|
|
reg empty_r, full_r;
|
|
|
|
wire [WIDTH-1:0] d0, d1;
|
|
|
|
wire d_set_n = slot_set[rd_ptr];
|
|
|
|
always @(posedge clk) begin
|
|
if (reset) begin
|
|
rd_ptr <= '0;
|
|
wr_ptr <= '0;
|
|
empty_r <= 1;
|
|
full_r <= 0;
|
|
end else begin
|
|
`ASSERT(~push || ~full, ("runtime error: writing to a full stack!"));
|
|
`ASSERT(~pop || ~empty, ("runtime error: reading an empty stack!"));
|
|
`ASSERT(~push || ~pop, ("runtime error: push and pop in same cycle not supported!"));
|
|
if (push) begin
|
|
rd_ptr <= wr_ptr;
|
|
wr_ptr <= wr_ptr + ADDRW'(1);
|
|
empty_r <= 0;
|
|
full_r <= (ADDRW'(DEPTH-1) == wr_ptr);
|
|
end else if (pop) begin
|
|
wr_ptr <= wr_ptr - ADDRW'(d_set_n);
|
|
rd_ptr <= rd_ptr - ADDRW'(d_set_n);
|
|
empty_r <= (rd_ptr == 0) && (d_set_n == 1);
|
|
full_r <= 0;
|
|
end
|
|
end
|
|
end
|
|
|
|
VX_dp_ram #(
|
|
.DATAW (WIDTH * 2),
|
|
.SIZE (DEPTH),
|
|
.OUT_REG (OUT_REG ? 1 : 0),
|
|
.LUTRAM (OUT_REG ? 0 : 1)
|
|
) store (
|
|
.clk (clk),
|
|
.read (1'b1),
|
|
.write (push),
|
|
`UNUSED_PIN (wren),
|
|
.waddr (wr_ptr),
|
|
.wdata ({q1, q0}),
|
|
.raddr (rd_ptr),
|
|
.rdata ({d1, d0})
|
|
);
|
|
|
|
always @(posedge clk) begin
|
|
if (push) begin
|
|
slot_set[wr_ptr] <= 0;
|
|
end else if (pop) begin
|
|
slot_set[rd_ptr] <= 1;
|
|
end
|
|
end
|
|
|
|
wire d_set_r;
|
|
VX_pipe_register #(
|
|
.DATAW (1),
|
|
.DEPTH (OUT_REG)
|
|
) pipe_reg (
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (1'b1),
|
|
.data_in (d_set_n),
|
|
.data_out (d_set_r)
|
|
);
|
|
|
|
assign d = d_set_r ? d0 : d1;
|
|
assign d_set = ~d_set_r;
|
|
assign empty = empty_r;
|
|
assign full = full_r;
|
|
|
|
endmodule
|