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

Subversion Repositories wiegand_ctl

[/] [wiegand_ctl/] [trunk/] [rtl/] [verilog/] [fifos.v] - Rev 15

Compare with Previous | Blame | View Log

//////////////////////////////////////////////////////////////////////
////                                                              ////
////  fifos.v                                                     ////
////                                                              ////
////                                                              ////
////  This file is part of the Wiegand Protocol Controller        ////
////  http://www.opencores.org/projects/wiegand/                  ////
////                                                              ////
////                                                              ////
////  Author(s):                                                  ////
////       Jeff Anderson                                          ////
////       jeaander@opencores.org                                 ////
////                                                              ////
////                                                              ////
////  All additional information is available in the README.txt   ////
////  file.                                                       ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// Copyright (C) 2013 Authors                                   ////
////                                                              ////
//// This source file may be used and distributed without         ////
//// restriction provided that this copyright statement is not    ////
//// removed from the file and that any derivative work contains  ////
//// the original copyright notice and the associated disclaimer. ////
////                                                              ////
//// This source file is free software; you can redistribute it   ////
//// and/or modify it under the terms of the GNU Lesser General   ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any   ////
//// later version.                                               ////
////                                                              ////
//// This source is distributed in the hope that it will be       ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
//// PURPOSE.  See the GNU Lesser General Public License for more ////
//// details.                                                     ////
////                                                              ////
//// You should have received a copy of the GNU Lesser General    ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//
//  Revisions at end of file
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "wiegand_defines.v"
 
//pulling in data bus width from WIEGAND_defines file
`ifdef WIEGAND_WIDTH64
  `define WIEGAND_FIFODATAWIDTH 64
`elsif WIEGAND_WIDTH32
  `define WIEGAND_FIFODATAWIDTH 32
`elsif WIEGAND_WIDTH16
  `define WIEGAND_FIFODATAWIDTH 16
`else
  `define WIEGAND_FIFODATAWIDTH 8
`endif
 
//define depth of FIFO; pulling in depth from WIEGAND_defines
//`define WIEGAND_FIFODEPTH 16
 
//uncomment a single implementation of FIFO; pulling in implementation from WIEGAND_defines
//`define WIEGAND_CUSTOMFIFO
 
module fifo_wieg
( 
  clk_rd,
  clk_wr,
  d_i,
  d_o,
  rst,
  wr_en,
  rd_en,
  full,
  empty
);
  input clk_rd;
  input clk_wr;
  input [`WIEGAND_FIFODATAWIDTH-1:0] d_i;
  output [`WIEGAND_FIFODATAWIDTH-1:0] d_o;
  input rst;
  input wr_en;
  input rd_en;
  output full;
  output empty;
 
`ifdef WIEGAND_CUSTOMFIFO
  `ifdef WIEGAND_WIDTH64
    wire [7:0] full_int;
    wire [7:0] empty_int;
    assign full = |full_int;
    assign empty = |empty_int;
    custom_fifo_dp custom_fifo_dp1(clk_rd,clk_wr,d_i[63:56],d_o[63:56],rst,wr_en,rd_en,full_int[0],empty_int[0]);
    custom_fifo_dp custom_fifo_dp2(clk_rd,clk_wr,d_i[55:48],d_o[55:48],rst,wr_en,rd_en,full_int[1],empty_int[1]);
    custom_fifo_dp custom_fifo_dp3(clk_rd,clk_wr,d_i[47:40],d_o[47:40],rst,wr_en,rd_en,full_int[2],empty_int[2]);
    custom_fifo_dp custom_fifo_dp4(clk_rd,clk_wr,d_i[39:32],d_o[39:32],rst,wr_en,rd_en,full_int[3],empty_int[3]);
    custom_fifo_dp custom_fifo_dp5(clk_rd,clk_wr,d_i[31:24],d_o[31:24],rst,wr_en,rd_en,full_int[4],empty_int[4]);
    custom_fifo_dp custom_fifo_dp6(clk_rd,clk_wr,d_i[23:16],d_o[23:16],rst,wr_en,rd_en,full_int[5],empty_int[5]);
    custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full_int[6],empty_int[6]);
    custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full_int[7],empty_int[7]);
  `elsif WIEGAND_WIDTH32
    wire [3:0] full_int;
    wire [3:0] empty_int;
    assign full = |full_int;
    assign empty = |empty_int;
    custom_fifo_dp custom_fifo_dp5(clk_rd,clk_wr,d_i[31:24],d_o[31:24],rst,wr_en,rd_en,full_int[0],empty_int[0]);
    custom_fifo_dp custom_fifo_dp6(clk_rd,clk_wr,d_i[23:16],d_o[23:16],rst,wr_en,rd_en,full_int[1],empty_int[1]);
    custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full_int[2],empty_int[2]);
    custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full_int[3],empty_int[3]);
  `elsif WIEGAND_WIDTH16
    wire [1:0] full_int;
    wire [1:0] empty_int;
    assign full = |full_int;
    assign empty = |empty_int;
    custom_fifo_dp custom_fifo_dp7(clk_rd,clk_wr,d_i[15:8],d_o[15:8],rst,wr_en,rd_en,full_int[0],empty_int[0]);
    custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full_int[1],empty_int[1]);
  `else
    custom_fifo_dp custom_fifo_dp8(clk_rd,clk_wr,d_i[7:0],d_o[7:0],rst,wr_en,rd_en,full,empty);
  `endif
