⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pci_delayed_sync.v

📁 用verilog编写的pci——rtl级。
💻 V
📖 第 1 页 / 共 2 页
字号:
) ;

// wire for clearing completion side request flag - whenever completion or retry expired are signalled
wire comp_req_pending_clear = comp_req_pending && ( comp_in || retry_expired_in) ;

// wire for enabling request flip - flop - it is enabled when completion is not active and done is not active
wire comp_req_pending_ena   = ~comp_comp_pending && ~comp_done_reg_main && ~comp_rty_exp_reg ;

// completion side request flip flop - gets a value from intermediate stage sync flip flop
always@(posedge comp_clk_in or posedge reset_in)
begin
    if ( reset_in )
        comp_req_pending <= #`FF_DELAY 1'b0 ;
    else
    if ( comp_req_pending_clear )
        comp_req_pending <= #`FF_DELAY 1'b0 ;
    else
    if ( comp_req_pending_ena )
        comp_req_pending <= #`FF_DELAY sync_comp_req_pending ;
end

// completion side request output assignment - when request ff is set and completion ff is not set
assign comp_req_pending_out = comp_req_pending ;

// requesting side request pending output
assign req_req_pending_out  = req_req_pending ;
/*=================================================================================================================================
Passing of completions between clock domains:
completion originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain
=================================================================================================================================*/
// main completion Flip - Flop - triggered by completing side's clock
// completion side completion pending flag is cleared when done flag propagates through clock domains
wire comp_comp_clear = comp_done_reg_main && ~comp_done_reg_clr ;
always@(posedge comp_clk_in or posedge reset_in)
begin
    if ( reset_in )
        comp_comp_pending <= #`FF_DELAY 1'b0 ;
    else
    if ( comp_comp_clear )
        comp_comp_pending <= #`FF_DELAY 1'b0 ;
    else
    if ( comp_in && comp_req_pending )
        comp_comp_pending <= #`FF_DELAY 1'b1 ;
end

assign comp_comp_pending_out = comp_comp_pending ;

// interemediate stage completion synchronization flip - flop - this one is prone to metastability
pci_synchronizer_flop #(1, 0) comp_sync
(
    .data_in        (comp_comp_pending),
    .clk_out        (req_clk_in),
    .sync_data_out  (sync_req_comp_pending),
    .async_reset    (reset_in)
) ;

// request side completion pending flip flop is cleared whenever done is signalled or completion counter expires - 2^^16 clock cycles
wire req_comp_pending_clear = done_in || comp_cycle_count[16];

// request side completion pending flip flop is disabled while done flag is set
wire req_comp_pending_ena   = ~req_done_reg ;

// request side completion flip flop - gets a value from intermediate stage sync flip flop
always@(posedge req_clk_in or posedge reset_in)
begin
    if ( reset_in )
        req_comp_pending <= #`FF_DELAY 1'b0 ;
    else
    if ( req_comp_pending_clear )
        req_comp_pending <= #`FF_DELAY 1'b0 ;
    else
    if ( req_comp_pending_ena )
        req_comp_pending <= #`FF_DELAY sync_req_comp_pending ;
end

// sampling FF - used for sampling incoming completion flag from completing side
always@(posedge req_clk_in or posedge reset_in)
begin
    if ( reset_in )
        req_comp_pending_sample <= #`FF_DELAY 1'b0 ;
    else
        req_comp_pending_sample <= #`FF_DELAY sync_req_comp_pending ;
end

// requesting side completion pending output assignment
assign req_comp_pending_out = req_comp_pending && ~req_req_pending ;

/*==================================================================================================================================
Passing of delayed transaction done signal between clock domains.
Done is signalled by requesting side of the bridge and is passed to completing side of the bridge
==================================================================================================================================*/
// main done flip-flop triggered on requesting side's clock
// when completing side removes completion flag, done flag is also removed, so requests can proceede
wire req_done_clear = ~req_comp_pending_sample ;
always@(posedge req_clk_in or posedge reset_in)
begin
    if ( reset_in )
        req_done_reg <= #`FF_DELAY 1'b0 ;
    else
    if ( req_done_clear )
        req_done_reg <= #`FF_DELAY 1'b0 ;
    else
    if ( done_in || comp_cycle_count[16] )
        req_done_reg <= #`FF_DELAY 1'b1 ;
end

pci_synchronizer_flop  #(1, 0) done_sync
(
    .data_in        (req_done_reg),
    .clk_out        (comp_clk_in),
    .sync_data_out  (sync_comp_done),
    .async_reset    (reset_in)
) ;

