OpenCores
URL https://opencores.org/ocsvn/srdydrdy_lib/srdydrdy_lib/trunk

Subversion Repositories srdydrdy_lib

[/] [srdydrdy_lib/] [trunk/] [rtl/] [verilog/] [buffers/] [sd_fifo_tail_b.v] - Diff between revs 19 and 22

Only display areas with differences | Details | Blame | View Log

Rev 19 Rev 22
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Srdy/Drdy FIFO Tail "B"
// Srdy/Drdy FIFO Tail "B"
//
//
// Building block for FIFOs.  The "B" (big) FIFO is design for larger FIFOs
// Building block for FIFOs.  The "B" (big) FIFO is design for larger FIFOs
// based around memories, with sizes that may not be a power of 2.
// based around memories, with sizes that may not be a power of 2.
//
//
// The bound inputs allow multiple FIFO controllers to share a single
// The bound inputs allow multiple FIFO controllers to share a single
// memory.  The enable input is for arbitration between multiple FIFO
// memory.  The enable input is for arbitration between multiple FIFO
// controllers, or between the fifo head and tail controllers on a
// controllers, or between the fifo head and tail controllers on a
// single port memory.
// single port memory.
//
//
// The commit parameter enables read/commit behavior.  This creates
// The commit parameter enables read/commit behavior.  This creates
// two read pointers, one which is used for reading from memory and
// two read pointers, one which is used for reading from memory and
// a commit pointer which is sent to the head block.  The abort behavior
// a commit pointer which is sent to the head block.  The abort behavior
// has a 3-cycle performance penalty due to pipeline flush.
// has a 3-cycle performance penalty due to pipeline flush.
//
//
// The FIFO tail assumes a memory with one-cycle read latency, and
// The FIFO tail assumes a memory with one-cycle read latency, and
// has output buffering to compensate for this.
// has output buffering to compensate for this.
//
//
// Naming convention: c = consumer, p = producer, i = internal interface
// Naming convention: c = consumer, p = producer, i = internal interface
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Author: Guy Hutchison
// Author: Guy Hutchison
//
//
// This block is uncopyrighted and released into the public domain.
// This block is uncopyrighted and released into the public domain.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
 
 
// Clocking statement for synchronous blocks.  Default is for
// Clocking statement for synchronous blocks.  Default is for
// posedge clocking and positive async reset
// posedge clocking and positive async reset
`ifndef SDLIB_CLOCKING
`ifndef SDLIB_CLOCKING
 `define SDLIB_CLOCKING posedge clk or posedge reset
 `define SDLIB_CLOCKING posedge clk or posedge reset
`endif
`endif
 
 
// delay unit for nonblocking assigns, default is to #1
// delay unit for nonblocking assigns, default is to #1
`ifndef SDLIB_DELAY
`ifndef SDLIB_DELAY
 `define SDLIB_DELAY #1
 `define SDLIB_DELAY #1
