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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_7/] [rtl/] [verilog/] [pci_pciw_fifo_control.v] - Diff between revs 104 and 108

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

Rev 104 Rev 108
Line 40... Line 40...
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//
// CVS Revision History
// CVS Revision History
//
//
// $Log: not supported by cvs2svn $
// $Log: not supported by cvs2svn $
 
// Revision 1.3  2003/07/29 08:20:11  mihad
 
// Found and simulated the problem in the synchronization logic.
 
// Repaired the synchronization logic in the FIFOs.
 
//
//
//
 
 
/* FIFO_CONTROL module provides read/write address and status generation for
/* FIFO_CONTROL module provides read/write address and status generation for
   FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */
   FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */
`include "pci_constants.v"
`include "pci_constants.v"
Line 64... Line 68...
    empty_out,
    empty_out,
    waddr_out,
    waddr_out,
    raddr_out,
    raddr_out,
    rallow_out,
    rallow_out,
    wallow_out,
    wallow_out,
 
    three_left_out,
    two_left_out
    two_left_out
);
);
 
 
parameter ADDR_LENGTH = 7 ;
parameter ADDR_LENGTH = 7 ;
 
 
Line 91... Line 96...
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out;
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out;
 
 
// read and write allow outputs
// read and write allow outputs
output rallow_out, wallow_out ;
output rallow_out, wallow_out ;
 
 
// two locations left output indicator
// three and two locations left output indicator
 
output three_left_out ;
output two_left_out ;
output two_left_out ;
 
 
// read address register
// read address register
reg [(ADDR_LENGTH - 1):0] raddr ;
reg [(ADDR_LENGTH - 1):0] raddr ;
 
 
// write address register
// write address register
reg [(ADDR_LENGTH - 1):0] waddr;
reg [(ADDR_LENGTH - 1):0] waddr;
 
reg [(ADDR_LENGTH - 1):0] waddr_plus1;
assign waddr_out = waddr ;
assign waddr_out = waddr ;
 
 
// grey code registers
// grey code registers
// grey code pipeline for write address
// grey code pipeline for write address
reg [(ADDR_LENGTH - 1):0] wgrey_minus1 ; // previous
reg [(ADDR_LENGTH - 1):0] wgrey_minus1 ; // previous
reg [(ADDR_LENGTH - 1):0] wgrey_addr   ; // current
reg [(ADDR_LENGTH - 1):0] wgrey_addr   ; // current
reg [(ADDR_LENGTH - 1):0] wgrey_next   ; // next
reg [(ADDR_LENGTH - 1):0] wgrey_next   ; // next
 
 
 