`endif 
 
endmodule
 
module custom_fifo_dp (
  clk_rd,
  clk_wr,
  d_i,
  d_o,
  rst,
  wr_en,
  rd_en,
  full,
  empty
);
  input clk_rd;
  input clk_wr;
  input [7:0] d_i;
  output [7:0] d_o;
  input rst;
  input wr_en;
  input rd_en;
  output full;
  output empty;
 
  reg [`WIEGAND_FIFODEPTH-1:0] addr_rd;
  reg [`WIEGAND_FIFODEPTH-1:0] addr_wr;
  reg [7:0] fifo_out;
  wire [7:0] mem_byte_out;
  wire [`WIEGAND_FIFODEPTH-1:0] full_int;
 
  //bytewide memory array in FIFO.  user sets depth.
  genvar c;
  generate
    for (c = 0; c < `WIEGAND_FIFODEPTH; c = c + 1) begin: mem
      mem_byte mem_byte(rst,clk_wr,d_i,mem_byte_out,addr_wr[c],addr_rd[c]);
    end
  endgenerate
 
  //read logic needed here to handle clock domain change
  assign d_o = fifo_out;
  always @(posedge clk_rd or posedge rst) begin
    if (rst)  fifo_out <= 8'h0;
    else      fifo_out <= mem_byte_out;
  end
 
  //addressing logic is simply a circular shift register that gets reset to 1
  always @(posedge clk_wr or posedge rst) begin
    if (rst)  addr_wr <= `WIEGAND_FIFODEPTH'h1;
    else if (wr_en&(~full)) begin
      addr_wr[`WIEGAND_FIFODEPTH-1:1] <= addr_wr[`WIEGAND_FIFODEPTH-2:0];
      addr_wr[0] <= addr_wr[`WIEGAND_FIFODEPTH-1];
    end
  end
 
  always @(posedge clk_rd or posedge rst) begin
    if (rst)  addr_rd <= `WIEGAND_FIFODEPTH'h1;
    else if (rd_en&(~empty)) begin
      addr_rd[`WIEGAND_FIFODEPTH-1:1] <= addr_rd[`WIEGAND_FIFODEPTH-2:0];
      addr_rd[0] <= addr_rd[`WIEGAND_FIFODEPTH-1];
    end
  end
 
  //use address logic for flags
  assign empty = (addr_wr == addr_rd);              //when read addr catches write addr, we're empty
 
  assign full = empty?1'b0:|full_int;              //if fifo isn't empty, then OR all full flag outputs
 
  assign full_int[0] = (addr_wr[`WIEGAND_FIFODEPTH-1] & addr_rd[0]);  //when we've written to entire mem, we're full
  genvar d;
  generate
    for (d = 1; d < `WIEGAND_FIFODEPTH; d = d + 1) begin: flag
      assign full_int[d] = (addr_wr[d-1] & addr_rd[d]);   //when we've written to entire mem, we're full
    end
  endgenerate
 
endmodule
 
module mem_byte(
  rst,
  clk,
  din,
  dout,
  wen,
  ren
);
 
  input rst;
  input clk;
  input[7:0] din;
  output [7:0] dout;
  input wen;
  input ren;
 
  reg[7:0] byte_reg;
 
  //just a byte-wide register with input and output enables
  assign dout = ren?byte_reg:8'bz;
 
  always @(posedge clk or posedge rst) begin
    if (rst)        byte_reg <= 8'h0;
    else if (wen)   byte_reg <= din;
  end
 
endmodule
 
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: $
//

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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