`endif
`endif
 
 
 
 
module sd_fifo_tail_b
module sd_fifo_tail_b
  #(parameter width=8,
  #(parameter width=8,
    parameter depth=16,
    parameter depth=16,
    parameter commit=0,
    parameter commit=0,
    parameter asz=$clog2(depth),
    parameter asz=$clog2(depth),
    parameter usz=$clog2(depth+1)
    parameter usz=$clog2(depth+1)
    )
    )
    (
    (
     input       clk,
     input       clk,
     input       reset,
     input       reset,
     input       enable,
     input       enable,
 
 
     input [asz-1:0]      bound_low,
     input [asz-1:0]      bound_low,
     input [asz-1:0]      bound_high,
     input [asz-1:0]      bound_high,
 
 
     output reg [asz-1:0]   cur_rdptr,
     output reg [asz-1:0]   cur_rdptr,
     output reg [asz-1:0]   com_rdptr,
     output reg [asz-1:0]   com_rdptr,
     input  [asz-1:0]       wrptr,
     input  [asz-1:0]       wrptr,
     output reg           mem_re,
     output reg           mem_re,
     input                mem_we,
     input                mem_we,
 
 
     output reg [usz-1:0] p_usage,
     output reg [usz-1:0] p_usage,
 
 
     output               p_srdy,
     output               p_srdy,
     input                p_drdy,
     input                p_drdy,
     input                p_commit,
     input                p_commit,
     input                p_abort,
     input                p_abort,
     input [width-1:0]    mem_rd_data,
     input [width-1:0]    mem_rd_data,
     output [width-1:0]   p_data
     output [width-1:0]   p_data
     );
     );
 
 
  reg [asz-1:0]           nxt_cur_rdptr;
  reg [asz-1:0]           nxt_cur_rdptr;
  reg [asz-1:0]           cur_rdptr_p1;
  reg [asz-1:0]           cur_rdptr_p1;
  reg                   empty, full;
  reg                   empty, full;
 
 
  reg                   nxt_irdy;
  reg                   nxt_irdy;
 
 
  reg [width-1:0]       hold_a, hold_b;
  reg [width-1:0]       hold_a, hold_b;
  reg                   valid_a, valid_b;
  reg                   valid_a, valid_b;
  reg                   prev_re;
  reg                   prev_re;
  reg [usz:0]           tmp_usage;
  reg [usz:0]           tmp_usage;
  reg [usz:0]           fifo_size;
  reg [usz:0]           fifo_size;
  wire                  rbuf1_drdy;
  wire                  rbuf1_drdy;
  wire                  ip_srdy, ip_drdy;
  wire                  ip_srdy, ip_drdy;
  wire [width-1:0]       ip_data;
  wire [width-1:0]       ip_data;
 
 
  // Stage 1 -- Read pipeline
  // Stage 1 -- Read pipeline
  // issue a read if:
  // issue a read if:
  //   1) we are enabled
  //   1) we are enabled
  //   2) valid_a is 0, OR
  //   2) valid_a is 0, OR
  //   3) valid_b is 0, OR
  //   3) valid_b is 0, OR
  //   4) valid_a && valid_b && trdy
  //   4) valid_a && valid_b && trdy
  always @*
  always @*
    begin
    begin
 
 
      if (cur_rdptr[asz-1:0] == (bound_high))
      if (cur_rdptr[asz-1:0] == (bound_high))
        begin
        begin
          cur_rdptr_p1[asz-1:0] = bound_low;
          cur_rdptr_p1[asz-1:0] = bound_low;
        end
        end
      else
      else
        cur_rdptr_p1 = cur_rdptr + 1;
        cur_rdptr_p1 = cur_rdptr + 1;
 
 
      empty = (wrptr == cur_rdptr);
      empty = (wrptr == cur_rdptr);
 
 
      if (commit && p_abort)
      if (commit && p_abort)
        begin
        begin
          nxt_cur_rdptr = com_rdptr;
          nxt_cur_rdptr = com_rdptr;
          mem_re = 0;
          mem_re = 0;
        end
        end
      else if (enable & !empty & ip_drdy)
      else if (enable & !empty & (ip_drdy | (rbuf1_drdy & !prev_re)))
        begin
        begin
          nxt_cur_rdptr = cur_rdptr_p1;
          nxt_cur_rdptr = cur_rdptr_p1;
          mem_re = 1;
          mem_re = 1;
        end
        end
      else
      else
        begin
        begin
          nxt_cur_rdptr = cur_rdptr;
          nxt_cur_rdptr = cur_rdptr;
          mem_re = 0;
          mem_re = 0;
        end // else: !if(enable & !empty & (!valid_a | !valid_b |...
        end // else: !if(enable & !empty & (!valid_a | !valid_b |...
 
 
      fifo_size = (bound_high - bound_low + 1);
      fifo_size = (bound_high - bound_low + 1);
      tmp_usage = wrptr[asz-1:0] - cur_rdptr[asz-1:0];
      tmp_usage = wrptr[asz-1:0] - cur_rdptr[asz-1:0];
      if (~tmp_usage[usz])
      if (~tmp_usage[usz])
        p_usage = tmp_usage[usz-1:0];
        p_usage = tmp_usage[usz-1:0];
      else
      else
        p_usage = fifo_size - (cur_rdptr[asz-1:0] - wrptr[asz-1:0]);
        p_usage = fifo_size - (cur_rdptr[asz-1:0] - wrptr[asz-1:0]);
    end // always @ *
    end // always @ *
 
 
  always @(posedge clk)
  always @(posedge clk)
    begin
    begin
      if (reset)
      if (reset)
        cur_rdptr <= `SDLIB_DELAY bound_low;
        cur_rdptr <= `SDLIB_DELAY bound_low;
      else
      else
        cur_rdptr <= `SDLIB_DELAY nxt_cur_rdptr;
        cur_rdptr <= `SDLIB_DELAY nxt_cur_rdptr;
    end
    end
 
 
  reg [asz-1:0]  rdaddr_s0, rdaddr_a, rdaddr_b;
  reg [asz-1:0]  rdaddr_s0, rdaddr_a, rdaddr_b;
  reg [asz-1:0]  nxt_com_rdptr;
  reg [asz-1:0]  nxt_com_rdptr;
  generate
  generate
    if (commit == 1)
    if (commit == 1)
      begin : gen_s0
      begin : gen_s0
 
 
        always @(posedge clk)
        always @(posedge clk)
          begin
          begin
            if (reset)
            if (reset)
              com_rdptr <= `SDLIB_DELAY bound_low;
              com_rdptr <= `SDLIB_DELAY bound_low;
            else
            else
              com_rdptr <= `SDLIB_DELAY nxt_com_rdptr;
              com_rdptr <= `SDLIB_DELAY nxt_com_rdptr;
 
 
            if (mem_re)
            if (mem_re)
              rdaddr_s0 <= `SDLIB_DELAY cur_rdptr;
              rdaddr_s0 <= `SDLIB_DELAY cur_rdptr;
          end
          end
      end
      end
    else
    else
      begin : gen_ns0
      begin : gen_ns0
        always @*
        always @*
          com_rdptr = cur_rdptr;
          com_rdptr = cur_rdptr;
      end
      end
  endgenerate
  endgenerate
 
 
  // Stage 2 -- read buffering
  // Stage 2 -- read buffering
  always @(`SDLIB_CLOCKING)
  always @(`SDLIB_CLOCKING)
    begin
    begin
      if (reset)
      if (reset)
        begin
        begin
          prev_re <= `SDLIB_DELAY 0;
          prev_re <= `SDLIB_DELAY 0;
        end
        end
      else
      else
        begin
        begin
          if (commit && p_abort)
          if (commit && p_abort)
            prev_re <= `SDLIB_DELAY 0;
            prev_re <= `SDLIB_DELAY 0;
          else
          else
            prev_re <= `SDLIB_DELAY mem_re;
            prev_re <= `SDLIB_DELAY mem_re;
        end // else: !if(reset)
        end // else: !if(reset)
    end // always @ (`SDLIB_CLOCKING)
    end // always @ (`SDLIB_CLOCKING)
 
 
  generate
  generate
    if (commit == 1)
    if (commit == 1)
      begin : gen_s2
      begin : gen_s2
        wire [asz-1:0] ip_rdaddr, p_rdaddr;
        wire [asz-1:0] ip_rdaddr, p_rdaddr;
 
 
        sd_input #(asz+width) rbuf1
        sd_input #(asz+width) rbuf1
          (.clk (clk), .reset (p_abort | reset),
          (.clk (clk), .reset (p_abort | reset),
           .c_srdy (prev_re),
           .c_srdy (prev_re),
           .c_drdy (rbuf1_drdy),
           .c_drdy (rbuf1_drdy),
           .c_data ({rdaddr_s0,mem_rd_data}),
           .c_data ({rdaddr_s0,mem_rd_data}),
           .ip_srdy (ip_srdy), .ip_drdy (ip_drdy),
           .ip_srdy (ip_srdy), .ip_drdy (ip_drdy),
           .ip_data ({ip_rdaddr,ip_data}));
           .ip_data ({ip_rdaddr,ip_data}));
 
 
        sd_output #(asz+width) rbuf2
        sd_output #(asz+width) rbuf2
          (.clk (clk), .reset (p_abort | reset),
          (.clk (clk), .reset (p_abort | reset),
           .ic_srdy (ip_srdy),
           .ic_srdy (ip_srdy),
           .ic_drdy (ip_drdy),
           .ic_drdy (ip_drdy),
           .ic_data ({ip_rdaddr,ip_data}),
           .ic_data ({ip_rdaddr,ip_data}),
           .p_srdy (p_srdy), .p_drdy (p_drdy),
           .p_srdy (p_srdy), .p_drdy (p_drdy),
           .p_data ({p_rdaddr,p_data}));
           .p_data ({p_rdaddr,p_data}));
 
 
        always @*
        always @*
          begin
          begin
            if (p_commit & p_srdy & p_drdy)
            if (p_commit & p_srdy & p_drdy)
              nxt_com_rdptr = p_rdaddr;
              nxt_com_rdptr = p_rdaddr;
            else
            else
              nxt_com_rdptr = com_rdptr;
              nxt_com_rdptr = com_rdptr;
          end
          end
      end // if (commit == 1)
      end // if (commit == 1)
    else
    else
      begin : gen_ns2
      begin : gen_ns2
        sd_input #(width) rbuf1
        sd_input #(width) rbuf1
          (.clk (clk), .reset (p_abort | reset),
          (.clk (clk), .reset (p_abort | reset),
           .c_srdy (prev_re),
           .c_srdy (prev_re),
           .c_drdy (rbuf1_drdy),
           .c_drdy (rbuf1_drdy),
           .c_data (mem_rd_data),
           .c_data (mem_rd_data),
           .ip_srdy (ip_srdy), .ip_drdy (ip_drdy),
           .ip_srdy (ip_srdy), .ip_drdy (ip_drdy),
           .ip_data (ip_data));
           .ip_data (ip_data));
 
 
        sd_output #(width) rbuf2
        sd_output #(width) rbuf2
          (.clk (clk), .reset (p_abort | reset),
          (.clk (clk), .reset (p_abort | reset),
           .ic_srdy (ip_srdy),
           .ic_srdy (ip_srdy),
           .ic_drdy (ip_drdy),
           .ic_drdy (ip_drdy),
           .ic_data (ip_data),
           .ic_data (ip_data),
           .p_srdy (p_srdy), .p_drdy (p_drdy),
           .p_srdy (p_srdy), .p_drdy (p_drdy),
           .p_data (p_data));
           .p_data (p_data));
      end // else: !if(commit == 1)
      end // else: !if(commit == 1)
  endgenerate
  endgenerate
 
 
endmodule // it_fifo
endmodule // it_fifo
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.