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

Subversion Repositories pci

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

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

Rev 6 Rev 21
Line 44... Line 44...
// $Log
// $Log
//
//
 
 
/* 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 "constants.v"
`include "pci_constants.v"
 
// synopsys translate_off
`include "timescale.v"
`include "timescale.v"
 
// synopsys translate_on
 
 
`ifdef FPGA
 
    // fifo design in FPGA will be synchronous
 
    `ifdef SYNCHRONOUS
 
    `else
 
        `define SYNCHRONOUS
 
    `endif
 
`endif
 
module PCIW_FIFO_CONTROL
module PCIW_FIFO_CONTROL
(
(
    rclock_in,
    rclock_in,
    wclock_in,
    wclock_in,
    renable_in,
    renable_in,
Line 155... Line 150...
assign almost_full_out  = almost_full && ~full ;
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 ;
 
 
`ifdef SYNCHRONOUS
 
 
 
    reg wclock_nempty_detect ;
    reg wclock_nempty_detect ;
    always@(posedge reset_in or posedge wclock_in)
    always@(posedge reset_in or posedge wclock_in)
    begin
    begin
        if (reset_in)
        if (reset_in)
            wclock_nempty_detect <= #`FF_DELAY 1'b0 ;
            wclock_nempty_detect <= #`FF_DELAY 1'b0 ;
        else
        else
            wclock_nempty_detect <= #`FF_DELAY (rgrey_addr != wgrey_addr) ;
            wclock_nempty_detect <= #`FF_DELAY (rgrey_addr != wgrey_addr) ;
    end
    end
 
 
    // special synchronizing mechanism for different implementations - in synchronous imp., empty is prolonged for 1 clock edge if no write clock comes after initial write
 
    reg stretched_empty ;
    reg stretched_empty ;
    always@(posedge rclock_in or posedge clear)
    always@(posedge rclock_in or posedge clear)
    begin
    begin
        if(clear)
        if(clear)
            stretched_empty <= #`FF_DELAY 1'b1 ;
            stretched_empty <= #`FF_DELAY 1'b1 ;
Line 192... Line 184...
 
 
    // 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
 
    // done for zero wait state burst
 
    assign raddr_out = empty_out ? raddr : raddr_plus_one ;
 
 
 
    // enable for this register
// read address mux - when read is performed, next address is driven, so next data is available immediately after read
    wire raddr_plus_one_en = rallow ;
// this is convenient for zero wait stait bursts
 
assign raddr_out = rallow ? 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[(ADDR_LENGTH - 1):1] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0}} ;
        // initial value is one more than initial value of read address - 6
            raddr_plus_one[0] <= #`FF_DELAY 1'b1 ;
        raddr_plus_one <= #`FF_DELAY 6 ;
        end
        end
        else if (raddr_plus_one_en)
    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 000......00
        // initial value is 5
                    raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ;
    raddr <= #`FF_DELAY 5 ;
            else if (rallow)
            else if (rallow)
                raddr <= #`FF_DELAY raddr_plus_one ;
                raddr <= #`FF_DELAY raddr_plus_one ;
    end
    end
 
 
`else
 
    // asynchronous RAM storage for FIFOs - somewhat simpler control logic
 
    //rallow generation    
 
    assign rallow = renable_in && ~empty ;
 
 
 
    assign rallow_out = rallow;
 
 
 
    assign almost_empty_out = almost_empty && ~empty ;
 
 
 
    // read address counter - normal counter, nothing to it
 
    // for asynchronous implementation, there is no need for pointing to next address.
 
    // On clock edge that read is performed, read address will change and on the next clock edge
 
    // asynchronous memory will provide next data
 
    always@(posedge rclock_in or posedge clear)
 
    begin
 
            if (clear)
 
            // initial value is 000......00
 
                    raddr <= #`FF_DELAY { ADDR_LENGTH{1'b0}} ;
 
            else if (rallow)
 
                    raddr <= #`FF_DELAY raddr + 1'b1 ;
 
    end
 
 
 
    assign empty_out = empty ;
 
    assign raddr_out = raddr ;
 
`endif
 
 
 
/*-----------------------------------------------------------------------------------------------
/*-----------------------------------------------------------------------------------------------
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 5 Grey addresses:
There are 5 Grey addresses:
    - rgrey_minus3 is Grey Code of address three before current address
    - rgrey_minus3 is Grey Code of address three before current address
    - rgrey_minus2 is Grey Code of address two before current address
    - rgrey_minus2 is Grey Code of address two before current address
Line 260... Line 225...
// grey code register for three before read address
// grey code register for three 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 100......110
        // initial value is 0
                rgrey_minus3[(ADDR_LENGTH - 1)]    <= #`FF_DELAY 1'b1 ;
        rgrey_minus3 <= #`FF_DELAY 0 ;
        rgrey_minus3[(ADDR_LENGTH  - 2):3] <= #`FF_DELAY { (ADDR_LENGTH  - 4){1'b0} } ;
 
        rgrey_minus3[2:0] <= #`FF_DELAY 3'b110 ;
 
    end
    end
        else
        else
                if (rallow)
                if (rallow)
                        rgrey_minus3 <= #`FF_DELAY rgrey_minus2 ;
                        rgrey_minus3 <= #`FF_DELAY rgrey_minus2 ;
end
end
Line 275... Line 238...
// grey code register for two before read address
// grey code register for two 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 100......010
        // initial value is 1
                rgrey_minus2[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ;
        rgrey_minus2 <= #`FF_DELAY 1 ;
        rgrey_minus2[(ADDR_LENGTH  - 2):2] <= #`FF_DELAY { (ADDR_LENGTH  - 3){1'b0} } ;
 
        rgrey_minus2[1:0] <= #`FF_DELAY 2'b10 ;
 
    end
    end
        else
        else
                if (rallow)
                if (rallow)
                        rgrey_minus2 <= #`FF_DELAY rgrey_minus1 ;
                        rgrey_minus2 <= #`FF_DELAY rgrey_minus1 ;
end
end
Line 290... Line 251...
// 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 100......011
        // initial value is 3 = ....011
                rgrey_minus1[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ;
        rgrey_minus1 <= #`FF_DELAY 3 ;
        rgrey_minus1[(ADDR_LENGTH  - 2):2] <= #`FF_DELAY { (ADDR_LENGTH  - 3){1'b0} } ;
 
        rgrey_minus1[1:0] <= #`FF_DELAY 2'b11 ;
 
    end
    end
        else
        else
                if (rallow)
                if (rallow)
                        rgrey_minus1 <= #`FF_DELAY rgrey_addr ;
                        rgrey_minus1 <= #`FF_DELAY rgrey_addr ;
end
end
Line 305... Line 264...
// 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 100.......01
        // initial value is 2 = ....010
                rgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ;
        rgrey_addr <= #`FF_DELAY 2 ;
        rgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ;
 
        rgrey_addr[0] <= #`FF_DELAY 1'b1 ;
 
    end
    end
        else
        else
                if (rallow)
                if (rallow)
                        rgrey_addr <= #`FF_DELAY rgrey_next ;
                        rgrey_addr <= #`FF_DELAY rgrey_next ;
end
end
Line 320... Line 277...
// 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 100......00
        // initial value is 6 = ....110
                rgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ;
        rgrey_next <= #`FF_DELAY 6 ;
        rgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ;
 
    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 340... Line 296...
// 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 100.....001
        // initial value is 3 = .....011
        wgrey_minus1[(ADDR_LENGTH - 1)]   <= #`FF_DELAY 1'b1 ;
        wgrey_minus1 <= #`FF_DELAY 3 ;
        wgrey_minus1[(ADDR_LENGTH - 2):2] <= #`FF_DELAY { (ADDR_LENGTH - 3){1'b0} } ;
 
        wgrey_minus1[1:0] <= #`FF_DELAY 2'b11 ;
 
    end
    end
        else
        else
    if (wallow)
    if (wallow)
            wgrey_minus1 <= #`FF_DELAY wgrey_addr ;
            wgrey_minus1 <= #`FF_DELAY wgrey_addr ;
end
end
 
 
// 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
        // initial value is 2 = .....010
        // initial value is 100.....001
        wgrey_addr <= #`FF_DELAY 2 ;
        wgrey_addr[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ;
 
        wgrey_addr[(ADDR_LENGTH - 2):1] <= #`FF_DELAY { (ADDR_LENGTH - 2){1'b0} } ;
 
        wgrey_addr[0] <= #`FF_DELAY 1'b1 ;
 
    end
 
        else
        else
    if (wallow)
    if (wallow)
            wgrey_addr <= #`FF_DELAY wgrey_next ;
            wgrey_addr <= #`FF_DELAY wgrey_next ;
end
end
 
 
// 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 100......00
        // initial value is 6 = ....0110
                wgrey_next[(ADDR_LENGTH - 1)] <= #`FF_DELAY 1'b1 ;
        wgrey_next <= #`FF_DELAY 6 ;
        wgrey_next[(ADDR_LENGTH - 2):0] <= #`FF_DELAY { (ADDR_LENGTH - 1){1'b0} } ;
 
    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
// 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 00.........00
        // initial value 5
                waddr <= #`FF_DELAY { (ADDR_LENGTH){1'b0} } ;
        waddr <= #`FF_DELAY 5 ;
        else
        else
        if (wallow)
        if (wallow)
                waddr <= #`FF_DELAY waddr + 1'b1 ;
                waddr <= #`FF_DELAY waddr + 1'b1 ;
end
end
 
 

powered by: WebSVN 2.1.0

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