X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/raggedstone/blobdiff_plain/528d015aa19100f9f97b3469ab7d2aafa43b425e..40a1f26c3a09dbd1f71f4fd7f3aca74f387a09db:/ethernet/source/pci/pci_master32_sm_if.v diff --git a/ethernet/source/pci/pci_master32_sm_if.v b/ethernet/source/pci/pci_master32_sm_if.v new file mode 100644 index 0000000..3dd959c --- /dev/null +++ b/ethernet/source/pci/pci_master32_sm_if.v @@ -0,0 +1,849 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// File name "pci_master32_sm_if.v" //// +//// //// +//// This file is part of the "PCI bridge" project //// +//// http://www.opencores.org/cores/pci/ //// +//// //// +//// Author(s): //// +//// - Miha Dolenc (mihad@opencores.org) //// +//// //// +//// All additional information is avaliable in the README //// +//// file. //// +//// //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +// +// CVS Revision History +// +// $Log: pci_master32_sm_if.v,v $ +// Revision 1.1 2007-03-20 17:50:56 sithglan +// add shit +// +// Revision 1.7 2004/03/19 16:36:55 mihad +// Single PCI Master write fix. +// +// Revision 1.6 2003/12/19 11:11:30 mihad +// Compact PCI Hot Swap support added. +// New testcases added. +// Specification updated. +// Test application changed to support WB B3 cycles. +// +// Revision 1.5 2003/06/12 10:12:22 mihad +// Changed one critical PCI bus signal logic. +// +// Revision 1.4 2003/01/27 16:49:31 mihad +// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. +// +// Revision 1.3 2002/02/01 15:25:12 mihad +// Repaired a few bugs, updated specification, added test bench files and design document +// +// Revision 1.2 2001/10/05 08:14:29 mihad +// Updated all files with inclusion of timescale file for simulation purposes. +// +// Revision 1.1.1.1 2001/10/02 15:33:46 mihad +// New project directory structure +// +// + +`include "pci_constants.v" +`include "bus_commands.v" + +// synopsys translate_off +`include "timescale.v" +// synopsys translate_on + +/*==================================================================== +Module provides interface between PCI bridge internals and PCI master +state machine +====================================================================*/ +module pci_master32_sm_if +( + clk_in, + reset_in, + + // interconnect to pci master state machine + address_out, + bc_out, + data_out, + data_in, + be_out, + req_out, + rdy_out, + last_out, + + next_data_out, + next_be_out, + next_last_out, + + // status inputs from master SM + wait_in, + wtransfer_in, + rtransfer_in, + retry_in, + rerror_in, + first_in , + mabort_in, + + + // WISHBONE WRITE fifo inputs and outputs + wbw_renable_out, + wbw_fifo_addr_data_in, + wbw_fifo_cbe_in, + wbw_fifo_control_in, + wbw_fifo_empty_in, + wbw_fifo_transaction_ready_in, + + // WISHBONE READ fifo inputs and outputs + wbr_fifo_wenable_out, + wbr_fifo_data_out, + wbr_fifo_be_out, + wbr_fifo_control_out, + + // delayed transaction control logic inputs and outputs + del_wdata_in, + del_complete_out, + del_req_in, + del_addr_in, + del_bc_in, + del_be_in, + del_burst_in, + del_error_out, + del_rty_exp_out, + del_we_in, + + // configuration space interconnect + // error reporting + err_addr_out, + err_bc_out, + err_signal_out, + err_source_out, + err_rty_exp_out, + + cache_line_size_in, + + // two signals for pci control and status + mabort_received_out, + tabort_received_out, + + posted_write_not_present_out +); + +// system inputs +input clk_in ; +input reset_in ; + +// PCI master state machine interconnect +output [31:0] address_out ; // address output + +output [3:0] bc_out ; // bus command output +reg [3:0] bc_out ; + +output [31:0] data_out ; // data output for writes +reg [31:0] data_out ; + +input [31:0] data_in ; // data input for reads +output [3:0] be_out ; // byte enable output +reg [3:0] be_out ; + +output req_out ; // request output + +output rdy_out ; // ready output +reg rdy_out ; + +output last_out ; // last data indicator output + +output [31:0] next_data_out ; // next data output +output [3:0] next_be_out ; // next byte enable output +output next_last_out ; // next transfer last indicator + +input wait_in, + wtransfer_in, + rtransfer_in, + retry_in, + rerror_in, + first_in , + mabort_in ; + +// WISHBONE write fifo interconnect +output wbw_renable_out ; // WBW_FIFO read enable signal + +input [31:0] wbw_fifo_addr_data_in ; // WBW_FIFO address/data bus +input [3:0] wbw_fifo_cbe_in ; // WBW_FIFO command/byte enable bus +input [3:0] wbw_fifo_control_in ; // WBW_FIFO control bus +input wbw_fifo_empty_in ; // WBW_FIFO's empty status indicator +input wbw_fifo_transaction_ready_in ; // WBW_FIFO transaction ready indicator + +// WISHBONE read FIFO interconnect +output wbr_fifo_wenable_out ; // write enable for WBR_FIFO + +output [31:0] wbr_fifo_data_out ; // data output to WBR_FIFO + +output [3:0] wbr_fifo_be_out ; // byte enable output for WBR_FIFO + +output [3:0] wbr_fifo_control_out ; // WBR_FIFO control output + +// delayed transaction control logic inputs and outputs +input [31:0] del_wdata_in ; // delayed write data input +output del_complete_out ; // delayed transaction completed output + +input del_req_in ; // delayed transaction request +input [31:0] del_addr_in ; // delayed transaction address +input [3:0] del_bc_in ; // delayed transaction bus command input +input [3:0] del_be_in ; // delayed transaction byte enables input +input del_burst_in ; // delayed transaction burst req. indicator +output del_error_out ; // delayed transation error termination signal + +output del_rty_exp_out ; // retry expired output for delayed transactions + +input del_we_in ; // delayed write request indicator + +output [31:0] err_addr_out ; // erroneous address output +output [3:0] err_bc_out ; // erroneous bus command output + +output err_signal_out ; // error signalization + +output err_source_out ; // error source indicator + +input [7:0] cache_line_size_in ; // cache line size value input + +output err_rty_exp_out ; // retry expired error output + +output mabort_received_out ; // master abort signaled to status register +output tabort_received_out ; // target abort signaled to status register + +output posted_write_not_present_out ; // used in target state machine - must deny read completions when this signal is 0 + + +assign err_bc_out = bc_out ; + +// assign read outputs +/*================================================================================================================== +WISHBONE read FIFO data outputs - just link them to SM data outputs and delayed BE input +==================================================================================================================*/ +assign wbr_fifo_data_out = data_in ; +assign wbr_fifo_be_out = del_be_in ; + +// decode if current bus command is configuration command +wire conf_cyc_bc = ( bc_out[3:1] == `BC_CONF_RW ) ; + +// register for indicating that current data is also last in transfer +reg current_last ; + +// register indicating that last data was transfered OK +reg last_transfered ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + last_transfered <= #`FF_DELAY 1'b0 ; + else + last_transfered <= #`FF_DELAY ~wait_in && last_out && wtransfer_in ; +end + +// status signals output assignement +assign mabort_received_out = mabort_in ; + +wire tabort_ff_in = ~wait_in && rerror_in ; + +reg tabort_received_out ; +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + tabort_received_out <= #`FF_DELAY 1'b0 ; + else + tabort_received_out <= #`FF_DELAY tabort_ff_in ; +end + +// error recovery indicator +reg err_recovery ; + +// operation is locked until error recovery is in progress or error bit is not cleared in configuration space +wire err_lock = err_recovery ; + +// three requests are possible - posted write, delayed write and delayed read +reg del_write_req ; +reg posted_write_req ; +reg del_read_req ; + +// assign request output +assign req_out = del_write_req || posted_write_req || del_read_req ; + +// posted write is not present, when WB Write Fifo is empty and posted write transaction is not beeing requested at present time +assign posted_write_not_present_out = !posted_write_req && wbw_fifo_empty_in ; + +// write requests are staged, so data is read from source into current data register and next data register +reg write_req_int ; +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + write_req_int <= #`FF_DELAY 1'b0 ; + else + write_req_int <= #`FF_DELAY posted_write_req || del_write_req ; + +end + +// ready output is generated one clock after request for reads and two after for writes +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + rdy_out <= #`FF_DELAY 1'b0 ; + else + rdy_out <= #`FF_DELAY del_read_req || ( (posted_write_req || del_write_req) && write_req_int) ; +end + +// wires with logic used as inputs to request FFs +wire do_posted_write = ( wbw_fifo_transaction_ready_in && ~wbw_fifo_empty_in && ~err_lock ) ; +wire do_del = ( del_req_in && ~err_lock && wbw_fifo_empty_in ) ; +wire do_del_write = do_del && del_we_in ; +wire do_del_read = do_del && ~del_we_in ; + +// register for indicating current operation's data source +parameter DELAYED_WRITE = 1'b1 ; +parameter POSTED_WRITE = 1'b0 ; + +// new data source - depending on which transaction will be processed next - delayed read is here because source of byte enables must +// be specified for delayed reads also - data source is not relevant for delayed reads, so value is don't care anyway +wire new_data_source = (do_del_write || do_del_read) ? DELAYED_WRITE : POSTED_WRITE ; // input to data source register +wire data_source_change = ~req_out ; // change (enable) for data source register - when no requests are in progress + +reg data_source ; // data source value +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + // default value is posted write source - wbw_fifo + data_source <= #`FF_DELAY POSTED_WRITE ; + else + if (data_source_change) + // change data source on rising clock edge + data_source <= #`FF_DELAY new_data_source ; +end + +// multiplexer for data output to PCI MASTER state machine +reg [31:0] source_data ; +reg [3:0] source_be ; +always@(data_source or wbw_fifo_addr_data_in or wbw_fifo_cbe_in or del_wdata_in or del_be_in or del_burst_in) +begin + case (data_source) + POSTED_WRITE: begin + source_data = wbw_fifo_addr_data_in ; + source_be = wbw_fifo_cbe_in ; + end + DELAYED_WRITE: begin + source_data = del_wdata_in ; + // read all bytes during delayed burst read! + source_be = ~( del_be_in | {4{del_burst_in}} ) ; + end + endcase +end + +wire waddr = wbw_fifo_control_in[`ADDR_CTRL_BIT] ; + +// address change indicator - address is allowed to be loaded only when no transaction is in progress! +wire address_change = ~req_out ; // address change - whenever there is no request in progress + +// new address - input to register storing address of current request - if posted write request will be next, +// load address and bus command from wbw_fifo, else load data from delayed transaction logic +wire [31:0] new_address = ( ~req_out && do_posted_write ) ? wbw_fifo_addr_data_in[31:0] : del_addr_in[31:0] ; +wire [3:0] new_bc = ( ~req_out && do_posted_write ) ? wbw_fifo_cbe_in : del_bc_in ; + +// address counter enable - only for posted writes when data is actually transfered +wire addr_count_en = !wait_in && posted_write_req && rtransfer_in ; + +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + bc_out <= #`FF_DELAY `BC_RESERVED0 ; + else + if (address_change) + bc_out <= #`FF_DELAY new_bc ; +end + +reg [29:0] current_dword_address ; + +// DWORD address counter with load +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + current_dword_address <= #`FF_DELAY 30'h0000_0000 ; + else + if (address_change) + current_dword_address <= #`FF_DELAY new_address[31:2] ; + else + if (addr_count_en) + current_dword_address <= #`FF_DELAY current_dword_address + 1'b1 ; +end + +reg [1:0] current_byte_address ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + current_byte_address <= #`FF_DELAY 2'b00 ; + else + if (address_change) + current_byte_address <= #`FF_DELAY new_address[1:0] ; +end + +// byte address generation logic +reg [ 1: 0] generated_byte_adr ; +reg [ 1: 0] pci_byte_adr ; + +always@(be_out) +begin + casex(be_out) + 4'bxxx0:generated_byte_adr = 2'b00 ; + 4'bxx01:generated_byte_adr = 2'b01 ; + 4'bx011:generated_byte_adr = 2'b10 ; + 4'b0111:generated_byte_adr = 2'b11 ; + 4'b1111:generated_byte_adr = 2'b00 ; + endcase +end + +always@(generated_byte_adr or bc_out or current_byte_address) +begin + // for memory access commands, set lower 2 address bits to 0 + if ((bc_out == `BC_MEM_READ) | (bc_out == `BC_MEM_WRITE) | + (bc_out == `BC_MEM_READ_MUL) | (bc_out == `BC_MEM_READ_LN) | + (bc_out == `BC_MEM_WRITE_INVAL)) + begin + pci_byte_adr = 2'b00 ; + end + else if ((bc_out == `BC_IO_WRITE) | (bc_out == `BC_IO_READ)) + begin + pci_byte_adr = generated_byte_adr ; + end + else + begin + pci_byte_adr = current_byte_address ; + end +end + +// address output to PCI master state machine assignment +assign address_out = { current_dword_address, pci_byte_adr } ; + +// the same for erroneous address assignement +assign err_addr_out = { current_dword_address, pci_byte_adr } ; + +// cacheline size counter - for read transaction length control +// cache line count is enabled during burst reads when data is actually transfered +wire read_count_enable = ~wait_in && del_read_req && del_burst_in && wtransfer_in ; + +// cache line counter is loaded when del read request is not in progress +wire read_count_load = ~del_read_req ; + +reg [(`WBR_ADDR_LENGTH - 1):0] max_read_count ; +always@(cache_line_size_in or del_bc_in) +begin + if ( (cache_line_size_in >= `WBR_DEPTH) || (~del_bc_in[1] && ~del_bc_in[0]) ) + max_read_count = `WBR_DEPTH - 1'b1; + else + max_read_count = cache_line_size_in ; +end + +reg [(`WBR_ADDR_LENGTH - 1):0] read_count ; + +// cache line bound indicator - it signals when data for one complete cacheline was read +wire read_bound_comb = ~|(read_count[(`WBR_ADDR_LENGTH - 1):2]) ; +reg read_bound ; +always@(posedge clk_in or posedge reset_in) +begin + if ( reset_in ) + read_bound <= #`FF_DELAY 1'b0 ; + else if (read_count_load) + read_bound <= #`FF_DELAY 1'b0 ; + else if ( read_count_enable ) + read_bound <= #`FF_DELAY read_bound_comb ; +end + +wire read_count_change_val = read_count_load | read_count_enable ; + +wire [(`WBR_ADDR_LENGTH - 1):0] read_count_next = read_count_load ? max_read_count : (read_count - 1'b1) ; + +// down counter with load +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + read_count <= #`FF_DELAY 0 ; + else +/* if (read_count_load) + read_count <= #`FF_DELAY max_read_count ; + else + if (read_count_enable) + read_count <= #`FF_DELAY read_count - 1'b1 ; +*/ if (read_count_change_val) + read_count <= #`FF_DELAY read_count_next ; +end + +// flip flop indicating error recovery is in progress +reg err_recovery_in ; +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + err_recovery <= #`FF_DELAY 1'b0 ; + else + err_recovery <= #`FF_DELAY err_recovery_in ; +end + +/*// retry counter implementation +reg [7:0] retry_count ; + +wire retry_expired = ~|(retry_count[7:1]) ; + +// loading of retry counter - whenever no request is present or other termination than retry or wait is signalled +wire retry_load = ~req_out || (~wait_in && rtransfer_in) ; + +// retry DOWN counter with load +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + retry_count <= #`FF_DELAY 8'hFF ; + else + if ( retry_load ) + retry_count <= #`FF_DELAY `PCI_RTY_CNT_MAX ; + else + if (retry_in) + retry_count <= #`FF_DELAY retry_count - 1'b1 ; +end*/ + +/*================================================================================================================== +Delayed write requests are always single transfers! +Delayed write request starts, when no request is currently beeing processed and it is signaled from other side +of the bridge. +==================================================================================================================*/ +// delayed write request FF input control +reg del_write_req_input ; + +always@( + do_del_write or + del_write_req or + posted_write_req or + del_read_req or + wait_in or + //retry_in or + //retry_expired or + rtransfer_in or + rerror_in or + mabort_in +) +begin + if (~del_write_req) + begin + // delayed write is not in progress and is requested + // delayed write can be requested when no other request is in progress + del_write_req_input = ~posted_write_req && ~del_read_req && do_del_write ; + end + else + begin + // delayed write request is in progress - assign input + del_write_req_input = wait_in || + ( /*~( retry_in && retry_expired) &&*/ + ~rtransfer_in && ~rerror_in && ~mabort_in + ); + end +end + +// delayed write request FLIP-FLOP +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + del_write_req <= #`FF_DELAY 1'b0 ; + else + del_write_req <= #`FF_DELAY del_write_req_input ; +end + +/*================================================================================================ +Posted write request indicator. +Posted write starts whenever no request is in progress and one whole posted write is +stored in WBW_FIFO. It ends on error terminations ( master, target abort, retry expired) or +data transfer terminations if last data is on top of FIFO. +Continues on wait, retry, and disconnect without data. +================================================================================================*/ +// posted write request FF input control +reg posted_write_req_input ; +always@( + do_posted_write or + del_write_req or + posted_write_req or + del_read_req or + wait_in or + //retry_in or + rerror_in or + mabort_in or + //retry_expired or + rtransfer_in or + last_transfered +) +begin + if (~posted_write_req) + begin + // posted write is not in progress + posted_write_req_input = ~del_write_req && ~del_read_req && do_posted_write ; + end + else + begin + posted_write_req_input = wait_in || + (/*~(retry_in && retry_expired && ~rtransfer_in) &&*/ + ~rerror_in && ~mabort_in && + ~(last_transfered) + ) ; + + end +end + +// posted write request flip flop +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + posted_write_req <= #`FF_DELAY 1'b0 ; + else + posted_write_req <= #`FF_DELAY posted_write_req_input ; + +end + +/*================================================================================================ +Delayed read request indicator. +Delayed read starts whenever no request is in progress and delayed read request is signaled from +other side of bridge. It ends on error terminations ( master, target abort, retry expired) or +data transfer terminations if it is not burst transfer or on cache line bounds on burst transfer. +It also ends on disconnects. +Continues on wait and retry. +================================================================================================*/ +// delayed read FF input control +reg del_read_req_input ; +always@( + do_del_read or + del_write_req or + posted_write_req or + del_read_req or + last_transfered or + wait_in or + retry_in or + //retry_expired or + mabort_in or + rtransfer_in or + rerror_in or + first_in or + del_complete_out +) +begin + if (~del_read_req) + begin + del_read_req_input = ~del_write_req && ~posted_write_req && ~del_complete_out && do_del_read ; + end + else + begin + del_read_req_input = wait_in || + ( ~(retry_in && (~first_in /*|| retry_expired */)) && + ~mabort_in && ~rerror_in && + ~(last_transfered) + ) ; + end +end + +// delayed read request FF +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + del_read_req <= #`FF_DELAY 1'b0 ; + else + del_read_req <= #`FF_DELAY del_read_req_input ; +end + +// wire indicating last entry of transaction on top of fifo +wire wlast = wbw_fifo_control_in[`LAST_CTRL_BIT] ; + +wire last_int = posted_write_req && wlast || del_write_req ; + +// intermidiate data, byte enable and last registers +reg [31:0] intermediate_data ; +reg [3:0] intermediate_be ; +reg intermediate_last ; + +wire intermediate_enable = ( posted_write_req || del_write_req ) && ( ~write_req_int || (( ~rdy_out || ~wait_in && rtransfer_in ) && ~intermediate_last)) ; + +always@(posedge reset_in or posedge clk_in) +begin + if ( reset_in ) + begin + intermediate_data <= #`FF_DELAY 32'h0000_0000 ; + intermediate_be <= #`FF_DELAY 4'h0 ; + intermediate_last <= #`FF_DELAY 1'b0 ; + end + else + if ( intermediate_enable ) + begin + intermediate_data <= #`FF_DELAY source_data ; + intermediate_be <= #`FF_DELAY source_be ; + intermediate_last <= #`FF_DELAY last_int ; + end +end + +// multiplexer for next data +reg [31:0] next_data_out ; +reg [3:0] next_be_out ; +reg write_next_last ; +reg [3:0] write_next_be ; + +always@ +( + rtransfer_in or + intermediate_data or + intermediate_be or + intermediate_last or + wbw_fifo_addr_data_in or + wbw_fifo_cbe_in or + wlast or + wait_in +) +begin + if( rtransfer_in & ~wait_in ) + begin + next_data_out = wbw_fifo_addr_data_in ; + write_next_last = wlast ; + write_next_be = wbw_fifo_cbe_in ; + end + else + begin + next_data_out = intermediate_data ; + write_next_last = intermediate_last ; + write_next_be = intermediate_be ; + end +end + +always@(del_read_req or source_be or write_next_be) +begin + if (del_read_req) + next_be_out = source_be ; + else + next_be_out = write_next_be ; +end +/*================================================================================================ +WBW_FIFO read enable - read from WBW_FIFO is performed on posted writes, when data transfer +termination is received - transfer or disconnect with data. Reads are enabled during error +recovery also, since erroneous transaction must be pulled out of FIFO! +================================================================================================*/ +// wbw_fifo read enable input control + +assign wbw_renable_out = ~req_out && (do_posted_write || err_recovery) || + posted_write_req && ( ~write_req_int || (~rdy_out && ~intermediate_last) || (~wait_in && rtransfer_in && ~intermediate_last)) ; + +/*================================================================================================ +WBR_FIFO write enable control - +writes to FIFO are possible only when delayed read request is in progress and data transfer +or error termination is signalled. It is not enabled on retry or disconnect without data. +================================================================================================*/ +// wbr_fifo write enable control - enabled when transfer is in progress and data is transfered or error is signalled +assign wbr_fifo_wenable_out = del_read_req && ~wait_in && ( rtransfer_in || mabort_in || rerror_in ) ; + +/*================================================================================================ +WBR_FIFO control output for identifying data entries. +This is necesary because of prefetched reads, which partially succeed. On error, error entry +gets in to signal it on WISHBONE bus if WISHBONE master reads up to this entry. +================================================================================================*/ +assign wbr_fifo_control_out[`ADDR_CTRL_BIT] = 1'b0 ; +assign wbr_fifo_control_out[`LAST_CTRL_BIT] = last_transfered ; +assign wbr_fifo_control_out[`DATA_ERROR_CTRL_BIT] = rerror_in || (mabort_in && ~conf_cyc_bc) ; +assign wbr_fifo_control_out[`UNUSED_CTRL_BIT] = 1'b0 ; + +// retry expired error for posted writes control +//assign err_rty_exp_out = posted_write_req && ~wait_in && retry_in && retry_expired && ~rtransfer_in; +assign err_rty_exp_out = 1'b0 ; + +// error source and error signal output control logic - only for posted writes +assign err_source_out = mabort_in /*|| err_rty_exp_out*/ ; + +assign err_signal_out = /*err_rty_exp_out || */ posted_write_req && ~wait_in && (mabort_in || rerror_in) ; + +//assign del_rty_exp_out = (~wait_in && (del_read_req || del_write_req)) && (retry_in && retry_expired && ~rtransfer_in) ; +assign del_rty_exp_out = 1'b0 ; + +assign del_error_out = ~wait_in && (del_write_req || del_read_req) && ( (mabort_in && ~conf_cyc_bc) || rerror_in ) ; + +wire del_write_complete = del_write_req && ~wait_in && ( rtransfer_in || rerror_in || mabort_in ) ; +wire del_read_complete = del_read_req && ~wait_in && ( rerror_in || mabort_in || last_transfered || ( retry_in && ~first_in ) ) ; + +assign del_complete_out = ~wait_in && ( del_write_complete || del_read_complete ) ; + +// next last output generation +assign next_last_out = del_write_req || del_read_req && ( ~del_burst_in || read_bound ) || posted_write_req && ( write_next_last ) ; +/*================================================================================================================== +Error recovery FF gets a value of one, when during posted write error occurs. It is cleared when all the data provided +for erroneous transaction is pulled out of WBW_FIFO +==================================================================================================================*/ + +// error recovery flip flop input - used when posted write is terminated with an error +always@( + err_recovery or + last_out or + wlast or + err_signal_out or + intermediate_last +) +begin + // when error recovery is not set - drive its input so it gets set + if ( ~err_recovery ) + err_recovery_in = ~last_out && ~intermediate_last && err_signal_out ; + else + // when error recovery is set, wbw_fifo is enabled - clear err_recovery when last data entry of erroneous transaction is pulled out of fifo + err_recovery_in = ~wlast ; +end + +wire data_out_load = (posted_write_req || del_write_req) && ( !rdy_out || ( !wait_in && rtransfer_in ) ) ; + +wire be_out_load = (req_out && !rdy_out) || ( posted_write_req && !wait_in && rtransfer_in ) ; + +wire last_load = req_out && ( ~rdy_out || ~wait_in && wtransfer_in ) ; + +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + data_out <= #`FF_DELAY 32'h0000_0000 ; + else + if ( data_out_load ) + data_out <= #`FF_DELAY intermediate_data ; +end + +always@(posedge clk_in or posedge reset_in) +begin + if ( reset_in ) + be_out <= #`FF_DELAY 4'hF ; + else + if ( be_out_load ) + be_out <= #`FF_DELAY posted_write_req ? intermediate_be : source_be ; +end + +always@(posedge reset_in or posedge clk_in) +begin + if (reset_in) + current_last <= #`FF_DELAY 1'b0 ; + else + if ( last_load ) + current_last <= #`FF_DELAY next_last_out ; +end + +assign last_out = current_last ; +endmodule