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 11 and 13

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 11 Rev 13
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// 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))
    (
    (
     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,
 
 
     output reg [asz:0]   usage,
     output reg [asz:0]   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 [asz:0]           tmp_usage;
  reg [asz:0]           tmp_usage;
  reg [asz:0]           fifo_size;
  reg [asz: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 & (!valid_a | (!prev_re & !valid_b) | 
//      else if (enable & !empty & (!valid_a | (!prev_re & !valid_b) | 
//                             (valid_a & valid_b & p_drdy)))
//                             (valid_a & valid_b & p_drdy)))
      else if (enable & !empty & ip_drdy)
      else if (enable & !empty & ip_drdy)
        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[asz])
      if (~tmp_usage[asz])
        usage = tmp_usage[asz-1:0];
        usage = tmp_usage[asz-1:0];
      else
      else
        usage = fifo_size - (cur_rdptr[asz-1:0] - wrptr[asz-1:0]);
        usage = fifo_size - (cur_rdptr[asz-1:0] - wrptr[asz-1:0]);
    end
    end // always @ *
 
 
 
/* -----\/----- EXCLUDED -----\/-----
 
  // alternate usage calc
 
  reg [asz-1:0] prev_wr;
 
  reg [asz:0] usage2, nxt_usage2;
 
  wire        lcl_wr_en;
 
  //assign lcl_wr_en = (prev_wr0 != wrptr[0]);
 
 
 
  always @(posedge clk)
 
    begin
 
      if (reset)
 
        begin
 
          /-*AUTORESET*-/
 
          // Beginning of autoreset for uninitialized flops
 
          usage2 <= {(1+(asz)){1'b0}};
 
          // End of automatics
 
        end
 
      else
 
        begin
 
          usage2   <= #1 nxt_usage2;
 
        end
 
    end
 
 
 
  always @*
 
    begin
 
      if (mem_re & !mem_we)
 
        nxt_usage2 = usage2 - 1;
 
      else if (!mem_re & mem_we)
 
        nxt_usage2 = usage2 + 1;
 
      else
 
        nxt_usage2 = usage2;
 
    end
 
 -----/\----- EXCLUDED -----/\----- */
 
 
  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)
            if (p_commit)
              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.