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 58 and 59

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

Rev 58 Rev 59
Line 125... Line 125...
 
 
// 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
// FFs for registered empty and full flags
reg empty ;
wire empty ;
reg full ;
wire full ;
 
 
// registered almost_empty and almost_full flags
// registered almost_empty and almost_full flags
reg almost_empty ;
wire almost_empty ;
reg almost_full ;
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 ;
wire wallow = wenable_in && !full ;
 
 
// write allow output assignment
// write allow output assignment
assign wallow_out = wallow ;
assign wallow_out = wallow ;
 
 
// read allow wire
// read allow wire
Line 145... Line 145...
 
 
// full output assignment
// full output assignment
assign full_out  = full ;
assign full_out  = full ;
 
 
// almost full output assignment
// almost full output assignment
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*/ ;     // flush not used for write fifo
wire clear = reset_in /*|| flush_in*/ ;     // flush not used for write fifo
 
 
reg wclock_nempty_detect ;
reg wclock_nempty_detect ;
Line 159... Line 159...
        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
 
 
reg stretched_empty ;
wire stretched_empty ;
always@(posedge rclock_in or posedge clear)
 
begin
wire stretched_empty_flop_i = empty && ~wclock_nempty_detect ;
    if(clear)
 
        stretched_empty <= #`FF_DELAY 1'b1 ;
meta_flop #(1) i_meta_flop_stretched_empty
    else
