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

Subversion Repositories pci

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

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

Rev 88 Rev 104
Line 40... Line 40...
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//
//
// CVS Revision History
// CVS Revision History
//
//
// $Log: not supported by cvs2svn $
// $Log: not supported by cvs2svn $
 
// Revision 1.2  2003/03/26 13:16:18  mihad
 
// Added the reset value parameter to the synchronizer flop module.
 
// Added resets to all synchronizer flop instances.
 
// Repaired initial sync value in fifos.
 
//
// Revision 1.1  2003/01/27 16:49:31  mihad
// Revision 1.1  2003/01/27 16:49:31  mihad
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed.
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed.
//
//
// Revision 1.6  2002/11/27 20:36:13  mihad
// Revision 1.6  2002/11/27 20:36:13  mihad
// Changed the code a bit to make it more readable.
// Changed the code a bit to make it more readable.
Line 79... Line 84...
    rclock_in,
    rclock_in,
    wclock_in,
    wclock_in,
    renable_in,
    renable_in,
    wenable_in,
    wenable_in,
    reset_in,
    reset_in,
//    flush_in, // not used
 
    almost_full_out,
    almost_full_out,
    full_out,
    full_out,
    empty_out,
    empty_out,
    waddr_out,
    waddr_out,
    raddr_out,
    raddr_out,
Line 124... Line 128...
// write address register
// write address register
reg [(ADDR_LENGTH - 1):0] waddr;
reg [(ADDR_LENGTH - 1):0] waddr;
assign waddr_out = waddr ;
assign waddr_out = waddr ;
 
 
// grey code registers
// grey code registers
 
reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current
// grey code register for next write address
// grey code register for next write address
reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next
reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next
 
 
// 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] ;
Line 138... Line 143...
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
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next  = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ;
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next  = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ;
 
 
// FFs for registered empty and full flags
 
wire empty ;
 
wire full ;
 
 
 
// almost_full tag
 
wire 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 ;
assign wallow_out = wenable_in & ~full_out ;
 
 
// write allow output assignment
 
assign wallow_out = wallow && !full ;
 
 
 
// read allow wire
 
wire rallow ;
 
 
 
// full output assignment
 
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*/ ;     // flush not used
wire clear = reset_in ;
 
 
assign empty_out = empty ;
 
 
 
//rallow generation
//rallow generation
assign rallow = renable_in && !empty ; // reads allowed if read enable is high and FIFO is not empty
assign rallow_out = renable_in & ~empty_out ; // reads allowed if read enable is high and FIFO is not empty
 
 
// rallow output assignment
 