always@(posedge comp_clk_in or posedge reset_in)
begin
    if ( reset_in )
        comp_done_reg_main <= #`FF_DELAY 1'b0 ;
    else
        comp_done_reg_main <= #`FF_DELAY sync_comp_done ;
end

always@(posedge comp_clk_in or posedge reset_in)
begin
    if ( reset_in )
        comp_done_reg_clr <= #`FF_DELAY 1'b0 ;
    else
        comp_done_reg_clr <= #`FF_DELAY comp_done_reg_main ;
end

/*=================================================================================================================================
Passing of retry expired signal between clock domains
Retry expiration originates on completing side. It's then synchronized with two flip-flops to cross to requesting clock domain
=================================================================================================================================*/
// main retry expired Flip - Flop - triggered by completing side's clock
wire comp_rty_exp_clear = comp_rty_exp_clr && comp_rty_exp_reg ;

// retry expired is a special case of transaction removal - retry expired propagates from completing
// clock domain to requesting clock domain to remove all pending requests and than propagates back
// to completing side to qualify valid new requests

always@(posedge comp_clk_in or posedge reset_in)
begin
    if ( reset_in )
        comp_rty_exp_reg <= #`FF_DELAY 1'b0 ;
    else
    if ( comp_rty_exp_clear )
        comp_rty_exp_reg <= #`FF_DELAY 1'b0 ;
    else
    if ( retry_expired_in && comp_req_pending)
        comp_rty_exp_reg <= #`FF_DELAY 1'b1 ;
end

// interemediate stage retry expired synchronization flip - flop - this one is prone to metastability
pci_synchronizer_flop #(1, 0) rty_exp_sync
(
    .data_in        (comp_rty_exp_reg),
    .clk_out        (req_clk_in),
    .sync_data_out  (sync_req_rty_exp),
    .async_reset    (reset_in)
) ;

// request retry expired flip flop - gets a value from intermediate stage sync flip flop
always@(posedge req_clk_in or posedge reset_in)
begin
    if ( reset_in )
        req_rty_exp_reg <= #`FF_DELAY 1'b0 ;
    else
        req_rty_exp_reg <= #`FF_DELAY sync_req_rty_exp ;
end

always@(posedge req_clk_in or posedge reset_in)
begin
    if ( reset_in )
        req_rty_exp_clr <= #`FF_DELAY 1'b0 ;
    else
        req_rty_exp_clr <= #`FF_DELAY req_rty_exp_reg ;
end

pci_synchronizer_flop #(1, 0) rty_exp_back_prop_sync
(
    .data_in        (req_rty_exp_reg && req_rty_exp_clr),
    .clk_out        (comp_clk_in),
    .sync_data_out  (sync_comp_rty_exp_clr),
    .async_reset    (reset_in)
) ;

always@(posedge comp_clk_in or posedge reset_in)
begin
    if ( reset_in )
        comp_rty_exp_clr <= #`FF_DELAY 1'b0 ;
    else
        comp_rty_exp_clr <= #`FF_DELAY sync_comp_rty_exp_clr ;
end

// completion status flip flop - if 0 when completion is signalled it's finished OK otherwise it means error
reg status_out ;
always@(posedge comp_clk_in or posedge reset_in)
begin
    if (reset_in)
        status_out <= #`FF_DELAY 1'b0 ;
    else
    if (comp_in && comp_req_pending)
        status_out <= #`FF_DELAY status_in ;
end

// clocks counter - it counts how many clock cycles completion is present without beeing repeated
// if it counts to 2^^16 cycles the completion must be ditched

// wire for clearing this counter
wire clear_count = in_progress_in || ~req_comp_pending_out || comp_cycle_count[16] ;
always@(posedge req_clk_in or posedge reset_in)
begin
    if (reset_in)
        comp_cycle_count <= #`FF_DELAY 17'h0_0000 ;
    else
    if (clear_count)
        comp_cycle_count <= #`FF_DELAY 17'h0_0000 ;
    else
        comp_cycle_count <= #`FF_DELAY comp_cycle_count + 1'b1 ;
end

// completion flush output - used for flushing fifos when counter expires
// if counter doesn't expire, fifo flush is up to WISHBONE slave or PCI target state machines
reg comp_flush_out ;
always@(posedge req_clk_in or posedge reset_in)
begin
    if (reset_in)
        comp_flush_out <= #`FF_DELAY 1'b0 ;
    else
        comp_flush_out <= #`FF_DELAY comp_cycle_count[16] ;
end

endmodule //delayed_sync

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -