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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_3/] [rtl/] [verilog/] [fifo_control.v] - Diff between revs 21 and 33

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 21 Rev 33
Line 40... Line 40...
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//
// CVS Revision History
// CVS Revision History
//
//
// $Log: not supported by cvs2svn $
// $Log: not supported by cvs2svn $
 
// Revision 1.3  2002/02/01 15:25:12  mihad
 
// Repaired a few bugs, updated specification, added test bench files and design document
 
//
// Revision 1.2  2001/10/05 08:14:28  mihad
// Revision 1.2  2001/10/05 08:14:28  mihad
// Updated all files with inclusion of timescale file for simulation purposes.
// Updated all files with inclusion of timescale file for simulation purposes.
//
//
// Revision 1.1.1.1  2001/10/02 15:33:46  mihad
// Revision 1.1.1.1  2001/10/02 15:33:46  mihad
// New project directory structure
// New project directory structure
Line 65... Line 68...
    wclock_in,
    wclock_in,
    renable_in,
    renable_in,
    wenable_in,
    wenable_in,
    reset_in,
    reset_in,
    flush_in,
    flush_in,
    almost_full_out,
 
    full_out,
    full_out,
    almost_empty_out,
    almost_empty_out,
    empty_out,
    empty_out,
    waddr_out,
    waddr_out,
    raddr_out,
    raddr_out,
Line 91... Line 93...
input  reset_in;
input  reset_in;
 
 
// flush input
// flush input
input flush_in ;
input flush_in ;
 
 
// almost full and empy status outputs
// almost empy status output
output almost_full_out, almost_empty_out;
output almost_empty_out;
 
 
// full and empty status outputs
// full and empty status outputs
output full_out, empty_out;
output full_out, empty_out;
 
 
// read and write addresses outputs
// read and write addresses outputs
Line 120... Line 122...
 
 
// next write gray address calculation - bitwise xor between address and shifted address
// next write gray address calculation - bitwise xor between address and shifted address
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next  = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ;
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next  = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ;
 
 
// grey code pipeline for read address
// grey code pipeline for read address
reg [(ADDR_LENGTH - 1):0] rgrey_minus2 ; // two before current
 
reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current
reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current
reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next
reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next
 
 
// next read gray address calculation - bitwise xor between address and shifted address
// next read gray address calculation - bitwise xor between address and shifted address
Line 132... Line 133...
 
 
// FFs for registered empty and full flags
// FFs for registered empty and full flags
reg empty ;
reg empty ;
reg full ;
reg full ;
 
 
// almost_empty and almost_full tag - implemented as latches
// almost_empty tag
reg almost_empty ;
reg almost_empty ;
reg almost_full ;
 
 
 
// write allow wire - writes are allowed when fifo is not full
// write allow wire - writes are allowed when fifo is not full
wire wallow = wenable_in && ~full ;
wire wallow = wenable_in && ~full ;
 
 
// write allow output assignment
// write allow output assignment
Line 148... Line 148...
wire rallow ;
wire rallow ;
 
 
// full output assignment
// full output assignment
assign full_out  = full ;
assign full_out  = full ;
 
 
// almost full output assignment
 
assign almost_full_out  = almost_full && ~full ;
 
 
 