assign rallow_out = rallow ;
 
 
 
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary
// when FIFO is empty, this register provides actual read address, so first location can be read
// when FIFO is empty, this register provides actual read address, so first location can be read
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ;
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ;
 
 
// address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out
// address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out
// done for zero wait state burst
// done for zero wait state burst
assign raddr_out = rallow ? raddr_plus_one : raddr ;
assign raddr_out = rallow_out ? raddr_plus_one : raddr ;
 
 
always@(posedge rclock_in or posedge clear)
always@(posedge rclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        raddr_plus_one <= #`FF_DELAY 4 ;
        raddr_plus_one <= #`FF_DELAY 4 ;
        raddr          <= #`FF_DELAY 3 ;
        raddr          <= #`FF_DELAY 3 ;
    end
    end
    else if (rallow)
    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 ;
    end
    end
end
end
Line 206... Line 187...
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 0
        // initial value is 0
        rgrey_minus1 <= #`FF_DELAY 0 ;
        rgrey_minus1 <= #1 0 ;
        rgrey_addr   <= #`FF_DELAY 1 ;
        rgrey_addr   <= #1 1 ;
        rgrey_next   <= #`FF_DELAY 3 ;
        rgrey_next   <= #`FF_DELAY 3 ;
    end
    end
    else
    else
    if (rallow)
    if (rallow_out)
    begin
    begin
        rgrey_minus1 <= #`FF_DELAY rgrey_addr ;
        rgrey_minus1 <= #1 rgrey_addr ;
        rgrey_addr   <= #`FF_DELAY rgrey_next ;
        rgrey_addr   <= #1 rgrey_next ;
        rgrey_next   <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ;
        rgrey_next   <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ;
    end
    end
end
end
 
 
/*--------------------------------------------------------------------------------------------
/*--------------------------------------------------------------------------------------------
Line 227... Line 208...
// 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_next <= #`FF_DELAY 3 ;
        wgrey_addr <= #`FF_DELAY 1 ;
 
        wgrey_next <= #1 3         ;
    end
    end
    else
    else
    if (wallow)
    if (wallow_out)
    begin
    begin
        wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
        wgrey_addr <= #`FF_DELAY wgrey_next ;
 
        wgrey_next <= #1 {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
    end
    end
end
end
 
 
// write address counter - nothing special - initial value is important though
// write address counter - nothing special - initial value is important though
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 4
            waddr <= #`FF_DELAY 3 ;
            waddr <= #`FF_DELAY 3 ;
    else
    else
    if (wallow)
    if (wallow_out)
        waddr <= #`FF_DELAY waddr + 1'b1 ;
        waddr <= #`FF_DELAY waddr + 1'b1 ;
end
end
 
 
/*------------------------------------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------------------------------------------------------------------
Full control:
Gray coded address of read address decremented by 1 is synchronized to write clock domain and compared to:
Gray coded read address pointer is synchronized to write clock domain and compared to Gray coded next write address.
 
If they are equal, fifo is full.
- Gray coded write address. If they are equal, fifo is full.
 
 
Almost full control:
- Gray coded next write address. If they are equal, fifo is almost full.
Gray coded address of read address decremented by 1 is synchronized to write clock domain and compared to Gray coded next write
 
address. If they are equal, fifo is almost full.
 
--------------------------------------------------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------------------------------------------------------*/
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_addr ;
 
reg  [(ADDR_LENGTH - 1):0] wclk_rgrey_addr ;
 
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ;
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ;
reg  [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ;
reg  [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ;
 
 
synchronizer_flop #(ADDR_LENGTH, 1) i_synchronizer_reg_rgrey_addr
 
(
 
    .data_in        (rgrey_addr),
 
    .clk_out        (wclock_in),
 
    .sync_data_out  (wclk_sync_rgrey_addr),
 
    .async_reset    (clear)
 
) ;
 
 
 
synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus1
synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus1
(
(
    .data_in        (rgrey_minus1),
    .data_in        (rgrey_minus1),
    .clk_out        (wclock_in),
    .clk_out        (wclock_in),
    .sync_data_out  (wclk_sync_rgrey_minus1),
    .sync_data_out  (wclk_sync_rgrey_minus1),
Line 281... Line 252...
 
 
always@(posedge wclock_in or posedge clear)
always@(posedge wclock_in or posedge clear)
begin
begin
    if (clear)
    if (clear)
    begin
    begin
        wclk_rgrey_addr   <= #`FF_DELAY 1 ;
 
        wclk_rgrey_minus1 <= #`FF_DELAY 0 ;
        wclk_rgrey_minus1 <= #`FF_DELAY 0 ;
    end
    end
    else
    else
    begin
    begin
        wclk_rgrey_addr   <= #`FF_DELAY wclk_sync_rgrey_addr ;
 
        wclk_rgrey_minus1 <= #`FF_DELAY wclk_sync_rgrey_minus1 ;
        wclk_rgrey_minus1 <= #`FF_DELAY wclk_sync_rgrey_minus1 ;
    end
    end
end
end
 
 
assign full         = (wgrey_next == wclk_rgrey_addr) ;
assign full_out        = (wgrey_addr == wclk_rgrey_minus1) ;
assign almost_full  = (wgrey_next == wclk_rgrey_minus1) ;
assign almost_full_out = (wgrey_next == wclk_rgrey_minus1) ;
 
 
/*------------------------------------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------------------------------------------------------------------
Empty control:
Empty control:
Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address.
Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address.
If they are equal, fifo is empty.
If they are equal, fifo is empty.
Line 317... Line 286...
        rclk_wgrey_next <= #`FF_DELAY 3 ;
        rclk_wgrey_next <= #`FF_DELAY 3 ;
    else
    else
        rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ;
        rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ;
end
end
 
 
assign empty = (rgrey_next == rclk_wgrey_next) ;
assign empty_out = (rgrey_next == rclk_wgrey_next) ;
 
 
endmodule
endmodule
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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