(
        stretched_empty <= #`FF_DELAY empty && ~wclock_nempty_detect ;
    .rst_i      (clear),
end
    .clk_i      (rclock_in),
 
    .ld_i       (1'b0),
 
    .ld_val_i   (1'b0),
 
    .en_i       (1'b1),
 
    .d_i        (stretched_empty_flop_i),
 
    .meta_q_o   (stretched_empty)
 
) ;
 
 
// empty output is actual empty + 1 read clock cycle ( stretched empty )
// empty output is actual empty + 1 read clock cycle ( stretched empty )
assign empty_out = empty  || stretched_empty ;
assign empty_out = empty  || stretched_empty ;
 
 
//rallow generation
//rallow generation
assign rallow = renable_in && ~empty && ~stretched_empty ; // reads allowed if read enable is high and FIFO is not empty
assign rallow = renable_in && !empty && !stretched_empty ; // reads allowed if read enable is high and FIFO is not empty
 
 
// rallow output assignment
// rallow output assignment
assign rallow_out = rallow ;
assign rallow_out = rallow ;
 
 
// almost empty output assignment
// almost empty output assignment
assign almost_empty_out = almost_empty && ~empty && ~stretched_empty ;
assign almost_empty_out = almost_empty && !empty && !stretched_empty ;
 
 
// 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 ;
 
 
Line 353... Line 359...
 
 
Registered two left control:
Registered two left control:
registered two left is set on rising edge of write clock when three locations are left in fifo and another is written to it.
registered two left is set on rising edge of write clock when three locations are left in fifo and another is written to it.
it's kept high until something is read/written from/to fifo.
it's kept high until something is read/written from/to fifo.
--------------------------------------------------------------------------------------------------------------------------------*/
--------------------------------------------------------------------------------------------------------------------------------*/
reg two_left_out ;
 
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_addr == rgrey_minus2 ;
wire comb_two_left      = wgrey_next == rgrey_minus2 ;
wire comb_two_left      = wgrey_next == rgrey_minus2 ;
wire comb_three_left    = wgrey_next == rgrey_minus3 ;
wire comb_three_left    = wgrey_next == rgrey_minus3 ;
 
 
//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)
meta_flop #(0) i_meta_flop_full
begin
(
        if (clear)
    .rst_i       (clear),
                full <= #`FF_DELAY 1'b0 ;
    .clk_i       (wclock_in),
        else
    .ld_i        (1'b0),
                full <= #`FF_DELAY reg_full ;
    .ld_val_i    (1'b0),
end
    .en_i        (1'b1),
 
    .d_i         (reg_full),
 
    .meta_q_o    (full)
 
) ;
 
 
// input for almost full flip flop
// input for almost full flip flop
wire reg_almost_full_in = wallow && comb_two_left || comb_almost_full ;
wire reg_almost_full_in = wallow && comb_two_left || comb_almost_full ;
 
 
always@(posedge clear or posedge wclock_in)
meta_flop #(0) i_meta_flop_almost_full
begin
(
    if (clear)
    .rst_i       (clear),
        almost_full <= #`FF_DELAY 1'b0 ;
    .clk_i       (wclock_in),
    else
    .ld_i        (1'b0),
        almost_full <= #`FF_DELAY reg_almost_full_in ;
    .ld_val_i    (1'b0),
end
    .en_i        (1'b1),
 
    .d_i         (reg_almost_full_in),
 
    .meta_q_o    (almost_full)
 
) ;
 
 
wire reg_two_left_in = wallow && comb_three_left || comb_two_left ;
wire reg_two_left_in = wallow && comb_three_left || comb_two_left ;
 
 
always@(posedge clear or posedge wclock_in)
meta_flop #(0) i_meta_flop_two_left
begin
(
    if (clear)
    .rst_i       (clear),
        two_left_out <= #`FF_DELAY 1'b0 ;
    .clk_i       (wclock_in),
    else
    .ld_i        (1'b0),
        two_left_out <= #`FF_DELAY reg_two_left_in ;
    .ld_val_i    (1'b0),
end
    .en_i        (1'b1),
 
    .d_i         (reg_two_left_in),
 
    .meta_q_o    (two_left_out)
 
) ;
 
 
/*------------------------------------------------------------------------------------------------------------------------------
/*------------------------------------------------------------------------------------------------------------------------------
Registered empty control:
Registered empty control:
registered empty is set on rising edge of rclock_in,
registered empty is set on rising edge of rclock_in,
when only one location is used in and read from fifo. It's kept high until something is written to FIFO, which is registered on
when only one location is used in and read from fifo. It's kept high until something is written to FIFO, which is registered on
Line 408... Line 422...
wire comb_two_used      = rgrey_next == wgrey_minus1 ;
wire comb_two_used      = rgrey_next == wgrey_minus1 ;
 
 
// combinatorial input for registered emty FlipFlop
// combinatorial input for registered emty FlipFlop
wire reg_empty = (rallow && comb_almost_empty) || comb_empty ;
wire reg_empty = (rallow && comb_almost_empty) || comb_empty ;
 
 
always@(posedge rclock_in or posedge clear)
meta_flop #(1) i_meta_flop_empty
begin
(
    if (clear)
    .rst_i      (clear),
        empty <= #`FF_DELAY 1'b1 ;
    .clk_i      (rclock_in),
        else
    .ld_i       (1'b0),
        empty <= #`FF_DELAY reg_empty ;
    .ld_val_i   (1'b0),
end
    .en_i       (1'b1),
 
    .d_i        (reg_empty),
 
    .meta_q_o   (empty)
 
) ;
 
 
// input for almost empty flip flop
// input for almost empty flip flop
wire reg_almost_empty = rallow && comb_two_used || comb_almost_empty ;
wire reg_almost_empty = rallow && comb_two_used || comb_almost_empty ;
always@(posedge clear or posedge rclock_in)
 
begin
meta_flop #(0) i_meta_flop_almost_empty
    if (clear)
(
        almost_empty <= #`FF_DELAY 1'b0 ;
    .rst_i      (clear),
    else
    .clk_i      (rclock_in),
        almost_empty <= #`FF_DELAY reg_almost_empty ;
    .ld_i       (1'b0),
end
    .ld_val_i   (1'b0),
 
    .en_i       (1'b1),
 
    .d_i        (reg_almost_empty),
 
    .meta_q_o   (almost_empty)
 
) ;
 
 
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.