// clear generation for FFs and registers
// clear generation for FFs and registers
wire clear = reset_in || flush_in ;
wire clear = reset_in || flush_in ;
 
 
reg wclock_nempty_detect ;
reg wclock_nempty_detect ;
always@(posedge reset_in or posedge wclock_in)
always@(posedge reset_in or posedge wclock_in)
Line 197... Line 194...
 
 
always@(posedge rclock_in or posedge clear)
always@(posedge rclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        // initial value is 5 - one more than initial value of read address
        // initial value is 4 - one more than initial value of read address
        raddr_plus_one <= #`FF_DELAY 5 ;
        raddr_plus_one <= #`FF_DELAY 4 ;
    end
    end
    else if (rallow)
    else if (rallow)
        raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ;
        raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ;
end
end
 
 
// raddr is filled with raddr_plus_one on rising read clock edge when rallow is high
// raddr is filled with raddr_plus_one on rising read clock edge when rallow is high
always@(posedge rclock_in or posedge clear)
always@(posedge rclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
        // initial value is 4
        // initial value is 3
        raddr <= #`FF_DELAY 4 ;
        raddr <= #`FF_DELAY 3 ;
    else if (rallow)
    else if (rallow)
        raddr <= #`FF_DELAY raddr_plus_one ;
        raddr <= #`FF_DELAY raddr_plus_one ;
end
end
 
 
/*-----------------------------------------------------------------------------------------------
/*-----------------------------------------------------------------------------------------------
Read address control consists of Read address counter and Grey Address pipeline
Read address control consists of Read address counter and Grey Address pipeline
There are 4 Grey addresses:
There are 4 Grey addresses:
    - rgrey_minus2 is Grey Code of address two before current address
 
    - rgrey_minus1 is Grey Code of address one before current address
    - rgrey_minus1 is Grey Code of address one before current address
    - rgrey_addr is Grey Code of current read address
    - rgrey_addr is Grey Code of current read address
    - rgrey_next is Grey Code of next read address
    - rgrey_next is Grey Code of next read address
--------------------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------------------------*/
// grey code register for two before read address
 
always@(posedge rclock_in or posedge clear)
 
begin
 
    if (clear)
 
    begin
 
        // initial value is 0
 
        rgrey_minus2 <= #`FF_DELAY 0 ;
 
    end
 
    else
 
    if (rallow)
 
        rgrey_minus2 <= #`FF_DELAY rgrey_minus1 ;
 
end
 
 
 
// grey code register for one before read address
// grey code register for one before read address
always@(posedge rclock_in or posedge clear)
always@(posedge rclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        // initial value is 1
        // initial value is 0
        rgrey_minus1 <= #`FF_DELAY 1 ;
        rgrey_minus1 <= #`FF_DELAY 0 ;
    end
    end
    else
    else
    if (rallow)
    if (rallow)
        rgrey_minus1 <= #`FF_DELAY rgrey_addr ;
        rgrey_minus1 <= #`FF_DELAY rgrey_addr ;
end
end
Line 253... Line 237...
// grey code register for read address - represents current Read Address
// grey code register for read address - represents current Read Address
always@(posedge rclock_in or posedge clear)
always@(posedge rclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        // initial value is 3
        // initial value is 1
        rgrey_addr <= #`FF_DELAY 3 ;
        rgrey_addr <= #`FF_DELAY 1 ;
    end
    end
    else
    else
    if (rallow)
    if (rallow)
        rgrey_addr <= #`FF_DELAY rgrey_next ;
        rgrey_addr <= #`FF_DELAY rgrey_next ;
end
end
Line 266... Line 250...
// grey code register for next read address - represents Grey Code of next read address
// grey code register for next read address - represents Grey Code of next read address
always@(posedge rclock_in or posedge clear)
always@(posedge rclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        // initial value is 2
        // initial value is 3
        rgrey_next <= #`FF_DELAY 2 ;
        rgrey_next <= #`FF_DELAY 3 ;
    end
    end
    else
    else
    if (rallow)
    if (rallow)
        rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ;
        rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ;
end
end
Line 285... Line 269...
// grey code register for one before write address
// grey code register for one before write address
always@(posedge wclock_in or posedge clear)
always@(posedge wclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        // initial value is 1
        // initial value is 0
        wgrey_minus1 <= #`FF_DELAY 1 ;
        wgrey_minus1 <= #`FF_DELAY 0 ;
    end
    end
    else
    else
    if (wallow)
    if (wallow)
        wgrey_minus1 <= #`FF_DELAY wgrey_addr ;
        wgrey_minus1 <= #`FF_DELAY wgrey_addr ;
end
end
Line 298... Line 282...
// grey code register for write address
// grey code register for write address
always@(posedge wclock_in or posedge clear)
always@(posedge wclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        // initial value is 3
        // initial value is 1
        wgrey_addr <= #`FF_DELAY 3 ;
        wgrey_addr <= #`FF_DELAY 1 ;
    end
    end
    else
    else
    if (wallow)
    if (wallow)
        wgrey_addr <= #`FF_DELAY wgrey_next ;
        wgrey_addr <= #`FF_DELAY wgrey_next ;
end
end
Line 311... Line 295...
// grey code register for next write address
// grey code register for next write address
always@(posedge wclock_in or posedge clear)
always@(posedge wclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        // initial value is 2
        // initial value is 3
        wgrey_next <= #`FF_DELAY 2 ;
        wgrey_next <= #`FF_DELAY 3 ;
    end
    end
    else
    else
    if (wallow)
    if (wallow)
        wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
        wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
end
end
 
 
// write address counter - nothing special except initial value
// write address counter - nothing special except initial value
always@(posedge wclock_in or posedge clear)
always@(posedge wclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
        // initial value 4
        // initial value 3
        waddr <= #`FF_DELAY 4 ;
        waddr <= #`FF_DELAY 3 ;
    else
    else
    if (wallow)
    if (wallow)
        waddr <= #`FF_DELAY waddr + 1'b1 ;
        waddr <= #`FF_DELAY waddr + 1'b1 ;
end
end
 
 
Line 340... Line 324...
Registered almost full control:
Registered almost full control:
Almost full flag is set on rising write clock edge whenever two free locations are left in fifo and another entry is written to it.
Almost full flag is set on rising write clock edge whenever two free locations are left in fifo and another entry is written to it.
It remains set if nothing is read/written from/to fifo. All operations are synchronized on write clock.
It remains set if nothing is read/written from/to fifo. All operations are synchronized on write clock.
--------------------------------------------------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------------------------------------------------------*/
wire comb_full          = wgrey_next == rgrey_addr ;
wire comb_full          = wgrey_next == rgrey_addr ;
wire comb_almost_full   = wgrey_addr == rgrey_minus2 ;
wire comb_almost_full   = wgrey_next == rgrey_minus1 ;
wire comb_two_left      = wgrey_next == rgrey_minus2 ;
 
 
 
//combinatorial input to Registered full FlipFlop
//combinatorial input to Registered full FlipFlop
wire reg_full = (wallow && comb_almost_full) || (comb_full) ;
wire reg_full = (wallow && comb_almost_full) || (comb_full) ;
 
 
always@(posedge wclock_in or posedge clear)
always@(posedge wclock_in or posedge clear)
Line 354... Line 337...
        full <= #`FF_DELAY 1'b0 ;
        full <= #`FF_DELAY 1'b0 ;
    else
    else
        full <= #`FF_DELAY reg_full ;
        full <= #`FF_DELAY reg_full ;
end
end
 
 
// input for almost full flip flop
 
wire reg_almost_full_in = wallow && comb_two_left || comb_almost_full ;
 
 
 
always@(posedge clear or posedge wclock_in)
 
begin
 
    if (clear)
 
        almost_full <= #`FF_DELAY 1'b0 ;
 
    else
 
        almost_full <= #`FF_DELAY reg_almost_full_in ;
 
end
 
 
 
/*------------------------------------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------------------------------------------------------------------
Registered empty control:
Registered empty control:
registered empty is set on rising edge of rclock_in when one location is occupied and read from it. It remains set until
registered empty is set on rising edge of rclock_in when one location is occupied and read from it. It remains set until
something is written to fifo which is detected on next read clock edge.
something is written to fifo which is detected on next read clock edge.
 
 

powered by: WebSVN 2.1.0

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