data/full_repos/permissive/165659134/rtl/fifo_synch.v
data/verilator_xmls/f36c04d6-1ebe-4957-8868-8736c012e369.xml
module fifo_synch
#(
  parameter DATA_WD = 8,
  parameter PTR_WD = 6
)
(
  input clk,
  input rst_n,
  input [DATA_WD-1:0] data_in,
  input wr_ptr_upd,
  input flush,
  output [PTR_WD-1:0] level,
  input push,
  output pop,
  output [DATA_WD-1:0] data_out,
  output full,
  output empty
);

localparam FIFO_DEPTH = 1 << PTR_WD;

reg [DATA_WD-1:0] fifo_r [FIFO_DEPTH-1:0];
reg [PTR_WD:0] rd_ptr_r;
reg [PTR_WD:0] wr_ptr_r;
reg [PTR_WD:0] wr_ptr_new_r;
reg [PTR_WD-1:0] level_r;
wire full_bit;

assign level = level_r;


assign full_bit = wr_ptr_r[PTR_WD] ^ rd_ptr_r[PTR_WD];
assign full = full_bit && (wr_ptr_r[PTR_WD-1:0] == rd_ptr_r[PTR_WD-1:0]);
assign empty = (wr_ptr_r == rd_ptr_r) ? 1'b1 : 1'b0;


assign data_out = fifo_r[rd_ptr_r[PTR_WD-1:0]];

always @(posedge clk)
begin: FIFO_R_PROC
  if (push) begin
    fifo_r[wr_ptr_new_r[PTR_WD-1:0]] <= data_in;
  end
end


always @(posedge clk or negedge rst_n)
begin: RD_POINTER_R_PROC
  if (!rst_n) begin
    rd_ptr_r <= {PTR_WD+1{1'b0}};
  end
  else if (!empty && pop) begin
    rd_ptr_r <= rd_ptr_r+1'b1;
  end
end


always @(posedge clk or negedge rst_n)
begin: WR_PTR_NEW_R_PROC
  if (!rst_n) begin
    wr_ptr_new_r <= {PTR_WD+1{1'b0}};
  end
  else begin
    if (flush) begin
      wr_ptr_new_r <= wr_ptr_r;
    end
    else if (!full && push) begin
      wr_ptr_new_r <= wr_ptr_new_r+1'b1;
    end
  end
end

always @(posedge clk or negedge rst_n)
begin: WR_PTR_R_PROC
  if (!rst_n) begin
    wr_ptr_r <= {PTR_WD+1{1'b0}};
  end
  else if (wr_ptr_upd) begin
    wr_ptr_r <= wr_ptr_new_r;
  end
end


always @(posedge clk or negedge rst_n)
begin: LEVEL_R_PROC
  if (!rst_n) begin
    level_r <= {PTR_WD{1'b0}};
  end
  else begin
    if (push && !pop) begin
      level_r <= level_r+1'b1;
    end
    else if (pop && !push) begin
      level_r <= level_r-1'b1;
    end
  end
end

endmodule
module fifo_synch
#(
  parameter DATA_WD = 8,
  parameter PTR_WD = 6
)
(
  input clk,
  input rst_n,
  input [DATA_WD-1:0] data_in,
  input wr_ptr_upd,
  input flush,
  output [PTR_WD-1:0] level,
  input push,
  output pop,
  output [DATA_WD-1:0] data_out,
  output full,
  output empty
);


localparam FIFO_DEPTH = 1 << PTR_WD;

reg [DATA_WD-1:0] fifo_r [FIFO_DEPTH-1:0];
reg [PTR_WD:0] rd_ptr_r;
reg [PTR_WD:0] wr_ptr_r;
reg [PTR_WD:0] wr_ptr_new_r;
reg [PTR_WD-1:0] level_r;
wire full_bit;

assign level = level_r;


assign full_bit = wr_ptr_r[PTR_WD] ^ rd_ptr_r[PTR_WD];
assign full = full_bit && (wr_ptr_r[PTR_WD-1:0] == rd_ptr_r[PTR_WD-1:0]);
assign empty = (wr_ptr_r == rd_ptr_r) ? 1'b1 : 1'b0;


assign data_out = fifo_r[rd_ptr_r[PTR_WD-1:0]];

always @(posedge clk)
begin: FIFO_R_PROC
  if (push) begin
    fifo_r[wr_ptr_new_r[PTR_WD-1:0]] <= data_in;
  end
end


always @(posedge clk or negedge rst_n)
begin: RD_POINTER_R_PROC
  if (!rst_n) begin
    rd_ptr_r <= {PTR_WD+1{1'b0}};
  end
  else if (!empty && pop) begin
    rd_ptr_r <= rd_ptr_r+1'b1;
  end
end


always @(posedge clk or negedge rst_n)
begin: WR_PTR_NEW_R_PROC
  if (!rst_n) begin
    wr_ptr_new_r <= {PTR_WD+1{1'b0}};
  end
  else begin
    if (flush) begin
      wr_ptr_new_r <= wr_ptr_r;
    end
    else if (!full && push) begin
      wr_ptr_new_r <= wr_ptr_new_r+1'b1;
    end
  end
end

always @(posedge clk or negedge rst_n)
begin: WR_PTR_R_PROC
  if (!rst_n) begin
    wr_ptr_r <= {PTR_WD+1{1'b0}};
  end
  else if (wr_ptr_upd) begin
    wr_ptr_r <= wr_ptr_new_r;
  end
end


always @(posedge clk or negedge rst_n)
begin: LEVEL_R_PROC
  if (!rst_n) begin
    level_r <= {PTR_WD{1'b0}};
  end
  else begin
    if (push && !pop) begin
      level_r <= level_r+1'b1;
    end
    else if (pop && !push) begin
      level_r <= level_r-1'b1;
    end
  end
end

endmodule