//----------------------------------------------------------------------------
// ACE address unpacking
//
// An ACE read/write request can specify a burst while only providing the
// address for the first transfer in the burst. To access the validation
// memory resources these 'packed' addresses are unpacked into a series of
// requests, each providing the full address.
//----------------------------------------------------------------------------
// Unpacked write address/control
.unpk_addr_o (unpk_wr_addr),
.unpk_last_o (unpk_wr_last),
.unpk_valid_o (unpk_wr_valid),
.unpk_ready_i (unpk_wr_ready)
);
// The ACE write address channel is stalled until the ACE write channel
// provides data on a completed W channel handshake.
//
// However, for the last beat of the burst the stall is extended until the end
// of the ACE write response channel handshake. This is required so that no
// other requests on the AW channel are started until the current request has
// completely cleared; the address unpacker can only handle a single
// outstanding write.
assign unpk_wr_ready = (ace_wvalid_i & ace_wready & ~unpk_wr_last) |
(ace_bvalid & ace_bready_i);
// ARID register:
// Capture ARID on a completed ACE AR handskake to form the correct ID for
// the read response
always @ (posedge clk or negedge reset_n)
if (!reset_n)
ace_arid_reg <= {(AXI_SRAM_ID){1'b0}};
else if (ace_arid_reg_we)
ace_arid_reg <= ace_arid_i;
// read data delay a cycle and rid need delay a cycle
always @ (posedge clk or negedge reset_n)
if (!reset_n)
ace_arid_d2 <= {(AXI_SRAM_ID){1'b0}};
else
ace_arid_d2 <= ace_arid_reg;
// RID:
// RID will normally be from ace_arid_reg, but because we can accept the
// next AR request while waiting for the previous request's RREADY we have
// to cover this extra window.
always @ (posedge clk or negedge reset_n)
if (!reset_n)
ace_rid <= {(AXI_SRAM_ID){1'b0}};
else if (ace_rid_we)
ace_rid <= ace_arid_d2;
// BID:
// Takes a copy of AWID when the write address handshake is complete.
// Bits[1:0] of the ID contains the CPU number of the CPU that made the
// request.
always @ (posedge clk or negedge reset_n)
if (!reset_n)
ace_bid <= {(AXI_SRAM_ID){1'b0}};
else if (ace_bid_we)
ace_bid <= ace_awid_i;
assign ace_bid_we = ace_awready & ace_awvalid_i;
//----------------------------------------------------------------------------
// Write channel handshake
//
// Once a write address handshake has completed, writes for that transaction
// do not incur any stalls. Therefore WREADY is brought high after a write
// address handshake and stays high until the handshake for the last data
// beat completes and the write response has handshaked.
//
// We must wait for the write response handshake to complete so as not to
// handshake any new write transactions that the processor may have
// presented.
//----------------------------------------------------------------------------
always @ (posedge clk or negedge reset_n)
if (!reset_n)
ace_wready <= 1'b0;
else
ace_wready <= nxt_ace_wready;
assign nxt_ace_wready = unpk_wr_valid & preproc_valid & // Ongoing write
~(ace_wvalid_i & ace_wready & ace_wlast_i) & // Not last beat
~ace_bvalid; // Not waiting for BREAD
// unpk_valid delay one cycle for val_write_i
always @ (posedge clk or negedge reset_n)
if (!reset_n)
unpk_wr_valid_d1 <= 1'b0;
else
unpk_wr_valid_d1 <= unpk_wr_valid;
// unpk_valid delay 2 cycle for val_write_i
always @ (posedge clk or negedge reset_n)
if (!reset_n)
unpk_wr_valid_d2 <= 1'b0;
else
unpk_wr_valid_d2 <= unpk_wr_valid_d1;
//----------------------------------------------------------------------------
// Write response channel handshake
//
// The write response is driven after the final beat of write data has been
// written (i.e. its write handshake has completed.) BVALID stays high
// until the processor completes the handshake.
//----------------------------------------------------------------------------
always @ (posedge clk or negedge reset_n)
if (!reset_n)
ace_bvalid <= 1'b0;
else
ace_bvalid <= nxt_ace_bvalid;
//----------------------------------------------------------------------------
// Read channel data register and handshake
//
// Read data from the validation memory model is registered before being
// sent to the processor.
//
// RVALID is set high at the same time and stays high until the processor
// completes the handshake.
//----------------------------------------------------------------------------
// Drive RLAST from the unpacked interface when the read is ongoing
always @ (posedge clk or negedge reset_n)
if (!reset_n)
ace_rlast <= 1'b0;
else if (ace_rvalid & ace_rready_i & ace_rlast)
ace_rlast <= 1'b0;
else if (val_read_d2)
ace_rlast <= unpk_rd_last_d2;
always @ (posedge clk or negedge reset_n)
if (!reset_n)
unpk_rd_last_d1 <= 1'b0;
else
unpk_rd_last_d1 <= unpk_rd_last;
always @ (posedge clk or negedge reset_n)
if (!reset_n)
unpk_rd_last_d2 <= 1'b0;
else
unpk_rd_last_d2 <= unpk_rd_last_d1;
// The validation memories never give an error response
assign ace_rresp = 2'b00; // OKAY response
//----------------------------------------------------------------------------
// Validation read/write valid
//
// A read to the validation memory interface is valid when the address
// unpacker signals a valid read and we are not waiting on RREADY (which
// stalls the next read.)
//
// Since write data is accepted as soon as it is provided by the processor,
// a write to the validation memory interface is valid when there's
// a completed ACE write channel handshake.
//----------------------------------------------------------------------------
always @ (posedge clk or negedge reset_n)
if (!reset_n)
val_read_d1 <= 1'b0;
else
val_read_d1 <= val_read;
always @ (posedge clk or negedge reset_n)
if (!reset_n)
val_read_d2 <= 1'b0;
else
val_read_d2 <= val_read_d1;
// Set a flag when a read is sent to the validation components and stays high
// until the read data is presented to the ACE interface, accounting for any
// stalls from the RVALID/RREADY handshake
assign val_rd_ongoing = ~empty_b1 | (val_rd_ongoing_reg & ~(ace_rvalid & ace_rready_i));
always @ (posedge clk or negedge reset_n)
if (!reset_n)
val_rd_ongoing_reg <= 1'b0;
else
val_rd_ongoing_reg <= val_rd_ongoing;
//----------------------------------------------------------------------------
// System address decoder
//
// The validation memory starts at address 0x000_0000_0000 and aliases
// through the whole memory map, except for the region 0x000_1300_0000 to
// 0x000_13FF_FFFF which is reserved for the tube and trickbox registers.
//
// This region contains:
//
// 0x000_1300_0000 : Tube
// 0x000_1300_0008 : Trickbox - FIQ counter load
// 0x000_1300_000C : Trickbox - FIQ clear
//
// Other locations in the trickbox region are reserved.
//----------------------------------------------------------------------------