1891 lines
103 KiB
Systemverilog
1891 lines
103 KiB
Systemverilog
// (C) 2001-2015 Altera Corporation. All rights reserved.
|
|
// Your use of Altera Corporation's design tools, logic functions and other
|
|
// software and tools, and its AMPP partner logic functions, and any output
|
|
// files any of the foregoing (including device programming or simulation
|
|
// files), and any associated documentation or information are expressly subject
|
|
// to the terms and conditions of the Altera Program License Subscription
|
|
// Agreement, Altera MegaCore Function License Agreement, or other applicable
|
|
// license agreement, including, without limitation, that your use is for the
|
|
// sole purpose of programming logic devices manufactured by Altera and sold by
|
|
// Altera or its authorized distributors. Please refer to the applicable
|
|
// agreement for further details.
|
|
|
|
|
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_burst_adapter/new_source/altera_merlin_burst_adapter_new.sv#1 $
|
|
// $Revision: #1 $
|
|
// $Date: 2015/08/09 $
|
|
// $Author: swbranch $
|
|
|
|
`timescale 1 ns / 1 ns
|
|
|
|
// -------------------------------------------------------------------
|
|
// Merlin Burst Adapter: converts incoming burst packets to fit slave burst
|
|
// capabilities.
|
|
// -------------------------------------------------------------------
|
|
module altera_merlin_burst_adapter_new
|
|
#(
|
|
parameter
|
|
// Standard merlin packet parameters that indicate
|
|
// field position within the packet
|
|
PKT_BEGIN_BURST = 81,
|
|
PKT_ADDR_H = 79,
|
|
PKT_ADDR_L = 48,
|
|
PKT_BYTE_CNT_H = 5,
|
|
PKT_BYTE_CNT_L = 0,
|
|
PKT_BURSTWRAP_H = 11,
|
|
PKT_BURSTWRAP_L = 6,
|
|
PKT_TRANS_COMPRESSED_READ = 14,
|
|
PKT_TRANS_WRITE = 13,
|
|
PKT_TRANS_READ = 12,
|
|
PKT_BYTEEN_H = 83,
|
|
PKT_BYTEEN_L = 80,
|
|
PKT_BURST_TYPE_H = 88,
|
|
PKT_BURST_TYPE_L = 87,
|
|
PKT_BURST_SIZE_H = 86,
|
|
PKT_BURST_SIZE_L = 84,
|
|
ST_DATA_W = 89,
|
|
ST_CHANNEL_W = 8,
|
|
|
|
// The values here are used to infer the slave's maximum
|
|
// burst count and constant wrapping boundary (if it exists)
|
|
OUT_BYTE_CNT_H = 5,
|
|
OUT_BURSTWRAP_H = 11,
|
|
|
|
// Indicates if incoming packets can have sizes less
|
|
// than the data width
|
|
IN_NARROW_SIZE = 0,
|
|
|
|
// Indicates if the endpoint slave can accept packets
|
|
// with sizes less than the data width
|
|
OUT_NARROW_SIZE = 0,
|
|
|
|
// Indicates if the endpoint slave can accept fixed bursts
|
|
OUT_FIXED = 0,
|
|
|
|
// Indicates if the endpoint slave can accept wrap bursts
|
|
OUT_COMPLETE_WRAP = 0,
|
|
|
|
// Enables byteenable synthesis, used to convert size to
|
|
// byteenables
|
|
BYTEENABLE_SYNTHESIS = 0,
|
|
|
|
// A mask that indicates which bits of the burstwrap field are
|
|
// constant. Used for optimization purposes.
|
|
BURSTWRAP_CONST_MASK = 0,
|
|
|
|
// Indicates the value of burstwrap bits that are constant when
|
|
// used with BURSTWRAP_CONST_MASK
|
|
BURSTWRAP_CONST_VALUE = -1,
|
|
|
|
// Controls wrapping support. For optimization purposes.
|
|
NO_WRAP_SUPPORT = 0,
|
|
INCOMPLETE_WRAP_SUPPORT = 1,
|
|
|
|
// Pipelining options
|
|
PIPE_INPUTS = 0,
|
|
PIPE_INTERNAL = 0
|
|
)
|
|
(
|
|
input clk,
|
|
input reset,
|
|
|
|
// -------------------
|
|
// Command Sink (Input)
|
|
// -------------------
|
|
input sink0_valid,
|
|
input [ST_DATA_W - 1 : 0] sink0_data,
|
|
input [ST_CHANNEL_W - 1 : 0] sink0_channel,
|
|
input sink0_startofpacket,
|
|
input sink0_endofpacket,
|
|
output reg sink0_ready,
|
|
|
|
// -------------------
|
|
// Command Source (Output)
|
|
// -------------------
|
|
output reg source0_valid,
|
|
output reg [ST_DATA_W - 1 : 0] source0_data,
|
|
output reg [ST_CHANNEL_W - 1 : 0] source0_channel,
|
|
output reg source0_startofpacket,
|
|
output reg source0_endofpacket,
|
|
input source0_ready
|
|
);
|
|
|
|
// Widths of various fields in the packet
|
|
localparam
|
|
PKT_BYTE_CNT_W = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1,
|
|
PKT_ADDR_W = PKT_ADDR_H - PKT_ADDR_L + 1,
|
|
PKT_BYTEEN_W = PKT_BYTEEN_H - PKT_BYTEEN_L + 1,
|
|
OUT_BYTE_CNT_W = OUT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1,
|
|
OUT_BURSTWRAP_W = OUT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1,
|
|
PKT_BURSTWRAP_W = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1,
|
|
PKT_BURST_SIZE_W = PKT_BURST_SIZE_H - PKT_BURST_SIZE_L + 1,
|
|
PKT_BURST_TYPE_W = PKT_BURST_TYPE_H - PKT_BURST_TYPE_L + 1;
|
|
|
|
localparam
|
|
NUM_SYMBOLS = PKT_BYTEEN_H - PKT_BYTEEN_L + 1,
|
|
LOG2_NUM_SYMBOLS = log2ceil(NUM_SYMBOLS),
|
|
ADDR_MASK_SEL = (NUM_SYMBOLS == 1) ? 1 : log2ceil(NUM_SYMBOLS);
|
|
|
|
// We try to keep everything in terms of words (transfers) instead of
|
|
// bytes in this implementation. Cognitive ease!
|
|
localparam
|
|
IN_LEN_W = PKT_BYTE_CNT_W - LOG2_NUM_SYMBOLS,
|
|
MAX_IN_LEN = 1 << (IN_LEN_W - 1),
|
|
OUT_LEN_W = OUT_BYTE_CNT_W - LOG2_NUM_SYMBOLS,
|
|
MAX_OUT_LEN = 1 << (OUT_LEN_W - 1),
|
|
|
|
BNDRY_WIDTH = PKT_BURSTWRAP_W,
|
|
OUT_BOUNDARY = MAX_OUT_LEN * NUM_SYMBOLS,
|
|
BYTE_TO_WORD_SHIFT = log2ceil(NUM_SYMBOLS),
|
|
BYTE_TO_WORD_SHIFT_W = log2ceil(BYTE_TO_WORD_SHIFT) + 1;
|
|
|
|
// Determines the protocol from the features that are enabled or disabled.
|
|
// Should be moved to the code that parameterizes this adapter.
|
|
localparam
|
|
AXI_SLAVE = OUT_FIXED & OUT_NARROW_SIZE & OUT_COMPLETE_WRAP,
|
|
IS_WRAP_AVALON_SLAVE = !AXI_SLAVE & (PKT_BURSTWRAP_H != OUT_BURSTWRAP_H),
|
|
IS_INCR_SLAVE = !AXI_SLAVE & !IS_WRAP_AVALON_SLAVE,
|
|
NON_BURSTING_SLAVE = (MAX_OUT_LEN == 1),
|
|
// This parameter indicates that the system is purely INCR avalon master/slave
|
|
INCR_AVALON_SYS = IS_INCR_SLAVE && (PKT_BURSTWRAP_W == 1) && (OUT_BURSTWRAP_W == 1) && (IN_NARROW_SIZE == 0);
|
|
|
|
// ---------------------------------------------------
|
|
// State definitions
|
|
// ---------------------------------------------------
|
|
typedef enum bit [1:0] {
|
|
|
|
// The idle state.
|
|
ST_IDLE = 2'b00,
|
|
|
|
// Adapter enters this state when the converters accept a compressed
|
|
// transaction (read). Address and burst length is calculated
|
|
// for every output transfer.
|
|
ST_COMP_TRANS = 2'b01,
|
|
|
|
// Adapter enters this state when the converters accept uncompressed
|
|
// transactions (writes, generally). Address is passed through and
|
|
// burst length is decremented according to the conventions of the
|
|
// packet format.
|
|
ST_UNCOMP_TRANS = 2'b10
|
|
} t_state;
|
|
|
|
t_state state, next_state;
|
|
|
|
// ---------------------------------------------------
|
|
// Merlin packet burst type encoding
|
|
// ---------------------------------------------------
|
|
typedef enum bit[1:0]
|
|
{
|
|
FIXED = 2'b00,
|
|
INCR = 2'b01,
|
|
WRAP = 2'b10,
|
|
REP_WRAP = 2'b11
|
|
} BurstType;
|
|
|
|
// ---------------------------------------------------
|
|
// Here we go!
|
|
//
|
|
// An optional input pipeline stage. We typically do not use this
|
|
// because the interconnect allows users to add pipelines just
|
|
// before the burst adapter inputs.
|
|
//
|
|
// Signal prefix entering this stage: sink0_*
|
|
// Signal prefix exiting this stage: sink0_pipe_*
|
|
// ---------------------------------------------------
|
|
wire sink0_pipe_valid;
|
|
wire [ST_DATA_W - 1 : 0] sink0_pipe_data;
|
|
wire [ST_CHANNEL_W - 1 : 0] sink0_pipe_channel;
|
|
wire sink0_pipe_sop;
|
|
wire sink0_pipe_eop;
|
|
wire sink0_pipe_ready;
|
|
|
|
generate
|
|
if (PIPE_INPUTS == 1) begin : input_pipeline
|
|
altera_avalon_st_pipeline_stage #(
|
|
.SYMBOLS_PER_BEAT (1),
|
|
.BITS_PER_SYMBOL (ST_DATA_W),
|
|
.USE_PACKETS (1),
|
|
.USE_EMPTY (0),
|
|
.EMPTY_WIDTH (0),
|
|
.CHANNEL_WIDTH (ST_CHANNEL_W),
|
|
.PACKET_WIDTH (2),
|
|
.ERROR_WIDTH (0),
|
|
.PIPELINE_READY (1)
|
|
) input_pipe (
|
|
.clk (clk),
|
|
.reset (reset),
|
|
|
|
.in_ready (sink0_ready),
|
|
.in_valid (sink0_valid),
|
|
.in_startofpacket (sink0_startofpacket),
|
|
.in_endofpacket (sink0_endofpacket),
|
|
.in_data (sink0_data),
|
|
.in_channel (sink0_channel),
|
|
|
|
.out_ready (sink0_pipe_ready),
|
|
.out_valid (sink0_pipe_valid),
|
|
.out_startofpacket (sink0_pipe_sop),
|
|
.out_endofpacket (sink0_pipe_eop),
|
|
.out_data (sink0_pipe_data),
|
|
.out_channel (sink0_pipe_channel),
|
|
|
|
.in_empty (1'b0),
|
|
.in_error (1'b0),
|
|
.out_empty (),
|
|
.out_error ()
|
|
);
|
|
end
|
|
else begin : no_input_pipeline
|
|
|
|
assign sink0_pipe_valid = sink0_valid;
|
|
assign sink0_pipe_data = sink0_data;
|
|
assign sink0_pipe_channel = sink0_channel;
|
|
assign sink0_pipe_sop = sink0_startofpacket;
|
|
assign sink0_pipe_eop = sink0_endofpacket;
|
|
assign sink0_ready = sink0_pipe_ready;
|
|
|
|
end
|
|
endgenerate
|
|
|
|
// --------------------------------------------------
|
|
// Signal extraction stage. We extract signals from
|
|
// the packet payload and compute some values.
|
|
//
|
|
// Signal prefix entering this stage: sink0_pipe_*
|
|
// Signal prefix exiting this stage: in_*
|
|
// --------------------------------------------------
|
|
wire [PKT_BURST_TYPE_W - 1 : 0] in_bursttype = sink0_pipe_data[PKT_BURST_TYPE_H : PKT_BURST_TYPE_L];
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] in_bytecount = sink0_pipe_data[PKT_BYTE_CNT_H : PKT_BYTE_CNT_L];
|
|
wire [PKT_ADDR_W - 1 : 0] in_addr = sink0_pipe_data[PKT_ADDR_H : PKT_ADDR_L];
|
|
wire [63 : 0] log2_numsymbols = log2ceil(NUM_SYMBOLS);
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] in_burstcount = in_bytecount >> log2_numsymbols[PKT_BYTE_CNT_W - 1 : 0];
|
|
wire [IN_LEN_W - 1 : 0] in_len = in_burstcount[IN_LEN_W - 1 : 0];
|
|
wire [PKT_BURST_SIZE_W - 1 : 0] in_size = sink0_pipe_data[PKT_BURST_SIZE_H : PKT_BURST_SIZE_L];
|
|
wire in_write = sink0_pipe_data[PKT_TRANS_WRITE];
|
|
wire in_compressed_read = sink0_pipe_data[PKT_TRANS_COMPRESSED_READ];
|
|
wire in_read = sink0_pipe_data[PKT_TRANS_READ];
|
|
wire in_uncompressed_read = in_read & ~sink0_pipe_data[PKT_TRANS_COMPRESSED_READ];
|
|
wire in_sop = sink0_pipe_sop;
|
|
wire in_eop = sink0_pipe_eop;
|
|
wire [PKT_BYTEEN_W - 1 : 0] in_byteen = sink0_pipe_data[PKT_BYTEEN_H : PKT_BYTEEN_L];
|
|
wire in_passthru = in_burstcount <= 16;
|
|
|
|
wire in_valid;
|
|
reg in_ready_hold;
|
|
wire in_narrow;
|
|
wire [PKT_BURSTWRAP_W - 1 : 0] in_burstwrap;
|
|
wire [PKT_ADDR_W - 1 : 0] in_aligned_addr;
|
|
wire [PKT_BURSTWRAP_W - 1 : 0] in_boundary;
|
|
|
|
// Used to keep ready low during reset
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_ready_hold <= '0;
|
|
end else begin
|
|
in_ready_hold <= '1;
|
|
end
|
|
end
|
|
|
|
assign in_valid = sink0_pipe_valid & in_ready_hold;
|
|
assign in_narrow = in_size < log2_numsymbols[PKT_BYTE_CNT_W - 1 : 0];
|
|
|
|
// Optimization: extract burstwrap, and drive the constant bits to
|
|
// their constant values to help the synthesis tool.
|
|
genvar i;
|
|
generate
|
|
for (i = 0; i < PKT_BURSTWRAP_W; i = i+1) begin: assign_burstwrap_bit
|
|
if (BURSTWRAP_CONST_MASK[i]) begin
|
|
assign in_burstwrap[i] = BURSTWRAP_CONST_VALUE[i];
|
|
end
|
|
else begin
|
|
assign in_burstwrap[i] = sink0_pipe_data[PKT_BURSTWRAP_L + i];
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
// Addresses in the packet can be unaligned. Here we align the address
|
|
// for ease of internal calculations. The initial output address may
|
|
// still be unaligned to preserve the original transaction intention.
|
|
|
|
wire [PKT_ADDR_W + LOG2_NUM_SYMBOLS - 1 : 0] out_mask_and_aligned_addr;
|
|
altera_merlin_address_alignment
|
|
#(
|
|
.ADDR_W (PKT_ADDR_W),
|
|
.BURSTWRAP_W (1), // unused because we just want to align address
|
|
.TYPE_W (0), // unused because we just want to align address
|
|
.SIZE_W (PKT_BURST_SIZE_W),
|
|
.INCREMENT_ADDRESS (0),
|
|
.NUMSYMBOLS (NUM_SYMBOLS)
|
|
) align_address_to_size
|
|
(
|
|
// Not used when INCREMENT_ADDRESS = 0
|
|
.clk (1'b0),
|
|
.reset (1'b0),
|
|
.in_valid (1'b0),
|
|
.in_sop (1'b0),
|
|
.in_eop (1'b0),
|
|
.out_ready (),
|
|
|
|
.in_data ({ in_addr, in_size }),
|
|
.out_data (out_mask_and_aligned_addr)
|
|
);
|
|
|
|
assign in_aligned_addr = out_mask_and_aligned_addr[PKT_ADDR_W - 1 : 0];
|
|
|
|
// Incrementing the burstwrap provides the wrapping boundary for
|
|
// wrapping transactions.
|
|
altera_merlin_burst_adapter_burstwrap_increment
|
|
#(
|
|
.WIDTH (PKT_BURSTWRAP_W)
|
|
) the_burstwrap_increment
|
|
(
|
|
.mask (in_burstwrap),
|
|
.inc (in_boundary)
|
|
);
|
|
|
|
localparam OUT_BNDRY_ADDR_SEL_W = log2ceil(OUT_BOUNDARY);
|
|
localparam OUT_BOUNDARY_WIDTH = OUT_BNDRY_ADDR_SEL_W + 1;
|
|
|
|
// address to use for distance calculations when the transaction
|
|
// boundary is less than the slave's wrapping boundary.
|
|
wire [PKT_ADDR_W - 1 : 0] in_bndry_addr_sel;
|
|
|
|
// the length (in words) to the transaction boundary (if it exists)
|
|
wire [IN_LEN_W - 1 : 0] len_to_in_bndry;
|
|
|
|
// the length (in words) to the slave's boundary (if it exists)
|
|
wire [OUT_BOUNDARY_WIDTH - 1 : 0] len_to_out_bndry;
|
|
|
|
reg [IN_LEN_W - 1 : 0] first_len;
|
|
wire [BYTE_TO_WORD_SHIFT_W - 1 : 0] byte_to_word_shift;
|
|
assign byte_to_word_shift = BYTE_TO_WORD_SHIFT[BYTE_TO_WORD_SHIFT_W - 1 : 0];
|
|
|
|
// This part calculates the length that is required to align the burst to
|
|
// the transaction's wrapping boundary (if it exists), or to the slave's
|
|
// wrapping boundary (if it exists). We pre-compute this ahead of the
|
|
// converters to minimize the logic loops in determining the output
|
|
// burst lengths. Note that incoming addresses for wrapping transactions
|
|
// are always aligned to size by definition.
|
|
|
|
assign in_bndry_addr_sel = in_addr & in_burstwrap;
|
|
assign len_to_in_bndry = (in_boundary - in_bndry_addr_sel) >> byte_to_word_shift;
|
|
|
|
generate
|
|
|
|
if (OUT_BNDRY_ADDR_SEL_W > 0) begin : len_to_out_bndry_calc
|
|
wire [OUT_BNDRY_ADDR_SEL_W - 1 : 0] out_bndry_addr_sel;
|
|
|
|
// We have to use the aligned address, because this part may
|
|
// handle incoming incrementing bursts which can be unaligned.
|
|
assign out_bndry_addr_sel = in_aligned_addr[OUT_BNDRY_ADDR_SEL_W - 1 : 0];
|
|
assign len_to_out_bndry = (OUT_BOUNDARY - out_bndry_addr_sel) >> byte_to_word_shift;
|
|
end
|
|
|
|
// A nonsensical corner-case of a wrapping slave with
|
|
// MAX_OUT_LEN = 1, NUM_SYMBOLS = 1
|
|
else begin : len_to_out_bndry_calc_corner
|
|
assign len_to_out_bndry = OUT_BOUNDARY >> byte_to_word_shift;
|
|
end
|
|
|
|
endgenerate
|
|
|
|
// --------------------------------------------------
|
|
// Optional internal pipeline stage.
|
|
//
|
|
// Note that we still buffer the transfer if the pipeline stage is
|
|
// unused, because the adapter must accept read transactions before
|
|
// converting them. Failure to do this will lead to masters receiving
|
|
// responses before their commands have been accepted in unpipelined
|
|
// systems. The buffering registers are named in_*_reg.
|
|
//
|
|
// Notes on signal naming convention used:
|
|
//
|
|
// in_* --> These signals are coming directly from the previous stage.
|
|
// --> Timing - zero cycle delta
|
|
// d0_in_* --> Signals that are outputs of this stage.
|
|
// --> Timing - zero cycle delta (IF PIPE_INTERNAL == 0) else 1 clock
|
|
// d1_in_* --> Signals that are outputs of this stage.
|
|
// --> Timing - always delayed by 1 clock. (vs the input)
|
|
// --------------------------------------------------
|
|
reg in_sop_reg;
|
|
reg in_eop_reg;
|
|
reg in_valid_reg;
|
|
reg in_compressed_read_reg;
|
|
reg in_uncompressed_read_reg;
|
|
reg in_write_reg;
|
|
reg in_passthru_reg;
|
|
reg [PKT_BURST_SIZE_W - 1 : 0] in_size_reg;
|
|
reg [ST_DATA_W - 1 : 0] in_data_reg;
|
|
reg [ST_CHANNEL_W - 1 : 0] in_channel_reg;
|
|
reg [PKT_BURST_TYPE_W - 1 : 0] in_bursttype_reg;
|
|
reg [PKT_BURSTWRAP_W - 1 : 0] in_burstwrap_reg;
|
|
reg [PKT_BYTEEN_W - 1 : 0] in_byteen_reg;
|
|
reg [PKT_ADDR_W - 1 : 0] in_addr_reg;
|
|
reg [PKT_ADDR_W - 1 : 0] in_aligned_addr_reg;
|
|
reg [IN_LEN_W - 1 : 0] in_len_reg;
|
|
reg in_narrow_reg;
|
|
|
|
reg [PKT_ADDR_W - 1 : 0] d0_in_addr;
|
|
reg [PKT_ADDR_W - 1 : 0] d0_in_aligned_addr;
|
|
reg d0_in_sop;
|
|
reg d0_in_compressed_read;
|
|
reg d0_in_uncompressed_read;
|
|
reg d0_in_write;
|
|
reg [PKT_BURST_TYPE_W - 1 : 0] d0_in_bursttype;
|
|
reg [PKT_BURSTWRAP_W - 1 : 0] d0_in_burstwrap;
|
|
reg [PKT_BURSTWRAP_W - 1 : 0] d0_in_burstwrap_value;
|
|
reg [PKT_BURST_SIZE_W - 1 : 0] d0_in_size;
|
|
reg [PKT_BURST_SIZE_W - 1 : 0] d0_in_size_value;
|
|
reg [IN_LEN_W - 1 : 0] d0_in_len;
|
|
reg d0_in_valid;
|
|
|
|
reg d1_in_narrow;
|
|
reg [PKT_ADDR_W - 1 : 0] d1_in_aligned_addr;
|
|
reg d1_in_eop;
|
|
reg d1_in_compressed_read;
|
|
reg d1_in_uncompressed_read;
|
|
reg [ST_DATA_W - 1 : 0] d1_in_data;
|
|
reg [ST_CHANNEL_W - 1 : 0] d1_in_channel;
|
|
reg d1_in_write;
|
|
reg [PKT_BURST_TYPE_W - 1 : 0] d1_in_bursttype;
|
|
reg [PKT_BURSTWRAP_W - 1 : 0] d1_in_burstwrap;
|
|
reg d1_in_passthru;
|
|
reg [PKT_BURST_SIZE_W - 1 : 0] d1_in_size;
|
|
reg [PKT_BYTEEN_W - 1 : 0] d1_in_byteen;
|
|
|
|
reg nb;
|
|
|
|
generate
|
|
if (PIPE_INTERNAL == 0) begin : no_internal_pipeline
|
|
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_eop_reg <= '0;
|
|
in_compressed_read_reg <= '0;
|
|
in_uncompressed_read_reg <= '0;
|
|
in_data_reg <= '0;
|
|
in_channel_reg <= '0;
|
|
in_write_reg <= '0;
|
|
in_bursttype_reg <= '0;
|
|
in_burstwrap_reg <= '0;
|
|
in_passthru_reg <= '0;
|
|
in_size_reg <= '0;
|
|
in_byteen_reg <= '0;
|
|
in_aligned_addr_reg <= '0;
|
|
in_narrow_reg <= '0;
|
|
end else begin
|
|
if (sink0_pipe_valid & sink0_pipe_ready) begin
|
|
in_eop_reg <= in_eop;
|
|
in_data_reg <= sink0_pipe_data;
|
|
in_channel_reg <= sink0_pipe_channel;
|
|
in_compressed_read_reg <= in_compressed_read;
|
|
in_uncompressed_read_reg <= in_uncompressed_read;
|
|
in_write_reg <= in_write;
|
|
in_bursttype_reg <= in_bursttype;
|
|
in_burstwrap_reg <= in_burstwrap;
|
|
in_size_reg <= in_size;
|
|
in_byteen_reg <= in_byteen;
|
|
in_aligned_addr_reg <= in_aligned_addr;
|
|
in_narrow_reg <= in_narrow;
|
|
end
|
|
// length changes during packets, so sample
|
|
// length-dependent signals at the start
|
|
if (sink0_pipe_valid & sink0_pipe_ready & in_sop) begin
|
|
in_passthru_reg <= in_passthru;
|
|
end
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
|
|
always_comb begin
|
|
d0_in_sop = in_sop;
|
|
d0_in_compressed_read = in_compressed_read;
|
|
d0_in_uncompressed_read = in_uncompressed_read;
|
|
d0_in_write = in_write;
|
|
d0_in_burstwrap = in_burstwrap;
|
|
d0_in_size = in_size;
|
|
d0_in_addr = in_addr;
|
|
d0_in_aligned_addr = in_aligned_addr;
|
|
d0_in_len = in_len;
|
|
d0_in_valid = in_valid;
|
|
|
|
d1_in_eop = in_eop_reg;
|
|
d1_in_compressed_read = in_compressed_read_reg;
|
|
d1_in_uncompressed_read = in_uncompressed_read_reg;
|
|
d1_in_write = in_write_reg;
|
|
d1_in_burstwrap = in_burstwrap_reg;
|
|
d1_in_size = in_size_reg;
|
|
d1_in_aligned_addr = in_aligned_addr_reg;
|
|
d1_in_data = in_data_reg;
|
|
d1_in_channel = in_channel_reg;
|
|
d1_in_bursttype = in_bursttype_reg;
|
|
d1_in_passthru = in_passthru_reg;
|
|
d1_in_byteen = in_byteen_reg;
|
|
d1_in_narrow = in_narrow_reg;
|
|
|
|
// Assign after the related d1_in_* signals have been assigned.
|
|
d0_in_size_value = nb ? d0_in_size : d1_in_size;
|
|
d0_in_burstwrap_value = nb ? d0_in_burstwrap : d1_in_burstwrap;
|
|
end
|
|
|
|
end // block: no_internal_pipeline
|
|
else begin : internal_pipeline
|
|
|
|
reg [PKT_BURST_SIZE_W - 1 : 0] d0_in_size_dl;
|
|
reg [PKT_BURSTWRAP_W - 1 : 0] d0_in_burstwrap_dl;
|
|
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_eop_reg <= '0;
|
|
in_sop_reg <= '0;
|
|
in_compressed_read_reg <= '0;
|
|
in_uncompressed_read_reg <= '0;
|
|
in_data_reg <= '0;
|
|
in_channel_reg <= '0;
|
|
in_write_reg <= '0;
|
|
in_bursttype_reg <= '0;
|
|
in_burstwrap_reg <= '0;
|
|
in_passthru_reg <= '0;
|
|
in_size_reg <= '0;
|
|
in_byteen_reg <= '0;
|
|
in_addr_reg <= '0;
|
|
in_aligned_addr_reg <= '0;
|
|
in_len_reg <= '0;
|
|
in_narrow_reg <= '0;
|
|
in_valid_reg <= '0;
|
|
|
|
d1_in_eop <= '0;
|
|
d1_in_compressed_read <= '0;
|
|
d1_in_data <= '0;
|
|
d1_in_channel <= '0;
|
|
d1_in_write <= '0;
|
|
d1_in_bursttype <= '0;
|
|
d1_in_burstwrap <= '0;
|
|
d1_in_passthru <= '0;
|
|
d1_in_size <= '0;
|
|
d0_in_size_dl <= '0;
|
|
d0_in_burstwrap_dl <= '0;
|
|
d1_in_byteen <= '0;
|
|
end else begin
|
|
if (sink0_pipe_valid & sink0_pipe_ready) begin
|
|
in_eop_reg <= in_eop;
|
|
in_sop_reg <= in_sop;
|
|
in_data_reg <= sink0_pipe_data;
|
|
in_channel_reg <= sink0_pipe_channel;
|
|
in_compressed_read_reg <= in_compressed_read;
|
|
in_uncompressed_read_reg <= in_uncompressed_read;
|
|
in_write_reg <= in_write;
|
|
in_bursttype_reg <= in_bursttype;
|
|
in_burstwrap_reg <= in_burstwrap;
|
|
in_size_reg <= in_size;
|
|
in_byteen_reg <= in_byteen;
|
|
in_addr_reg <= in_addr;
|
|
in_aligned_addr_reg <= in_aligned_addr;
|
|
in_len_reg <= in_len;
|
|
in_narrow_reg <= in_narrow;
|
|
end
|
|
// length changes during packets, so sample
|
|
// length-dependent signals at the start
|
|
if (in_valid & sink0_pipe_ready & in_sop)
|
|
in_passthru_reg <= in_passthru;
|
|
if (sink0_pipe_ready)
|
|
in_valid_reg <= in_valid;
|
|
if (((state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |
|
|
( (state == ST_COMP_TRANS) & (~source0_valid | source0_ready & source0_endofpacket) )) begin
|
|
d1_in_eop <= in_eop_reg;
|
|
d1_in_compressed_read <= in_compressed_read_reg;
|
|
d1_in_data <= in_data_reg;
|
|
d1_in_channel <= in_channel_reg;
|
|
d1_in_write <= in_write_reg;
|
|
d1_in_bursttype <= in_bursttype_reg;
|
|
d1_in_burstwrap <= in_burstwrap_reg;
|
|
d0_in_burstwrap_dl <= in_burstwrap_reg;
|
|
d1_in_passthru <= in_passthru_reg;
|
|
d1_in_size <= in_size_reg;
|
|
d0_in_size_dl <= in_size_reg;
|
|
d1_in_byteen <= in_byteen_reg;
|
|
d1_in_aligned_addr <= in_aligned_addr_reg;
|
|
d1_in_narrow <= in_narrow_reg;
|
|
d1_in_uncompressed_read <= in_uncompressed_read_reg;
|
|
end // if (((state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |...
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
|
|
always_comb begin
|
|
d0_in_valid = in_valid_reg;
|
|
d0_in_sop = in_sop_reg;
|
|
d0_in_compressed_read = in_compressed_read_reg;
|
|
d0_in_uncompressed_read = in_uncompressed_read_reg;
|
|
d0_in_write = in_write_reg;
|
|
d0_in_burstwrap = in_burstwrap_reg;
|
|
d0_in_size = in_size_reg;
|
|
d0_in_size_value = nb ? in_size_reg : d0_in_size_dl;
|
|
d0_in_burstwrap_value = nb ? in_burstwrap_reg : d0_in_burstwrap_dl;
|
|
d0_in_addr = in_addr_reg;
|
|
d0_in_aligned_addr = in_aligned_addr_reg;
|
|
d0_in_len = in_len_reg;
|
|
end // always_comb
|
|
end // block: internal_pipeline
|
|
|
|
endgenerate
|
|
|
|
// --------------------------------------------------
|
|
// Control logic stage: state machine
|
|
// --------------------------------------------------
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
state <= ST_IDLE;
|
|
end else begin
|
|
if (~source0_valid | source0_ready) begin
|
|
state <= next_state;
|
|
end
|
|
end
|
|
end
|
|
|
|
always_comb begin : state_transition
|
|
next_state = ST_IDLE; // default
|
|
case (state)
|
|
ST_IDLE : begin
|
|
next_state = ST_IDLE;
|
|
|
|
if (d0_in_valid) begin
|
|
if (d0_in_write | d0_in_uncompressed_read) next_state = ST_UNCOMP_TRANS;
|
|
if (d0_in_compressed_read) next_state = ST_COMP_TRANS;
|
|
end
|
|
end
|
|
|
|
ST_UNCOMP_TRANS : begin
|
|
next_state = ST_UNCOMP_TRANS;
|
|
|
|
if (source0_endofpacket) begin
|
|
if (!d0_in_valid) next_state = ST_IDLE;
|
|
else begin
|
|
if (d0_in_write | d0_in_uncompressed_read) next_state = ST_UNCOMP_TRANS;
|
|
if (d0_in_compressed_read) next_state = ST_COMP_TRANS;
|
|
end
|
|
end
|
|
end
|
|
ST_COMP_TRANS : begin
|
|
next_state = ST_COMP_TRANS;
|
|
|
|
if (source0_endofpacket) begin
|
|
if (!d0_in_valid) begin
|
|
next_state = ST_IDLE;
|
|
end
|
|
else begin
|
|
if (d0_in_write | d0_in_uncompressed_read) next_state = ST_UNCOMP_TRANS;
|
|
if (d0_in_compressed_read) next_state = ST_COMP_TRANS;
|
|
end
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
|
|
// --------------------------------------------------
|
|
// Control logic stage: signals for the converters. These signals
|
|
// enable the correct converter for a burst type, and act as a
|
|
// select line when muxing the converter outputs.
|
|
//
|
|
// Each type of slave receives its own control logic stage, optimized
|
|
// for that particular type.
|
|
// --------------------------------------------------
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] out_byte_cnt;
|
|
wire [IN_LEN_W - 1 : 0] incr_out_len;
|
|
wire [IN_LEN_W - 1 : 0] wrap_out_len;
|
|
wire [IN_LEN_W - 1 : 0] incr_uncompr_out_len;
|
|
wire [IN_LEN_W - 1 : 0] wrap_uncompr_out_len;
|
|
wire [PKT_ADDR_W - 1 : 0] incr_out_addr;
|
|
wire [PKT_ADDR_W - 1 : 0] wrap_out_addr;
|
|
wire [PKT_ADDR_W - 1 : 0] fixed_out_addr;
|
|
reg [PKT_ADDR_W - 1 : 0] uncompr_out_addr;
|
|
wire [IN_LEN_W - 1 : 0] fixed_out_len;
|
|
wire [PKT_ADDR_W - 1 : 0] out_addr;
|
|
|
|
wire in_full_size_write_wrap;
|
|
wire in_full_size_read_wrap;
|
|
wire in_default_converter;
|
|
wire in_full_size_incr;
|
|
reg in_default_converter_reg;
|
|
reg in_full_size_incr_reg;
|
|
reg in_full_size_write_wrap_reg;
|
|
reg in_full_size_read_wrap_reg;
|
|
|
|
wire new_burst;
|
|
wire fixed_new_burst;
|
|
wire wrap_new_burst;
|
|
wire incr_new_burst;
|
|
|
|
wire next_out_sop;
|
|
wire next_out_eop;
|
|
wire is_passthru;
|
|
wire enable_incr_converter;
|
|
wire enable_fixed_converter;
|
|
wire enable_write_wrap_converter;
|
|
wire enable_read_wrap_converter;
|
|
wire enable_incr_write_converter;
|
|
wire enable_incr_read_converter;
|
|
reg [IN_LEN_W - 1 : 0] d0_first_len;
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Enable the converters when:
|
|
// - (sink0_pipe_valid && (source0_ready | ~source0_valid):
|
|
// : when the BA is in idle (!source_valid) and there is a packet coming at input
|
|
// or the outpacket has been accepted and there is a packet coming
|
|
// - (source0_endofpacket ? 1'b0 :(state == ST_COMP_TRANS) && (!source0_valid | source0_ready))
|
|
// : For compressed read, need something consider at end_of_packet, only when seeing
|
|
// end_of_packet then turn off converter.
|
|
// Each converter will be turned on with its own enable based on different type of incoming burst
|
|
// -----------------------------------------------------------------------
|
|
generate
|
|
if (NON_BURSTING_SLAVE) begin : non_bursting_converter_control
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] fixed_out_byte_cnt;
|
|
assign fixed_out_byte_cnt = fixed_out_len << log2_numsymbols;
|
|
|
|
if (PIPE_INTERNAL == 0) begin : NO_PIPELINE_INPUT
|
|
always_comb begin
|
|
d0_in_bursttype = nb ? in_bursttype : in_bursttype_reg;
|
|
end
|
|
end
|
|
else begin : PIPELINE_INPUT
|
|
reg [PKT_BURST_TYPE_W - 1 :0] d0_in_bursttype_dl;
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
d0_in_bursttype_dl <= '0;
|
|
end else begin
|
|
if (((state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |
|
|
( (state == ST_COMP_TRANS) & (~source0_valid | source0_ready & source0_endofpacket) ) ) begin
|
|
d0_in_bursttype_dl <= in_bursttype_reg;
|
|
end
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
always_comb begin
|
|
d0_in_bursttype = nb ? in_bursttype_reg : d0_in_bursttype_dl;
|
|
end
|
|
end
|
|
|
|
//nb: new burst signal
|
|
assign nb = fixed_new_burst;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// I. Conveter enable signals: Turn on/off each conveter accordingly
|
|
// -----------------------------------------------------------------------
|
|
assign enable_fixed_converter = (d0_in_valid && (source0_ready | !source0_valid) || (source0_endofpacket ? 1'b0 :(state == ST_COMP_TRANS) && (!source0_valid | source0_ready)));
|
|
|
|
// -----------------------------------------------------------------------
|
|
// II. Packet signals
|
|
// -----------------------------------------------------------------------
|
|
assign next_out_sop = ((state == ST_COMP_TRANS) & source0_ready & !(fixed_new_burst)) ? 1'b0 : d0_in_sop;
|
|
assign next_out_eop = (state == ST_COMP_TRANS) ? fixed_new_burst : d1_in_eop;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// III. Output select
|
|
// -----------------------------------------------------------------------
|
|
assign out_byte_cnt = fixed_out_byte_cnt;
|
|
assign out_addr = fixed_out_addr;
|
|
end
|
|
else if (INCR_AVALON_SYS) begin : incr_avalon_converter_control
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] incr_out_byte_cnt;
|
|
assign incr_out_byte_cnt = (d1_in_compressed_read ? incr_out_len : incr_uncompr_out_len) << log2_numsymbols;
|
|
|
|
//nb: new burst signal
|
|
assign nb = incr_new_burst;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// I. Conveter enable signals: Turn on/off each conveter accordingly
|
|
// -----------------------------------------------------------------------
|
|
assign enable_incr_converter = (d0_in_valid && (source0_ready | !source0_valid) || (source0_endofpacket ? 1'b0 :(state == ST_COMP_TRANS) && (!source0_valid | source0_ready)));
|
|
|
|
// -----------------------------------------------------------------------
|
|
// II. Packet signals
|
|
// -----------------------------------------------------------------------
|
|
assign next_out_sop = ((state == ST_COMP_TRANS) & source0_ready & !(incr_new_burst)) ? 1'b0 : d0_in_sop;
|
|
assign next_out_eop = (state == ST_COMP_TRANS) ? incr_new_burst : d1_in_eop;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// III. Output select
|
|
// -----------------------------------------------------------------------
|
|
assign out_byte_cnt = incr_out_byte_cnt;
|
|
assign out_addr = incr_out_addr;
|
|
end
|
|
else begin : other_converter_control
|
|
if (IS_WRAP_AVALON_SLAVE) begin
|
|
wire in_narrow_or_fixed;
|
|
wire in_read_but_not_fixed_or_narrow;
|
|
wire in_write_but_not_fixed_or_narrow;
|
|
reg in_read_but_not_fixed_or_narrow_reg;
|
|
reg in_write_but_not_fixed_or_narrow_reg;
|
|
reg in_narrow_or_fixed_reg;
|
|
reg d0_in_read_but_not_fixed_or_narrow;
|
|
reg d0_in_write_but_not_fixed_or_narrow;
|
|
reg d0_in_default_converter;
|
|
reg d1_in_narrow_or_fixed;
|
|
reg d1_in_read_but_not_fixed_or_narrow;
|
|
reg d1_in_write_but_not_fixed_or_narrow;
|
|
reg d1_in_default_converter;
|
|
reg [IN_LEN_W - 1 : 0] first_len_reg;
|
|
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] fixed_out_byte_cnt;
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] incr_out_byte_cnt;
|
|
wire in_fixed = (in_bursttype == 2'b00) || (in_bursttype == 2'b11);
|
|
|
|
// nb: new burst
|
|
assign nb = (d1_in_narrow_or_fixed ? fixed_new_burst : new_burst);
|
|
assign in_read_but_not_fixed_or_narrow = in_compressed_read & !in_narrow_or_fixed;
|
|
assign in_write_but_not_fixed_or_narrow = in_write & !in_narrow_or_fixed;
|
|
assign in_narrow_or_fixed = in_narrow || in_fixed;
|
|
assign in_default_converter = in_fixed || in_narrow || in_uncompressed_read;
|
|
assign incr_out_byte_cnt = (d1_in_compressed_read ? incr_out_len : incr_uncompr_out_len) << log2_numsymbols;
|
|
assign fixed_out_byte_cnt = fixed_out_len << log2_numsymbols;
|
|
|
|
//----------------------------------------------------------------
|
|
// I. Pipeline input stage
|
|
//----------------------------------------------------------------
|
|
if (PIPE_INTERNAL == 0) begin : NO_PIPELINE_INPUT
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_narrow_or_fixed_reg <= '0;
|
|
in_read_but_not_fixed_or_narrow_reg <= '0;
|
|
in_write_but_not_fixed_or_narrow_reg <= '0;
|
|
in_default_converter_reg <= '0;
|
|
end else begin
|
|
if (sink0_pipe_ready & sink0_pipe_valid) begin
|
|
in_narrow_or_fixed_reg <= in_narrow_or_fixed;
|
|
in_read_but_not_fixed_or_narrow_reg <= in_read_but_not_fixed_or_narrow;
|
|
in_write_but_not_fixed_or_narrow_reg <= in_write_but_not_fixed_or_narrow;
|
|
in_default_converter_reg <= in_default_converter;
|
|
end // if (sink0_pipe_ready & sink0_pipe_valid)
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
always_comb begin
|
|
d0_first_len = first_len;
|
|
d0_in_read_but_not_fixed_or_narrow = in_read_but_not_fixed_or_narrow;
|
|
d0_in_write_but_not_fixed_or_narrow = in_write_but_not_fixed_or_narrow;
|
|
d0_in_default_converter = in_default_converter;
|
|
d1_in_narrow_or_fixed = in_narrow_or_fixed_reg;
|
|
d1_in_read_but_not_fixed_or_narrow = in_read_but_not_fixed_or_narrow_reg;
|
|
d1_in_write_but_not_fixed_or_narrow = in_write_but_not_fixed_or_narrow_reg;
|
|
d1_in_default_converter = in_default_converter_reg;
|
|
end // always_comb
|
|
end // block: NO_PIPELINE_INPUT
|
|
else begin : PIPELINE_INPUT
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_narrow_or_fixed_reg <= '0;
|
|
in_read_but_not_fixed_or_narrow_reg <= '0;
|
|
in_write_but_not_fixed_or_narrow_reg <= '0;
|
|
in_default_converter_reg <= '0;
|
|
d1_in_narrow_or_fixed <= '0;
|
|
d1_in_read_but_not_fixed_or_narrow <= '0;
|
|
d1_in_write_but_not_fixed_or_narrow <= '0;
|
|
d1_in_default_converter <= '0;
|
|
first_len_reg <= '0;
|
|
end else begin
|
|
if (sink0_pipe_ready & sink0_pipe_valid) begin
|
|
in_narrow_or_fixed_reg <= in_narrow_or_fixed;
|
|
in_read_but_not_fixed_or_narrow_reg <= in_read_but_not_fixed_or_narrow;
|
|
in_write_but_not_fixed_or_narrow_reg <= in_write_but_not_fixed_or_narrow;
|
|
in_default_converter_reg <= in_default_converter;
|
|
end // if (sink0_pipe_ready & sink0_pipe_valid)
|
|
if (((state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |
|
|
( (state == ST_COMP_TRANS) & (~source0_valid | source0_ready & source0_endofpacket) ) ) begin
|
|
first_len_reg <= first_len;
|
|
d1_in_narrow_or_fixed <= in_narrow_or_fixed_reg;
|
|
d1_in_read_but_not_fixed_or_narrow <= in_read_but_not_fixed_or_narrow_reg;
|
|
d1_in_write_but_not_fixed_or_narrow <= in_write_but_not_fixed_or_narrow_reg;
|
|
d1_in_default_converter <= in_default_converter_reg;
|
|
end
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
always_comb begin
|
|
d0_in_default_converter = in_default_converter_reg;
|
|
d0_first_len = first_len_reg;
|
|
d0_in_read_but_not_fixed_or_narrow = in_read_but_not_fixed_or_narrow_reg;
|
|
d0_in_write_but_not_fixed_or_narrow = in_write_but_not_fixed_or_narrow_reg;
|
|
end
|
|
end // block: PIPELINE_INPUT
|
|
|
|
// -------------------------------------------------------------------------
|
|
// II. First length calculation
|
|
// -------------------------------------------------------------------------
|
|
wire same_boundary;
|
|
// ----------------------------------------------------------
|
|
// Slave is a wrapping slave, if in_burst wrap has same boundary
|
|
// pass the burst untouched.
|
|
// ----------------------------------------------------------
|
|
if (OUT_BNDRY_ADDR_SEL_W <= PKT_BURSTWRAP_W - 1) begin
|
|
assign same_boundary = (in_boundary[OUT_BNDRY_ADDR_SEL_W] == 1);
|
|
end else begin
|
|
assign same_boundary = 0;
|
|
end
|
|
|
|
// --------------------------------------------------------------------------
|
|
// 1. If in_burst wrapping boundary is lager or INCR burst then always
|
|
// send first sub_burst length is aligned to slave boudary,
|
|
// 2. Else aligned to master boundary
|
|
// Notes:
|
|
// For INCR, it is tricky that the length can be any value but as the slave is
|
|
// wrapping, still needs to convert the burst at slave boundary
|
|
// (in_len <= len_to_out_bndry): can tell the in INCR burst can totally
|
|
// fit in slave boundary -> pass thru
|
|
// This works same way for INCOMPLETE wrap as well, so cannot make seperate
|
|
// optimization when dont support INCOMPLETE wrap
|
|
// --------------------------------------------------------------------------
|
|
wire in_len_smaller_not_cross_out_bndry;
|
|
wire in_len_smaller_not_cross_in_bndry;
|
|
|
|
assign in_len_smaller_not_cross_out_bndry = (in_len <= len_to_out_bndry);
|
|
assign in_len_smaller_not_cross_in_bndry = (in_len <= len_to_in_bndry);
|
|
always_comb begin
|
|
if ((in_boundary > OUT_BOUNDARY) || (in_burstwrap[BNDRY_WIDTH - 1] == 1)) begin
|
|
first_len = len_to_out_bndry;
|
|
if (in_len_smaller_not_cross_out_bndry || same_boundary)
|
|
first_len = in_len;
|
|
end
|
|
else begin
|
|
first_len = len_to_in_bndry;
|
|
if (in_len_smaller_not_cross_in_bndry || same_boundary)
|
|
first_len = in_len;
|
|
end
|
|
end // always_comb
|
|
|
|
// -----------------------------------------------------------------------
|
|
// III. Conveter enable signals: Turn on/off each conveter accordingly
|
|
// -----------------------------------------------------------------------
|
|
// WRAPPING AVALON: two conveters:
|
|
// 1. wrap_burst_conveter -> handle full_size INCR, WRAP
|
|
// 2. default_burst_conveter -> handle narrow_size burst
|
|
// opt, seperate enable for write and reach
|
|
// -----------------------------------------------------------------------
|
|
// fixed_new_burst && new_burst : note this for incr_write as it is write_enable, cannot turn on incase a read happen before
|
|
assign enable_incr_write_converter = (d0_in_valid && d0_in_write_but_not_fixed_or_narrow && fixed_new_burst && new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_write_but_not_fixed_or_narrow && !nb));
|
|
assign enable_incr_read_converter = (d0_in_valid && d0_in_read_but_not_fixed_or_narrow && fixed_new_burst && (source0_ready || !source0_valid) || (( state == ST_COMP_TRANS) && source0_ready && d1_in_read_but_not_fixed_or_narrow && !nb));
|
|
assign enable_fixed_converter = (d0_in_valid && d0_in_default_converter && new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_default_converter && !nb));
|
|
|
|
// -----------------------------------------------------------------------
|
|
// IV. Packet signals
|
|
// -----------------------------------------------------------------------
|
|
assign next_out_sop = ((state == ST_COMP_TRANS) & source0_ready & !(d1_in_default_converter ? fixed_new_burst : new_burst)) ? 1'b0 : d0_in_sop;
|
|
assign next_out_eop = (state == ST_COMP_TRANS) ? (d1_in_default_converter ? fixed_new_burst : new_burst) : d1_in_eop;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// V. Output select
|
|
// -----------------------------------------------------------------------
|
|
assign out_byte_cnt = d1_in_default_converter ? fixed_out_byte_cnt : incr_out_byte_cnt;
|
|
assign out_addr = d1_in_default_converter ? fixed_out_addr : incr_out_addr;
|
|
end // if (IS_WRAP_AVALON_SLAVE)
|
|
|
|
if (AXI_SLAVE) begin
|
|
reg [IN_LEN_W - 1 : 0] first_len_reg;
|
|
reg d0_in_incr;
|
|
reg d1_in_incr;
|
|
reg in_incr_reg;
|
|
wire in_read_wrap_conveter;
|
|
wire in_write_wrap_conveter;
|
|
reg in_read_wrap_conveter_reg;
|
|
reg in_write_wrap_conveter_reg;
|
|
|
|
reg d0_in_read_wrap_conveter;
|
|
reg d0_in_write_wrap_conveter;
|
|
reg d0_in_default_converter;
|
|
reg d1_in_read_wrap_conveter;
|
|
reg d1_in_write_wrap_conveter;
|
|
reg d1_in_default_converter;
|
|
|
|
wire in_incr = (in_bursttype == 2'b01) && !in_uncompressed_read;
|
|
wire in_wrap = (in_bursttype == 2'b10);
|
|
wire in_fixed = (in_bursttype == 2'b00) || (in_bursttype == 2'b11);
|
|
wire in_narrow_read_wrap_smaller_16 = in_narrow && in_wrap && is_passthru && in_compressed_read;
|
|
wire in_narrow_write_wrap_smaller_16 = in_narrow && in_wrap && is_passthru && in_write;
|
|
wire in_narrow_wrap_larger_16 = in_narrow && in_wrap && !is_passthru;
|
|
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] wrap_out_byte_cnt;
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] fixed_out_byte_cnt;
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] incr_out_byte_cnt;
|
|
|
|
assign incr_out_byte_cnt = (d1_in_compressed_read ? incr_out_len : incr_uncompr_out_len) << log2_numsymbols;
|
|
assign wrap_out_byte_cnt = (d1_in_compressed_read ? wrap_out_len : wrap_uncompr_out_len) << log2_numsymbols;
|
|
assign fixed_out_byte_cnt = fixed_out_len << log2_numsymbols;
|
|
|
|
assign in_full_size_read_wrap = in_compressed_read & in_wrap & !in_narrow;
|
|
assign in_full_size_write_wrap = in_write & in_wrap & !in_narrow;
|
|
assign in_read_wrap_conveter = in_full_size_read_wrap || in_narrow_read_wrap_smaller_16;
|
|
assign in_write_wrap_conveter = in_full_size_write_wrap || in_narrow_write_wrap_smaller_16;
|
|
assign in_default_converter = in_narrow_wrap_larger_16 || in_fixed || in_uncompressed_read;
|
|
|
|
//nb: new burst signal
|
|
assign nb = (d1_in_default_converter ? fixed_new_burst : (d1_in_incr ? incr_new_burst : wrap_new_burst));
|
|
// is_passthru : still read from real input, as we want to shift 1 clock here, all control signal and first len
|
|
assign is_passthru = in_sop ? (in_passthru) : in_passthru_reg;
|
|
|
|
//----------------------------------------------------------------
|
|
// I. Pipeline input stage
|
|
//----------------------------------------------------------------
|
|
if(PIPE_INTERNAL == 0) begin : NO_PIPELINE_INPUT
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_write_wrap_conveter_reg <= '0;
|
|
in_read_wrap_conveter_reg <= '0;
|
|
in_default_converter_reg <= '0;
|
|
in_incr_reg <= '0;
|
|
end else begin
|
|
if (sink0_pipe_ready & sink0_pipe_valid) begin
|
|
in_write_wrap_conveter_reg <= in_write_wrap_conveter;
|
|
in_read_wrap_conveter_reg <= in_read_wrap_conveter;
|
|
in_default_converter_reg <= in_default_converter;
|
|
in_incr_reg <= in_incr;
|
|
end
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
always_comb begin
|
|
d0_in_incr = in_incr;
|
|
d0_in_default_converter = in_default_converter;
|
|
d0_in_read_wrap_conveter = in_read_wrap_conveter;
|
|
d0_in_write_wrap_conveter = in_write_wrap_conveter;
|
|
d0_first_len = first_len;
|
|
d1_in_default_converter = in_default_converter_reg;
|
|
d1_in_read_wrap_conveter = in_read_wrap_conveter_reg;
|
|
d1_in_write_wrap_conveter = in_write_wrap_conveter_reg;
|
|
d1_in_incr = in_incr_reg;
|
|
d0_in_bursttype = nb ? in_bursttype : in_bursttype_reg;
|
|
end
|
|
end
|
|
else begin : PIPELINE_INPUT
|
|
reg [PKT_BURST_TYPE_W - 1 :0] d0_in_bursttype_dl;
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_write_wrap_conveter_reg <= '0;
|
|
in_read_wrap_conveter_reg <= '0;
|
|
in_default_converter_reg <= '0;
|
|
d1_in_default_converter <= '0;
|
|
d1_in_read_wrap_conveter <= '0;
|
|
d1_in_write_wrap_conveter <= '0;
|
|
first_len_reg <= '0;
|
|
in_incr_reg <= '0;
|
|
d0_in_bursttype_dl <= '0;
|
|
end else begin
|
|
if (sink0_pipe_ready & in_valid) begin
|
|
in_write_wrap_conveter_reg <= in_write_wrap_conveter;
|
|
in_read_wrap_conveter_reg <= in_read_wrap_conveter;
|
|
in_default_converter_reg <= in_default_converter;
|
|
first_len_reg <= first_len;
|
|
in_incr_reg <= in_incr;
|
|
end
|
|
if (((state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |
|
|
( (state == ST_COMP_TRANS) & (~source0_valid | source0_ready & source0_endofpacket) ) ) begin
|
|
d1_in_default_converter <= in_default_converter_reg;
|
|
d1_in_read_wrap_conveter <= in_read_wrap_conveter_reg;
|
|
d1_in_write_wrap_conveter <= in_write_wrap_conveter_reg;
|
|
d1_in_incr <= in_incr_reg;
|
|
d0_in_bursttype_dl <= in_bursttype_reg;
|
|
end
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
always_comb begin
|
|
d0_in_incr = in_incr_reg;
|
|
d0_in_default_converter = in_default_converter_reg;
|
|
d0_in_read_wrap_conveter = in_read_wrap_conveter_reg;
|
|
d0_in_write_wrap_conveter = in_write_wrap_conveter_reg;
|
|
d0_first_len = first_len_reg;
|
|
d0_in_bursttype = nb ? in_bursttype_reg : d0_in_bursttype_dl;
|
|
end
|
|
end
|
|
|
|
// -------------------------------------------------------------------------
|
|
// II. First length calculation
|
|
// -------------------------------------------------------------------------
|
|
// For AXI slave, avalon master must set alwaysBurstMaxBurst so
|
|
// INCOMPLETE wrap burst will not happen
|
|
// 1. If any wrapping burst that smaller than 16 -> pass thru
|
|
// 2. Else first sub_burst length is aligned to slave boundary
|
|
// -------------------------------------------------------------------------
|
|
//wire passthru = (in_len < len_to_out_bndry) || is_passthru; // why compare here? Keep this until we figure out why.
|
|
always_comb begin
|
|
if (in_boundary > OUT_BOUNDARY) begin
|
|
first_len = is_passthru ? in_len : len_to_out_bndry;
|
|
end else begin
|
|
first_len = is_passthru ? in_len : len_to_in_bndry;
|
|
end
|
|
end // always_comb
|
|
|
|
// -----------------------------------------------------------------------
|
|
// III. Conveter enable signals: Turn on/off each conveter accordingly
|
|
// -----------------------------------------------------------------------
|
|
// AXI slave: three conveters:
|
|
// 1. wrap_burst_conveter -> handle WRAP
|
|
// 1.1 : full size wrap --> convert to fit in slave boundary
|
|
// 1.2 : narrow size wrap
|
|
// ---> <= 16 : pass thru
|
|
// ---> > 16 : convert to non-bursting
|
|
// 2. incr_burst_convter -> handle full/narrow size INCR
|
|
// 3. default_burst_conveter -> handle FIXED
|
|
// -----------------------------------------------------------------------
|
|
// Note: narrow wrap with length larger 16 can happen with Avalon narrow wraping
|
|
// master to AXI slave. To support this, it will hurt fmax
|
|
// also the WA adapter currently not pack data in this case, to be better support
|
|
// need to start from WA first
|
|
// -----------------------------------------------------------------------
|
|
assign new_burst = incr_new_burst && wrap_new_burst;
|
|
assign enable_incr_converter = (d0_in_valid && d0_in_incr && fixed_new_burst && wrap_new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_incr && !nb));
|
|
assign enable_write_wrap_converter = (d0_in_valid && d0_in_write_wrap_conveter && fixed_new_burst && new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_write_wrap_conveter && !nb));
|
|
assign enable_read_wrap_converter = (d0_in_valid && d0_in_read_wrap_conveter && fixed_new_burst && new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_read_wrap_conveter && !nb));
|
|
assign enable_fixed_converter = (d0_in_valid && d0_in_default_converter && new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_default_converter && !nb));
|
|
|
|
// -----------------------------------------------------------------------
|
|
// IV. Packet signals
|
|
// -----------------------------------------------------------------------
|
|
assign next_out_sop = ((state == ST_COMP_TRANS) & source0_ready & !(d1_in_default_converter ? fixed_new_burst : (d1_in_incr ? incr_new_burst : wrap_new_burst))) ? 1'b0 : d0_in_sop;
|
|
assign next_out_eop = (state == ST_COMP_TRANS) ? (d1_in_default_converter ? fixed_new_burst : (d1_in_incr ? incr_new_burst : wrap_new_burst)) : d1_in_eop;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// V. Output select
|
|
// -----------------------------------------------------------------------
|
|
assign out_byte_cnt = d1_in_default_converter ? fixed_out_byte_cnt : (d1_in_incr ? incr_out_byte_cnt : wrap_out_byte_cnt);
|
|
assign out_addr = d1_in_default_converter ? fixed_out_addr : (d1_in_incr ? incr_out_addr : wrap_out_addr);
|
|
end // if (AXI_SLAVE)
|
|
|
|
if (IS_INCR_SLAVE) begin
|
|
reg [IN_LEN_W - 1 : 0] first_len_reg;
|
|
reg d0_in_default_converter;
|
|
reg d0_in_full_size_incr;
|
|
reg d0_in_full_size_write_wrap;
|
|
reg d0_in_full_size_read_wrap;
|
|
reg d1_in_default_converter;
|
|
reg d1_in_full_size_incr;
|
|
reg d1_in_full_size_write_wrap;
|
|
reg d1_in_full_size_read_wrap;
|
|
reg d1_in_incr;
|
|
reg in_incr_reg;
|
|
wire in_incr = (in_bursttype == 2'b01);
|
|
wire in_wrap = (in_bursttype == 2'b10);
|
|
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] incr_out_byte_cnt;
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] fixed_out_byte_cnt;
|
|
|
|
assign incr_out_byte_cnt = (d1_in_compressed_read ? incr_out_len : incr_uncompr_out_len) << log2_numsymbols;
|
|
assign fixed_out_byte_cnt = fixed_out_len << log2_numsymbols;
|
|
|
|
if (NO_WRAP_SUPPORT) begin
|
|
assign in_default_converter = !in_full_size_incr;
|
|
assign nb = d1_in_default_converter ? fixed_new_burst : incr_new_burst;
|
|
end
|
|
else begin
|
|
wire in_narrow_incr;
|
|
wire in_fixed = (in_bursttype == 2'b00) || (in_bursttype == 2'b11);
|
|
|
|
assign in_narrow_incr = in_incr & in_narrow;
|
|
assign in_default_converter = in_fixed || in_narrow || in_narrow_incr || in_uncompressed_read;
|
|
assign nb = (d1_in_default_converter ? fixed_new_burst : (d1_in_incr ? incr_new_burst : wrap_new_burst));
|
|
end
|
|
|
|
assign in_full_size_incr = in_incr & !in_narrow & !in_uncompressed_read;
|
|
assign in_full_size_write_wrap = in_write & in_wrap & !in_narrow;
|
|
assign in_full_size_read_wrap = in_compressed_read & in_wrap & !in_narrow;
|
|
|
|
//----------------------------------------------------------------
|
|
// I. Pipeline input stage
|
|
//----------------------------------------------------------------
|
|
if(PIPE_INTERNAL == 0) begin : NO_PIPELINE_INPUT
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_full_size_write_wrap_reg <= '0;
|
|
in_full_size_read_wrap_reg <= '0;
|
|
in_full_size_incr_reg <= '0;
|
|
in_default_converter_reg <= '0;
|
|
in_incr_reg <= '0;
|
|
end else begin
|
|
if (sink0_pipe_ready & sink0_pipe_valid) begin
|
|
in_incr_reg <= in_incr;
|
|
in_full_size_incr_reg <= in_full_size_incr;
|
|
in_full_size_write_wrap_reg <= in_full_size_write_wrap;
|
|
in_full_size_read_wrap_reg <= in_full_size_read_wrap;
|
|
in_default_converter_reg <= in_default_converter;
|
|
end
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
always_comb begin
|
|
d0_in_default_converter = in_default_converter;
|
|
d0_in_full_size_incr = in_full_size_incr;
|
|
d0_in_full_size_write_wrap = in_full_size_write_wrap;
|
|
d0_in_full_size_read_wrap = in_full_size_read_wrap;
|
|
d0_first_len = first_len;
|
|
d1_in_incr = in_incr_reg;
|
|
d1_in_default_converter = in_default_converter_reg;
|
|
d1_in_full_size_incr = in_full_size_incr_reg;
|
|
d1_in_full_size_write_wrap = in_full_size_write_wrap_reg;
|
|
d1_in_full_size_read_wrap = in_full_size_read_wrap_reg;
|
|
d0_in_bursttype = nb ? in_bursttype : in_bursttype_reg;
|
|
end
|
|
end
|
|
else begin : PIPELINE_INPUT
|
|
reg [PKT_BURST_TYPE_W - 1 :0] d0_in_bursttype_dl;
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
in_full_size_write_wrap_reg <= '0;
|
|
in_full_size_read_wrap_reg <= '0;
|
|
in_full_size_incr_reg <= '0;
|
|
in_default_converter_reg <= '0;
|
|
d1_in_default_converter <= '0;
|
|
d1_in_full_size_incr <= '0;
|
|
d1_in_full_size_write_wrap <= '0;
|
|
d1_in_full_size_read_wrap <= '0;
|
|
d1_in_incr <= '0;
|
|
first_len_reg <= '0;
|
|
in_incr_reg <= '0;
|
|
d0_in_bursttype_dl <= '0;
|
|
end else begin
|
|
if (sink0_pipe_ready & in_valid) begin
|
|
in_full_size_incr_reg <= in_full_size_incr;
|
|
in_full_size_write_wrap_reg <= in_full_size_write_wrap;
|
|
in_full_size_read_wrap_reg <= in_full_size_read_wrap;
|
|
in_default_converter_reg <= in_default_converter;
|
|
in_incr_reg <= in_incr;
|
|
first_len_reg <= first_len;
|
|
end
|
|
if (((state != ST_COMP_TRANS) & (~source0_valid | source0_ready)) |
|
|
( (state == ST_COMP_TRANS) & (~source0_valid | source0_ready & source0_endofpacket) ) ) begin
|
|
d1_in_default_converter <= in_default_converter_reg;
|
|
d1_in_full_size_incr <= in_full_size_incr_reg;
|
|
d1_in_full_size_write_wrap <= in_full_size_write_wrap_reg;
|
|
d1_in_full_size_read_wrap <= in_full_size_read_wrap_reg;
|
|
d1_in_incr <= in_incr_reg;
|
|
d0_in_bursttype_dl <= in_bursttype_reg;
|
|
end
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
always_comb begin
|
|
d0_in_default_converter = in_default_converter_reg;
|
|
d0_in_full_size_incr = in_full_size_incr_reg;
|
|
d0_in_full_size_write_wrap = in_full_size_write_wrap_reg;
|
|
d0_in_full_size_read_wrap = in_full_size_read_wrap_reg;
|
|
d0_first_len = first_len_reg;
|
|
d0_in_bursttype = nb ? in_bursttype_reg : d0_in_bursttype_dl;
|
|
end
|
|
end
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
// II. First length calculation
|
|
// --------------------------------------------------------------------------------------
|
|
// Note: the slave is INCR slave, in pratical is has no boundary so if in burst is wrap
|
|
// the sub burst can send out "slave max length" first fs the in burst not yet wraps back
|
|
// To simplify and optimize: the first sub_burst length stills send out aligned length first
|
|
// --------------------------------------------------------------------------------------
|
|
// If no INCOMPLETE wrap burst
|
|
// 1. in_boundary is larger out_boundary; first sub_burst length is: aligned to out boundary
|
|
// 2. in_boundary is smaller out_boundary; first sub_burst length is: aligned to in boundary
|
|
// --------------------------------------------------------------------------------------
|
|
if (!NO_WRAP_SUPPORT) begin : HAVE_WRAP_BURSTING_SUPPORT
|
|
if (!INCOMPLETE_WRAP_SUPPORT) begin : no_incomplete_wrap_support
|
|
assign first_len = (in_boundary > OUT_BOUNDARY) ? len_to_out_bndry : len_to_in_bndry;
|
|
end
|
|
else begin : incomplete_wrap_support
|
|
// -------------------------------------------------------------------------
|
|
// If INCOMPLETE wrap support
|
|
// 1. The idea is still same, based on boundary and select either aligned to in/out boundary
|
|
// 2. But need to check if in_len is smaller to "aligned" in/out boundary for incomplete case
|
|
// -> the burst is pass thru is in_len is smaller
|
|
// -------------------------------------------------------------------------
|
|
wire in_len_smaller_aligned_out_bdry = (in_len <= len_to_out_bndry);
|
|
wire in_len_smaller_aligned_in_bdry = (in_len <= len_to_in_bndry);
|
|
always_comb begin
|
|
if (in_boundary > OUT_BOUNDARY) begin
|
|
first_len = (in_len_smaller_aligned_out_bdry) ? in_len : len_to_out_bndry;
|
|
end
|
|
else begin
|
|
first_len = (in_len_smaller_aligned_in_bdry) ? in_len : len_to_in_bndry;
|
|
end
|
|
end
|
|
end // block: incomplete_wrap_support
|
|
end
|
|
|
|
// -----------------------------------------------------------------------
|
|
// III. Conveter enable signals: Turn on/off each conveter accordingly
|
|
// -----------------------------------------------------------------------
|
|
// INCR slave: three conveters:
|
|
// 1. wrap_burst_conveter -> handle WRAP
|
|
// 2. incr_burst_convter -> handle INCR
|
|
// 2. default_burst_conveter -> handle narrow burst
|
|
// -----------------------------------------------------------------------
|
|
// -----------------------------------------------------------------------
|
|
// Purposely support AXI to Avalon: with no wrapping suppport
|
|
// all wrapping transaction witll be converted to non-bursting sub-burst
|
|
// 21-January-2014
|
|
// -----------------------------------------------------------------------
|
|
if (NO_WRAP_SUPPORT) begin
|
|
assign enable_incr_converter = (d0_in_valid && d0_in_full_size_incr && fixed_new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_full_size_incr && !nb));
|
|
assign enable_fixed_converter = (d0_in_valid && d0_in_default_converter && incr_new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_default_converter && !nb));
|
|
|
|
// -----------------------------------------------------------------------
|
|
// IV. Packet signals
|
|
// -----------------------------------------------------------------------
|
|
assign next_out_sop = (state == ST_COMP_TRANS) & source0_ready & !(d1_in_default_converter ? fixed_new_burst : incr_new_burst) ? 1'b0 : d0_in_sop;
|
|
assign next_out_eop = (state == ST_COMP_TRANS) ? (d1_in_default_converter ? fixed_new_burst : incr_new_burst) : d1_in_eop;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// V. Output select
|
|
// -----------------------------------------------------------------------
|
|
assign out_byte_cnt = d1_in_default_converter ? fixed_out_byte_cnt : incr_out_byte_cnt;
|
|
assign out_addr = d1_in_default_converter ? fixed_out_addr : incr_out_addr;
|
|
end
|
|
else begin
|
|
assign new_burst = incr_new_burst && wrap_new_burst;
|
|
assign enable_incr_converter = (d0_in_valid && d0_in_full_size_incr && fixed_new_burst && wrap_new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_full_size_incr && !nb));
|
|
assign enable_fixed_converter = (d0_in_valid && d0_in_default_converter && new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_default_converter && !nb));
|
|
assign enable_write_wrap_converter = (d0_in_valid && d0_in_full_size_write_wrap && fixed_new_burst && incr_new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_full_size_write_wrap && !nb));
|
|
assign enable_read_wrap_converter = (d0_in_valid && d0_in_full_size_read_wrap && fixed_new_burst && incr_new_burst && (source0_ready || !source0_valid) || ((state == ST_COMP_TRANS) && source0_ready && d1_in_full_size_read_wrap && !nb));
|
|
|
|
// -----------------------------------------------------------------------
|
|
// IV. Packet signals
|
|
// -----------------------------------------------------------------------
|
|
assign next_out_sop = ((state == ST_COMP_TRANS) & source0_ready & !(d1_in_default_converter ? fixed_new_burst : (d1_in_incr ? incr_new_burst : wrap_new_burst))) ? 1'b0 : d0_in_sop;
|
|
assign next_out_eop = (state == ST_COMP_TRANS) ? (d1_in_default_converter ? fixed_new_burst : (d1_in_incr ? incr_new_burst : wrap_new_burst)) : d1_in_eop;
|
|
|
|
// -----------------------------------------------------------------------
|
|
// V. Output select
|
|
// -----------------------------------------------------------------------
|
|
wire [PKT_BYTE_CNT_W - 1 : 0] wrap_out_byte_cnt;
|
|
assign wrap_out_byte_cnt = (d1_in_compressed_read ? wrap_out_len : wrap_uncompr_out_len) << log2_numsymbols;
|
|
|
|
assign out_byte_cnt = d1_in_default_converter ? fixed_out_byte_cnt : (d1_in_incr ? incr_out_byte_cnt : wrap_out_byte_cnt);
|
|
assign out_addr = d1_in_default_converter ? fixed_out_addr : (d1_in_incr ? incr_out_addr : wrap_out_addr);
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
// --------------------------------------------------
|
|
// Control signals
|
|
// --------------------------------------------------
|
|
reg source0_valid_reg;
|
|
wire next_source0_valid;
|
|
reg source0_startofpacket_reg;
|
|
|
|
wire is_write;
|
|
assign is_write = nb ? (d0_in_write) : d1_in_write;
|
|
|
|
//-------------------------------------------------------------------------
|
|
// Handshaking and packet signals
|
|
// -----------------------------------------------------------------------
|
|
// source0_valid: takes from in sink_valid unless read then wait until end_of_packet
|
|
assign next_source0_valid = ((state == ST_COMP_TRANS) & !source0_endofpacket) ? 1'b1 : d0_in_valid;
|
|
|
|
// sink0_ready needs always to be asserted first, hold one after reset
|
|
assign sink0_pipe_ready = (state == ST_UNCOMP_TRANS) ? source0_ready || !source0_valid : (state == ST_COMP_TRANS) ? nb && source0_ready || !source0_valid : in_ready_hold;
|
|
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
source0_valid_reg <= '0;
|
|
source0_startofpacket_reg <= '1;
|
|
end else begin
|
|
if (~source0_valid | source0_ready) begin
|
|
source0_valid_reg <= next_source0_valid;
|
|
source0_startofpacket_reg <= next_out_sop;
|
|
end
|
|
end // else: !if(reset)
|
|
end // always_ff @
|
|
|
|
// Assign output signals
|
|
always_comb begin
|
|
source0_endofpacket = next_out_eop;
|
|
source0_startofpacket = source0_startofpacket_reg;
|
|
source0_valid = source0_valid_reg;
|
|
end
|
|
|
|
// --------------------------------------------------
|
|
// Converters instantiation and signal mappings.
|
|
// --------------------------------------------------
|
|
generate
|
|
if (NON_BURSTING_SLAVE) begin : non_bursting_slave_converters_sel
|
|
altera_default_burst_converter
|
|
#(
|
|
.PKT_BURST_TYPE_W (PKT_BURST_TYPE_W),
|
|
.PKT_ADDR_W (PKT_ADDR_W),
|
|
.PKT_BURSTWRAP_W (PKT_BURSTWRAP_W),
|
|
.PKT_BURST_SIZE_W (PKT_BURST_SIZE_W),
|
|
.LEN_W (IN_LEN_W),
|
|
.IS_AXI_SLAVE (AXI_SLAVE)
|
|
)
|
|
the_default_burst_converter
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_fixed_converter), // turn on if a fixed
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.in_bursttype (d0_in_bursttype),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_burstwrap_value (d0_in_burstwrap_value),
|
|
.in_len (d0_in_len),
|
|
.in_size_value (d0_in_size_value),
|
|
.in_is_write (is_write),
|
|
.out_len (fixed_out_len),
|
|
.out_addr (fixed_out_addr),
|
|
.new_burst (fixed_new_burst)
|
|
);
|
|
end
|
|
else if (INCR_AVALON_SYS) begin : system_purely_avalon_converter_sel
|
|
//-----------------------------------------------------------------
|
|
// When system is purely INCR, only need one converter.
|
|
//-----------------------------------------------------------------
|
|
altera_incr_burst_converter
|
|
#(
|
|
.MAX_IN_LEN (MAX_IN_LEN),
|
|
.MAX_OUT_LEN (MAX_OUT_LEN),
|
|
.ADDR_WIDTH (PKT_ADDR_W),
|
|
.BNDRY_WIDTH (PKT_BURSTWRAP_W),
|
|
.BURSTSIZE_WIDTH (PKT_BURST_SIZE_W),
|
|
.IN_NARROW_SIZE (IN_NARROW_SIZE),
|
|
.NUM_SYMBOLS (NUM_SYMBOLS),
|
|
.PURELY_INCR_AVL_SYS (INCR_AVALON_SYS)
|
|
)
|
|
the_converter_for_avalon_incr_slave
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_incr_converter),
|
|
.in_len (d0_in_len),
|
|
.in_sop (d0_in_sop),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_size_t (d0_in_size),
|
|
.in_size_reg (d1_in_size),
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.is_write (is_write),
|
|
.out_len (incr_out_len),
|
|
.uncompr_out_len (incr_uncompr_out_len),
|
|
.out_addr (incr_out_addr),
|
|
.new_burst_export (incr_new_burst)
|
|
);
|
|
end
|
|
else begin : converters_selection
|
|
if (IS_WRAP_AVALON_SLAVE) begin : wrapping_avalon_slave_converter_sel
|
|
altera_wrap_burst_converter
|
|
#(
|
|
.MAX_IN_LEN (MAX_IN_LEN),
|
|
.MAX_OUT_LEN (MAX_OUT_LEN),
|
|
.ADDR_WIDTH (PKT_ADDR_W),
|
|
.BNDRY_WIDTH (PKT_BURSTWRAP_W),
|
|
.AXI_SLAVE (AXI_SLAVE),
|
|
.NUM_SYMBOLS (NUM_SYMBOLS),
|
|
.OPTIMIZE_WRITE_BURST (0)
|
|
)
|
|
the_converter_for_avalon_wrap_slave
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable_read (enable_incr_read_converter),
|
|
.enable_write (enable_incr_write_converter),
|
|
.in_len (d0_in_len),
|
|
.first_len (d0_first_len),
|
|
.in_sop (d0_in_sop),
|
|
.in_burstwrap (d0_in_burstwrap),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_boundary (in_boundary),
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.out_len (incr_out_len),
|
|
.uncompr_out_len (incr_uncompr_out_len),
|
|
.out_addr (incr_out_addr),
|
|
.new_burst_export (new_burst)
|
|
);
|
|
|
|
altera_default_burst_converter
|
|
#(
|
|
.PKT_BURST_TYPE_W (PKT_BURST_TYPE_W),
|
|
.PKT_ADDR_W (PKT_ADDR_W),
|
|
.PKT_BURSTWRAP_W (PKT_BURSTWRAP_W),
|
|
.PKT_BURST_SIZE_W (PKT_BURST_SIZE_W),
|
|
.LEN_W (IN_LEN_W),
|
|
.IS_AXI_SLAVE (AXI_SLAVE)
|
|
)
|
|
the_default_burst_converter
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_fixed_converter), // turn on if a fixed
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.in_bursttype (d0_in_bursttype),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_burstwrap_value (d0_in_burstwrap_value),
|
|
.in_len (d0_in_len),
|
|
.in_size_value (d0_in_size_value),
|
|
.in_is_write (is_write),
|
|
.out_len (fixed_out_len),
|
|
.out_addr (fixed_out_addr),
|
|
.new_burst (fixed_new_burst)
|
|
);
|
|
end
|
|
if (AXI_SLAVE) begin : axi_slave_converter_sel
|
|
altera_wrap_burst_converter
|
|
#(
|
|
.MAX_IN_LEN (MAX_IN_LEN),
|
|
.MAX_OUT_LEN (MAX_OUT_LEN),
|
|
.ADDR_WIDTH (PKT_ADDR_W),
|
|
.BNDRY_WIDTH (PKT_BURSTWRAP_W),
|
|
.NUM_SYMBOLS (NUM_SYMBOLS),
|
|
.AXI_SLAVE (AXI_SLAVE),
|
|
.OPTIMIZE_WRITE_BURST (0)
|
|
)
|
|
the_converter_for_avalon_wrap_slave
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable_read (enable_read_wrap_converter),
|
|
.enable_write (enable_write_wrap_converter),
|
|
.in_len (d0_in_len),
|
|
.first_len (d0_first_len),
|
|
.in_sop (d0_in_sop),
|
|
.in_burstwrap (d0_in_burstwrap),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_boundary (in_boundary),
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.out_len (wrap_out_len),
|
|
.uncompr_out_len (wrap_uncompr_out_len),
|
|
.out_addr (wrap_out_addr),
|
|
.new_burst_export (wrap_new_burst)
|
|
);
|
|
|
|
altera_incr_burst_converter
|
|
#(
|
|
.MAX_IN_LEN (MAX_IN_LEN),
|
|
.MAX_OUT_LEN (MAX_OUT_LEN),
|
|
.ADDR_WIDTH (PKT_ADDR_W),
|
|
.BNDRY_WIDTH (PKT_BURSTWRAP_W),
|
|
.BURSTSIZE_WIDTH (PKT_BURST_SIZE_W),
|
|
.IN_NARROW_SIZE (IN_NARROW_SIZE),
|
|
.NUM_SYMBOLS (NUM_SYMBOLS),
|
|
.PURELY_INCR_AVL_SYS (INCR_AVALON_SYS)
|
|
)
|
|
the_converter_for_avalon_incr_slave
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_incr_converter),
|
|
.in_len (d0_in_len),
|
|
.in_sop (d0_in_sop),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_size_t (d0_in_size),
|
|
.in_size_reg (d1_in_size),
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.is_write (is_write),
|
|
.out_len (incr_out_len),
|
|
.uncompr_out_len (incr_uncompr_out_len),
|
|
.out_addr (incr_out_addr),
|
|
.new_burst_export (incr_new_burst)
|
|
);
|
|
|
|
// --------------------------------------------------
|
|
// The fixed burst converter module
|
|
// --------------------------------------------------
|
|
altera_default_burst_converter
|
|
#(
|
|
.PKT_BURST_TYPE_W (PKT_BURST_TYPE_W),
|
|
.PKT_ADDR_W (PKT_ADDR_W),
|
|
.PKT_BURSTWRAP_W (PKT_BURSTWRAP_W),
|
|
.PKT_BURST_SIZE_W (PKT_BURST_SIZE_W),
|
|
.LEN_W (IN_LEN_W),
|
|
.IS_AXI_SLAVE (AXI_SLAVE)
|
|
)
|
|
the_default_burst_converter
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_fixed_converter), // turn on if a fixed
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.in_bursttype (d0_in_bursttype),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_burstwrap_value (d0_in_burstwrap_value),
|
|
.in_len (d0_in_len),
|
|
.in_size_value (d0_in_size_value),
|
|
.in_is_write (is_write),
|
|
.out_len (fixed_out_len),
|
|
.out_addr (fixed_out_addr),
|
|
.new_burst (fixed_new_burst)
|
|
);
|
|
end
|
|
if (IS_INCR_SLAVE) begin : incr_slave_converter_sel
|
|
if (NO_WRAP_SUPPORT) begin : no_wrap_incr_slave_converter_sel
|
|
altera_incr_burst_converter
|
|
#(
|
|
.MAX_IN_LEN (MAX_IN_LEN),
|
|
.MAX_OUT_LEN (MAX_OUT_LEN),
|
|
.ADDR_WIDTH (PKT_ADDR_W),
|
|
.BNDRY_WIDTH (PKT_BURSTWRAP_W),
|
|
.BURSTSIZE_WIDTH (PKT_BURST_SIZE_W),
|
|
.IN_NARROW_SIZE (0), // not support narrow as this is INCR avalon slave
|
|
.NUM_SYMBOLS (NUM_SYMBOLS),
|
|
.PURELY_INCR_AVL_SYS (INCR_AVALON_SYS)
|
|
)
|
|
the_converter_for_avalon_incr_slave
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_incr_converter),
|
|
.in_len (d0_in_len),
|
|
.in_sop (d0_in_sop),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_size_t (d0_in_size),
|
|
.in_size_reg (d1_in_size),
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.is_write (is_write),
|
|
.out_len (incr_out_len),
|
|
.uncompr_out_len (incr_uncompr_out_len),
|
|
.out_addr (incr_out_addr),
|
|
.new_burst_export (incr_new_burst)
|
|
);
|
|
|
|
// --------------------------------------------------
|
|
// The default converter
|
|
// --------------------------------------------------
|
|
altera_default_burst_converter
|
|
#(
|
|
.PKT_BURST_TYPE_W (PKT_BURST_TYPE_W),
|
|
.PKT_ADDR_W (PKT_ADDR_W),
|
|
.PKT_BURSTWRAP_W (PKT_BURSTWRAP_W),
|
|
.PKT_BURST_SIZE_W (PKT_BURST_SIZE_W),
|
|
.LEN_W (IN_LEN_W),
|
|
.IS_AXI_SLAVE (AXI_SLAVE)
|
|
)
|
|
the_default_burst_converter
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_fixed_converter), // turn on if a fixed
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.in_bursttype (d0_in_bursttype),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_burstwrap_value (d0_in_burstwrap_value),
|
|
.in_len (d0_in_len),
|
|
.in_size_value (d0_in_size_value),
|
|
.in_is_write (is_write),
|
|
.out_len (fixed_out_len),
|
|
.out_addr (fixed_out_addr),
|
|
.new_burst (fixed_new_burst)
|
|
);
|
|
end
|
|
else begin : wrap_incr_slave_conveter_sel
|
|
altera_wrap_burst_converter
|
|
#(
|
|
.MAX_IN_LEN (MAX_IN_LEN),
|
|
.MAX_OUT_LEN (MAX_OUT_LEN),
|
|
.ADDR_WIDTH (PKT_ADDR_W),
|
|
.BNDRY_WIDTH (PKT_BURSTWRAP_W),
|
|
.NUM_SYMBOLS (NUM_SYMBOLS),
|
|
.AXI_SLAVE (AXI_SLAVE),
|
|
.OPTIMIZE_WRITE_BURST (0)
|
|
)
|
|
the_converter_for_avalon_wrap_slave
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable_read (enable_read_wrap_converter),
|
|
.enable_write (enable_write_wrap_converter),
|
|
.in_len (d0_in_len),
|
|
.first_len (d0_first_len),
|
|
.in_sop (d0_in_sop),
|
|
.in_burstwrap (d0_in_burstwrap),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_boundary (in_boundary),
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.out_len (wrap_out_len),
|
|
.uncompr_out_len (wrap_uncompr_out_len),
|
|
.out_addr (wrap_out_addr),
|
|
.new_burst_export (wrap_new_burst)
|
|
);
|
|
|
|
altera_incr_burst_converter
|
|
#(
|
|
.MAX_IN_LEN (MAX_IN_LEN),
|
|
.MAX_OUT_LEN (MAX_OUT_LEN),
|
|
.ADDR_WIDTH (PKT_ADDR_W),
|
|
.BNDRY_WIDTH (PKT_BURSTWRAP_W),
|
|
.BURSTSIZE_WIDTH (PKT_BURST_SIZE_W),
|
|
.IN_NARROW_SIZE (IN_NARROW_SIZE),
|
|
.NUM_SYMBOLS (NUM_SYMBOLS),
|
|
.PURELY_INCR_AVL_SYS (INCR_AVALON_SYS)
|
|
)
|
|
the_converter_for_avalon_incr_slave
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_incr_converter),
|
|
.in_len (d0_in_len),
|
|
.in_sop (d0_in_sop),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_size_t (d0_in_size),
|
|
.in_size_reg (d1_in_size),
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.is_write (is_write),
|
|
.out_len (incr_out_len),
|
|
.uncompr_out_len (incr_uncompr_out_len),
|
|
.out_addr (incr_out_addr),
|
|
.new_burst_export (incr_new_burst)
|
|
);
|
|
|
|
// --------------------------------------------------
|
|
// The fixed burst converter module
|
|
// --------------------------------------------------
|
|
altera_default_burst_converter
|
|
#(
|
|
.PKT_BURST_TYPE_W (PKT_BURST_TYPE_W),
|
|
.PKT_ADDR_W (PKT_ADDR_W),
|
|
.PKT_BURSTWRAP_W (PKT_BURSTWRAP_W),
|
|
.PKT_BURST_SIZE_W (PKT_BURST_SIZE_W),
|
|
.LEN_W (IN_LEN_W),
|
|
.IS_AXI_SLAVE (AXI_SLAVE)
|
|
)
|
|
the_default_burst_converter
|
|
(
|
|
.clk (clk),
|
|
.reset (reset),
|
|
.enable (enable_fixed_converter), // turn on if a fixed
|
|
.in_addr (d0_in_aligned_addr),
|
|
.in_addr_reg (d1_in_aligned_addr),
|
|
.in_bursttype (d0_in_bursttype),
|
|
.in_burstwrap_reg (d1_in_burstwrap),
|
|
.in_burstwrap_value (d0_in_burstwrap_value),
|
|
.in_len (d0_in_len),
|
|
.in_size_value (d0_in_size_value),
|
|
.in_is_write (is_write),
|
|
.out_len (fixed_out_len),
|
|
.out_addr (fixed_out_addr),
|
|
.new_burst (fixed_new_burst)
|
|
);
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
// --------------------------------------------------
|
|
// Ceil(log2()) function
|
|
// --------------------------------------------------
|
|
function unsigned[63:0] log2ceil;
|
|
input reg [63:0] val;
|
|
reg [63:0] i;
|
|
begin
|
|
i = 1;
|
|
log2ceil = 0;
|
|
|
|
while (i < val) begin
|
|
log2ceil = log2ceil + 1;
|
|
i = i << 1;
|
|
end
|
|
end
|
|
endfunction
|
|
|
|
// ---------------------------------------------------
|
|
// Mapping of output signals.
|
|
// ---------------------------------------------------
|
|
wire load_next_output_pck = source0_ready | !source0_valid;
|
|
always_ff @(posedge clk or posedge reset) begin
|
|
if (reset) begin
|
|
uncompr_out_addr <= '0;
|
|
end
|
|
else if (load_next_output_pck) begin
|
|
uncompr_out_addr <= d0_in_addr;
|
|
end
|
|
|
|
end
|
|
|
|
// ---------------------------------------------------
|
|
// Out burstype
|
|
// ---------------------------------------------------
|
|
// If AXI slave, out_bursttype = INCR if either of the following 2 conditions is met:
|
|
// 1) in_passthru (i.e. the input burst count < 16).
|
|
// 2) input packet has bursttype == REP_WRAP (Repeated Wrap).
|
|
// Else, out_bursttype = in_bursttype.
|
|
// For all other slaves, change the bursttype to INCR.
|
|
wire [PKT_BURST_TYPE_W - 1 : 0] out_bursttype;
|
|
generate
|
|
if (AXI_SLAVE) begin : AXI_SLAVE_out_bursttype
|
|
assign out_bursttype = (!d1_in_passthru || d1_in_bursttype == REP_WRAP) ? INCR : d1_in_bursttype;
|
|
end
|
|
else begin : others_slave_out_bursttype
|
|
assign out_bursttype = INCR;
|
|
end
|
|
endgenerate
|
|
|
|
// At source0_startofpacket, out_addr_read is the in_addr.
|
|
wire [PKT_ADDR_W - 1 : 0] out_addr_read;
|
|
assign out_addr_read = source0_startofpacket_reg ? uncompr_out_addr : out_addr;
|
|
|
|
// Choose between uncompressed or compressed trans address.
|
|
wire [PKT_ADDR_W - 1 : 0] out_addr_assigned_to_packet;
|
|
assign out_addr_assigned_to_packet = (d1_in_write || d1_in_uncompressed_read) ? uncompr_out_addr : out_addr_read;
|
|
|
|
// ---------------------------------------------------
|
|
// Byteenable Generation.
|
|
// Passthrough unless compressed transaction.
|
|
// ---------------------------------------------------
|
|
reg [PKT_BYTEEN_W - 1 : 0 ] out_byteen;
|
|
reg [ADDR_MASK_SEL - 1 : 0 ] out_addr_masked;
|
|
wire [511:0] initial_byteen = set_byteenable_based_on_size(d1_in_size); // To fix quartus integration error. Unused bits are expected to be synthesized away
|
|
|
|
// Unaligned address changes.
|
|
// Assumption : Byte enable is calculated for all cycles coming out from BA, and needs to be based on aligned address.
|
|
// Hence, it cannot take directly output address of BA (which sends out unaligned address for 1st cycle)
|
|
always_comb begin
|
|
// Addresses from the converters (out_addr) are always aligned.
|
|
out_addr_masked = out_addr[ADDR_MASK_SEL-1:0];
|
|
end
|
|
|
|
always_comb begin
|
|
if (BYTEENABLE_SYNTHESIS == 1 && d1_in_narrow == 1 && (state == ST_COMP_TRANS))
|
|
out_byteen = initial_byteen[NUM_SYMBOLS-1:0] << out_addr_masked;
|
|
else
|
|
out_byteen = d1_in_byteen;
|
|
end
|
|
// -- End of Byteenable Generation --
|
|
|
|
always_comb begin : source0_out_assignments
|
|
source0_data = d1_in_data;
|
|
source0_channel = d1_in_channel;
|
|
// Override fields the component is aware of.
|
|
source0_data[PKT_BURST_TYPE_H : PKT_BURST_TYPE_L] = out_bursttype;
|
|
source0_data[PKT_BYTE_CNT_H : PKT_BYTE_CNT_L ] = out_byte_cnt;
|
|
source0_data[PKT_ADDR_H : PKT_ADDR_L ] = out_addr_assigned_to_packet;
|
|
source0_data[PKT_BYTEEN_H : PKT_BYTEEN_L ] = out_byteen;
|
|
end
|
|
|
|
//----------------------------------------------------
|
|
// "min" operation on burstwrap values is a bitwise AND.
|
|
//----------------------------------------------------
|
|
function [PKT_BURSTWRAP_W - 1 : 0] altera_merlin_burst_adapter_burstwrap_min;
|
|
input [PKT_BURSTWRAP_W - 1 : 0] a, b;
|
|
begin
|
|
altera_merlin_burst_adapter_burstwrap_min = a & b;
|
|
end
|
|
endfunction
|
|
|
|
//----------------------------------------------------
|
|
// AXSIZE encoding: run-time size of the transaction.
|
|
// ---------------------------------------------------
|
|
function reg[511:0] set_byteenable_based_on_size;
|
|
input [3:0] axsize;
|
|
begin
|
|
case (axsize)
|
|
4'b0000: set_byteenable_based_on_size = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001;
|
|
4'b0001: set_byteenable_based_on_size = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003;
|
|
4'b0010: set_byteenable_based_on_size = 512'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F;
|
|
4'b0011: set_byteenable_based_on_size = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF;
|
|
4'b0100: set_byteenable_based_on_size = 512'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF;
|
|
4'b0101: set_byteenable_based_on_size = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFF;
|
|
4'b0110: set_byteenable_based_on_size = 512'h0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF;
|
|
4'b0111: set_byteenable_based_on_size = 512'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
|
|
4'b1000: set_byteenable_based_on_size = 512'h0000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
|
|
4'b1001: set_byteenable_based_on_size = 512'hFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
|
|
default: set_byteenable_based_on_size = 512'h00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001;
|
|
endcase
|
|
end
|
|
endfunction
|
|
|
|
endmodule
|
|
|