reg [(ADDR_LENGTH - 1):0] wgrey_next_plus1   ; // next plus 1
 
 
 
 
// 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] ;
 
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next_plus1  = waddr_plus1[(ADDR_LENGTH - 1):1] ^ waddr_plus1[(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_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
Line 144... Line 155...
    if (clear)
    if (clear)
    begin
    begin
        // initial values seem a bit odd - they are this way to allow easier grey pipeline implementation and to allow min fifo size of 8
        // initial values seem a bit odd - they are this way to allow easier grey pipeline implementation and to allow min fifo size of 8
        raddr_plus_one <= #`FF_DELAY 5 ;
        raddr_plus_one <= #`FF_DELAY 5 ;
        raddr          <= #`FF_DELAY 4 ;
        raddr          <= #`FF_DELAY 4 ;
 
//        raddr_plus_one <= #`FF_DELAY 6 ;
 
//        raddr          <= #`FF_DELAY 5 ;
    end
    end
    else if (rallow_out)
    else if (rallow_out)
    begin
    begin
        raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ;
        raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ;
        raddr          <= #`FF_DELAY raddr_plus_one ;
        raddr          <= #`FF_DELAY raddr_plus_one ;
Line 184... Line 197...
 
 
/*--------------------------------------------------------------------------------------------
/*--------------------------------------------------------------------------------------------
Write address control consists of write address counter and 3 Grey Code Registers:
Write address control consists of write address counter and 3 Grey Code Registers:
    - wgrey_minus1 represents previous Grey coded write address
    - wgrey_minus1 represents previous Grey coded write address
    - wgrey_addr   represents current Grey Coded write address
    - wgrey_addr   represents current Grey Coded write address
    - wgrey_next   represents Grey Coded next write address
    - wgrey_next   represents next Grey Coded write address
 
 
 
    - wgrey_next_plus1 represents second next Grey Coded write address
 
 
----------------------------------------------------------------------------------------------*/
----------------------------------------------------------------------------------------------*/
// grey coded address pipeline for status generation in write clock domain
// grey coded address pipeline for status generation in write clock domain
always@(posedge wclock_in or posedge clear)
always@(posedge wclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        wgrey_minus1 <= #`FF_DELAY 1 ;
        wgrey_minus1 <= #`FF_DELAY 1 ;
        wgrey_addr   <= #1 3 ;
        wgrey_addr   <= #`FF_DELAY 3 ;
        wgrey_next   <= #`FF_DELAY 2 ;
        wgrey_next   <= #`FF_DELAY 2 ;
 
 
 
        wgrey_next_plus1 <= #`FF_DELAY 6;
 
 
    end
    end
    else
    else
    if (wallow_out)
    if (wallow_out)
    begin
    begin
        wgrey_minus1 <= #`FF_DELAY wgrey_addr ;
        wgrey_minus1 <= #`FF_DELAY wgrey_addr ;
        wgrey_addr   <= #1 wgrey_next ;
        wgrey_addr   <= #`FF_DELAY wgrey_next ;
 
 
        wgrey_next   <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
        wgrey_next   <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
 
//        wgrey_next   <= #`FF_DELAY wgrey_next_plus1 ;
 
        wgrey_next_plus1 <= #`FF_DELAY {waddr_plus1[(ADDR_LENGTH - 1)], calc_wgrey_next_plus1} ;
 
 
    end
    end
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)
 
    begin
        // initial value 5
        // initial value 5
 
 
        waddr <= #`FF_DELAY 4 ;
        waddr <= #`FF_DELAY 4 ;
 
        waddr_plus1 <= #`FF_DELAY 5 ;
 
    end
    else
    else
    if (wallow_out)
    if (wallow_out)
 
    begin
        waddr <= #`FF_DELAY waddr + 1'b1 ;
        waddr <= #`FF_DELAY waddr + 1'b1 ;
 
        waddr_plus1 <= #`FF_DELAY waddr_plus1 + 1'b1 ;
 
    end
end
end
 
 
/*------------------------------------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------------------------------------------------------------------
Gray coded address of read address decremented by two is synchronized to write clock domain and compared to:
Gray coded address of read address decremented by two is synchronized to write clock domain and compared to:
- previous grey coded write address - if they are equal, the fifo is full
- previous grey coded write address - if they are equal, the fifo is full
Line 250... Line 280...
 
 
assign full_out        = (wgrey_minus1 == wclk_rgrey_minus2) ;
assign full_out        = (wgrey_minus1 == wclk_rgrey_minus2) ;
assign almost_full_out = (wgrey_addr   == wclk_rgrey_minus2) ;
assign almost_full_out = (wgrey_addr   == wclk_rgrey_minus2) ;
assign two_left_out = (wgrey_next   == wclk_rgrey_minus2) ;
assign two_left_out = (wgrey_next   == wclk_rgrey_minus2) ;
 
 
 
assign three_left_out  = (wgrey_next_plus1 == wclk_rgrey_minus2) ;
 
 
 
 
/*------------------------------------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------------------------------------------------------------------
Empty control:
Empty control:
Gray coded write address pointer is synchronized to read clock domain and compared to Gray coded read address pointer.
Gray coded write address pointer is synchronized to read clock domain and compared to Gray coded read address pointer.
If they are equal, fifo is empty.
If they are equal, fifo is empty.
 
 

powered by: WebSVN 2.1.0

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