// (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_width_adapter/altera_merlin_width_adapter.sv#1 $ // $Revision: #1 $ // $Date: 2015/08/09 $ // $Author: swbranch $ // ----------------------------------------------------- // Merlin Width Adapter // ----------------------------------------------------- `timescale 1 ns / 1 ns module altera_merlin_width_adapter #( parameter IN_PKT_ADDR_L = 0, parameter IN_PKT_ADDR_H = 31, parameter IN_PKT_DATA_L = 32, parameter IN_PKT_DATA_H = 63, parameter IN_PKT_BYTEEN_L = 64, parameter IN_PKT_BYTEEN_H = 67, parameter IN_PKT_TRANS_COMPRESSED_READ = 72, parameter IN_PKT_BYTE_CNT_L = 73, parameter IN_PKT_BYTE_CNT_H = 77, parameter IN_PKT_BURSTWRAP_L = 78, parameter IN_PKT_BURSTWRAP_H = 82, parameter IN_PKT_BURST_SIZE_L = 83, parameter IN_PKT_BURST_SIZE_H = 85, parameter IN_PKT_RESPONSE_STATUS_L = 86, parameter IN_PKT_RESPONSE_STATUS_H = 87, parameter IN_PKT_TRANS_EXCLUSIVE = 88, parameter IN_PKT_BURST_TYPE_L = 89, parameter IN_PKT_BURST_TYPE_H = 90, parameter IN_PKT_ORI_BURST_SIZE_L = 91, parameter IN_PKT_ORI_BURST_SIZE_H = 93, parameter IN_PKT_TRANS_WRITE = 94, parameter IN_ST_DATA_W = 110, parameter OUT_PKT_ADDR_L = 0, parameter OUT_PKT_ADDR_H = 31, parameter OUT_PKT_DATA_L = 32, parameter OUT_PKT_DATA_H = 47, parameter OUT_PKT_BYTEEN_L = 48, parameter OUT_PKT_BYTEEN_H = 49, parameter OUT_PKT_TRANS_COMPRESSED_READ = 54, parameter OUT_PKT_BYTE_CNT_L = 55, parameter OUT_PKT_BYTE_CNT_H = 59, parameter OUT_PKT_BURST_SIZE_L = 60, parameter OUT_PKT_BURST_SIZE_H = 62, parameter OUT_PKT_RESPONSE_STATUS_L = 63, parameter OUT_PKT_RESPONSE_STATUS_H = 64, parameter OUT_PKT_TRANS_EXCLUSIVE = 65, parameter OUT_PKT_BURST_TYPE_L = 66, parameter OUT_PKT_BURST_TYPE_H = 67, parameter OUT_PKT_ORI_BURST_SIZE_L = 68, parameter OUT_PKT_ORI_BURST_SIZE_H = 70, parameter OUT_ST_DATA_W = 92, parameter ST_CHANNEL_W = 32, parameter OPTIMIZE_FOR_RSP = 0, parameter PACKING = 1, // 1: Enables packing in Avalon systems parameter CONSTANT_BURST_SIZE = 1, // 1: Optimizes for Avalon-only systems as those always have full size transactions parameter RESPONSE_PATH = 0, // 0: This adapter is on command path, 1: This adapter is on response path // Address alignment can be turned off (an optimisation) if all connected // masters only issue aligned addresses. parameter ENABLE_ADDRESS_ALIGNMENT = 1 ) ( input clk, input reset, output reg in_ready, input in_valid, input [ST_CHANNEL_W-1:0] in_channel, input [IN_ST_DATA_W-1:0] in_data, input in_startofpacket, input in_endofpacket, input out_ready, output reg out_valid, output reg [ST_CHANNEL_W-1:0] out_channel, output reg [OUT_ST_DATA_W-1:0] out_data, output reg out_startofpacket, output reg out_endofpacket, input [2:0] in_command_size_data ); // ------------------------------------------------------------ // Local Parameters // ------------------------------------------------------------ localparam IN_NUMSYMBOLS = IN_PKT_BYTEEN_H - IN_PKT_BYTEEN_L + 1; localparam IN_DATA_W = IN_PKT_DATA_H - IN_PKT_DATA_L + 1; localparam IN_BYTEEN_W = IN_NUMSYMBOLS; localparam OUT_NUMSYMBOLS = OUT_PKT_BYTEEN_H - OUT_PKT_BYTEEN_L + 1; localparam OUT_DATA_W = OUT_PKT_DATA_H - OUT_PKT_DATA_L + 1; localparam OUT_BYTEEN_W = OUT_NUMSYMBOLS; localparam BURST_TYPE_W = IN_PKT_BURST_TYPE_H - IN_PKT_BURST_TYPE_L + 1; localparam BURST_SIZE_W = IN_PKT_BURST_SIZE_H - IN_PKT_BURST_SIZE_L + 1; localparam RESPONSE_STATUS_W = IN_PKT_RESPONSE_STATUS_H - IN_PKT_RESPONSE_STATUS_L + 1; localparam SYMBOL_W = IN_DATA_W / IN_NUMSYMBOLS; localparam ADDRESS_W = IN_PKT_ADDR_H - IN_PKT_ADDR_L + 1; localparam BYTE_CNT_W = IN_PKT_BYTE_CNT_H - IN_PKT_BYTE_CNT_L + 1; localparam OUT_BYTE_CNT_W = OUT_PKT_BYTE_CNT_H - OUT_PKT_BYTE_CNT_L + 1; localparam BWRAP_W = IN_PKT_BURSTWRAP_H - IN_PKT_BURSTWRAP_L + 1; localparam SIZE_W = 2 ** BURST_SIZE_W; localparam RATIO = (IN_NUMSYMBOLS > OUT_NUMSYMBOLS ? IN_NUMSYMBOLS / OUT_NUMSYMBOLS : OUT_NUMSYMBOLS / IN_NUMSYMBOLS ); localparam WIDE_NUMSYMBOLS = (IN_NUMSYMBOLS > OUT_NUMSYMBOLS ? IN_NUMSYMBOLS : OUT_NUMSYMBOLS ); localparam WIDE_DATA = (IN_NUMSYMBOLS > OUT_NUMSYMBOLS ? IN_DATA_W - (OUT_NUMSYMBOLS*SYMBOL_W) : OUT_DATA_W - (IN_NUMSYMBOLS*SYMBOL_W)); localparam OUT_SEGMENT_W = OUT_NUMSYMBOLS * SYMBOL_W; localparam NW_BITFORSELECT_R = clogb2(IN_NUMSYMBOLS); localparam NW_BITFORSELECT_L = clogb2(OUT_NUMSYMBOLS) - 1; localparam ALIGNED_BITS_L = clogb2(OUT_NUMSYMBOLS) - 1; localparam WN_ADDR_LSBS = clogb2(RATIO); localparam WN_ADDR_SELECT = clogb2(IN_NUMSYMBOLS); localparam LOG_OUT_NUMSYMBOLS = clogb2(OUT_NUMSYMBOLS); // ------------------------------------------------------------ // Utility Functions // ------------------------------------------------------------ function integer clogb2; input [63:0] value; begin clogb2 = 0; while (value>0) begin value = value >> 1; clogb2 = clogb2 + 1; end clogb2 = clogb2 - 1; end endfunction // clogb2 function integer min; input [31:0] a; input [31:0] b; begin return (a < b) ? a : b; end endfunction function integer max; input [31:0] a; input [31:0] b; begin return (a > b) ? a : b; end endfunction function reg [clogb2(RATIO)-1:0] mask_to_select_correct_segments_for_size; input [clogb2(RATIO)-1:0] select_output_segment; input [9:0] size_ratio; input int msb_select_bit; integer i; mask_to_select_correct_segments_for_size = '1; for (i=0; i < msb_select_bit; i = i +1'b1 ) begin if (clogb2(size_ratio) > i) mask_to_select_correct_segments_for_size[i] = select_output_segment[i]; end endfunction function reg [ADDRESS_W-1:0] choose_packed_address_base_on_size; input [9:0] size_ratio; input int msb_select_bit; integer i; choose_packed_address_base_on_size = '1; for (i=0; i < msb_select_bit; i = i +1'b1 ) begin if (clogb2(size_ratio) > i) choose_packed_address_base_on_size[i + NW_BITFORSELECT_R] = 1'b0; end endfunction // ------------------------------------------------------------ // Computes how many bytes are in this transfer, based on the size // encoding. // ------------------------------------------------------------ function reg[9:0] bytes_in_transfer; input [BURST_SIZE_W-1:0] axsize; case (axsize) 4'b0000: bytes_in_transfer = 10'b0000000001; 4'b0001: bytes_in_transfer = 10'b0000000010; 4'b0010: bytes_in_transfer = 10'b0000000100; 4'b0011: bytes_in_transfer = 10'b0000001000; 4'b0100: bytes_in_transfer = 10'b0000010000; 4'b0101: bytes_in_transfer = 10'b0000100000; 4'b0110: bytes_in_transfer = 10'b0001000000; 4'b0111: bytes_in_transfer = 10'b0010000000; 4'b1000: bytes_in_transfer = 10'b0100000000; 4'b1001: bytes_in_transfer = 10'b1000000000; default: bytes_in_transfer = 10'b0000000001; endcase endfunction // ------------------------------------------------------------ // Pseudo-field Parameters // // The width adapter widens the data and byteenable fields in the // output packet, thus changing the output packet format. By using // pseudo-fields, we can avoid remapping each individual field to // the output, which is a non-scalable solution. // // How? Assume the packet format is { FIRST, byteen, MID, data, LAST }, // where byteen and data positions are interchangeable. FIRST, MID and // LAST are pseudo-fields that represent the collection of fields in // those positions. // // Not all the pseudo-fields may exist for a given packet format. A // non-existent field has reversed indices, so we have to be careful // when using them. // ------------------------------------------------------------ localparam IN_FIRST_L = 0, IN_FIRST_H = min(IN_PKT_BYTEEN_L, IN_PKT_DATA_L) - 1, IN_MID_L = min(IN_PKT_DATA_H, IN_PKT_BYTEEN_H) + 1, IN_MID_H = max(IN_PKT_DATA_L, IN_PKT_BYTEEN_L) - 1, IN_LAST_L = max(IN_PKT_BYTEEN_H, IN_PKT_DATA_H) + 1, IN_LAST_H = IN_ST_DATA_W - 1, FIRST_EXISTS = (IN_FIRST_H >= IN_FIRST_L), MID_EXISTS = (IN_MID_H >= IN_MID_L), LAST_EXISTS = (IN_LAST_H >= IN_LAST_L), FIRST_W = IN_FIRST_H - IN_FIRST_L + 1, MID_W = IN_MID_H - IN_MID_L + 1, LAST_W = IN_LAST_H - IN_LAST_L + 1, // ------------------------------------------------- // We cannot split the output map into generate blocks as we // do for the inputs because address and size are mapped over // the pseudo-fields. We ensure that the indices are always // legal, even if the field is unused later on. OUT_FIRST_L = 0, OUT_FIRST_H = FIRST_EXISTS ? min(OUT_PKT_BYTEEN_L, OUT_PKT_DATA_L) - 1 : OUT_FIRST_L, OUT_MID_L = min(OUT_PKT_DATA_H, OUT_PKT_BYTEEN_H) + 1, OUT_MID_H = MID_EXISTS ? max(OUT_PKT_DATA_L, OUT_PKT_BYTEEN_L) - 1 : OUT_MID_L, OUT_LAST_L = max(OUT_PKT_BYTEEN_H, OUT_PKT_DATA_H) + 1, OUT_LAST_H = LAST_EXISTS ? OUT_ST_DATA_W - 1 : OUT_LAST_L; // ------------------------------------------------------------ // Signals // ------------------------------------------------------------ reg [BURST_SIZE_W-1:0] in_size_field; reg [IN_DATA_W-1:0] in_data_field; reg [IN_BYTEEN_W-1:0] in_byteen_field; reg [ADDRESS_W-1:0] in_address_field; reg [ADDRESS_W-1:0] address_from_packet; reg [BYTE_CNT_W-1:0] in_byte_cnt_field; reg [BWRAP_W-1:0] in_burstwrap_field; reg [RESPONSE_STATUS_W-1:0] in_response_status_field; reg in_cmpr_read; reg in_lock_field; reg in_write; reg [BURST_TYPE_W-1:0] in_burst_type_field; reg [BYTE_CNT_W-1:0] quantized_byte_cnt_field; reg [BURST_SIZE_W-1:0] out_size_field; reg [OUT_DATA_W-1:0] out_data_field; reg [OUT_BYTEEN_W-1:0] out_byteen_field; reg [ADDRESS_W-1:0] out_address_field; reg out_cmpr_read; reg [BYTE_CNT_W-1:0] out_byte_cnt_field; reg out_lock_field; reg [BURST_TYPE_W-1:0] out_burst_type_field; reg [RESPONSE_STATUS_W-1:0] out_response_status_field; reg [FIRST_W-1:0] in_first_field; reg [FIRST_W-1:0] out_first_field; reg [MID_W-1:0] in_mid_field; reg [MID_W-1:0] out_mid_field; reg [LAST_W-1:0] in_last_field; reg [LAST_W-1:0] out_last_field; reg [WIDE_DATA-1:0] data_reg; reg [WIDE_NUMSYMBOLS-1:0] byteen_reg; reg [ADDRESS_W-1:0] address_reg; reg [BYTE_CNT_W-1:0] byte_cnt_reg; reg use_reg; reg startofpacket_reg; reg endofpacket_reg; reg [OUT_SEGMENT_W-1:0] mask; reg [RESPONSE_STATUS_W-1:0] response_status_reg; reg [ADDRESS_W-1:0] int_output_sel; reg [clogb2(RATIO)-1:0] output_sel; reg [OUT_SEGMENT_W-1:0] data_array [0:RATIO-1]; reg [OUT_NUMSYMBOLS-1:0] byteen_array [0:RATIO-1]; // In narrow-to-wide adaptation, each input datum/byteenable bit maps to // one of OUT_NUMSYMBOLS/IN_NUMSYMBOLS subfields in the wider output // packet. (Call these subfields "segments".) A subfield of the input // address, in_bitforselect, selects the segment. Examples: // 8-16 adaptation: in_bitforselect = in_address_field[0] // 8-32 adaptation: in_bitforselect = in_address_field[1:0] // 8-64 adaptation: in_bitforselect = in_address_field[2:0] // 16-32 adaptation: in_bitforselect = in_address_field[1] // 32-64 adaptation: in_bitforselect = in_address_field[2] // The width of in_bitforselect is // log2(OUT_NUM_SYMBOLS) - log2(IN_NUM_SYMBOLS) = // log2(RATIO) // The msb of in_bitforselect is driven by // in_adress_field[log2(OUT_NUMSYMBOLS) - 1] // The lsb of in_adress_field is driven by // in_adress_field[log2(IN_NUMSYMBOLS)] reg [clogb2(RATIO)-1:0] in_bitforselect; integer i, j; // ---------------------------------------- // Input Field Mapping // ---------------------------------------- reg [ADDRESS_W-1:0] address_for_adaptation; always @* begin in_size_field = in_data[IN_PKT_BURST_SIZE_H :IN_PKT_BURST_SIZE_L ]; in_data_field = in_data[IN_PKT_DATA_H :IN_PKT_DATA_L ]; in_byteen_field = in_data[IN_PKT_BYTEEN_H :IN_PKT_BYTEEN_L ]; address_from_packet = in_data[IN_PKT_ADDR_H :IN_PKT_ADDR_L ]; in_byte_cnt_field = in_data[IN_PKT_BYTE_CNT_H :IN_PKT_BYTE_CNT_L ]; in_cmpr_read = in_data[IN_PKT_TRANS_COMPRESSED_READ]; in_write = in_data[IN_PKT_TRANS_WRITE]; in_lock_field = in_data[IN_PKT_TRANS_EXCLUSIVE]; in_burst_type_field = in_data[IN_PKT_BURST_TYPE_H :IN_PKT_BURST_TYPE_L ]; in_response_status_field = in_data[IN_PKT_RESPONSE_STATUS_H :IN_PKT_RESPONSE_STATUS_L]; end // ---------------------------------------- // Process unaligned address for first address of the burst // ---------------------------------------- generate if (IN_NUMSYMBOLS > OUT_NUMSYMBOLS && ENABLE_ADDRESS_ALIGNMENT) begin reg [ADDRESS_W + (BWRAP_W-1) + BURST_SIZE_W + BURST_TYPE_W - 1 :0] address_for_alignment; reg [ADDRESS_W + clogb2(IN_NUMSYMBOLS)-1:0] address_after_aligned; assign address_for_alignment = {address_from_packet, in_size_field}; assign address_for_adaptation = address_after_aligned[ADDRESS_W-1:0]; altera_merlin_address_alignment #( .ADDR_W (ADDRESS_W), .BURSTWRAP_W (BWRAP_W), .INCREMENT_ADDRESS (0), .NUMSYMBOLS (IN_NUMSYMBOLS), .SIZE_W (BURST_SIZE_W) ) check_and_align_address_to_size ( .clk (clk), .reset (reset), .in_data (address_for_alignment), .out_data (address_after_aligned), .in_valid (), .in_sop (), .in_eop (), .out_ready () ); end else begin assign address_for_adaptation = address_from_packet; end endgenerate generate begin if (FIRST_EXISTS) begin always @* begin in_first_field = in_data[IN_FIRST_H:IN_FIRST_L]; end end else begin always @* begin in_first_field = '0; end end if (MID_EXISTS) begin always @* begin in_mid_field = in_data[IN_MID_H:IN_MID_L]; end end else begin always @* begin in_mid_field = '0; end end if (LAST_EXISTS) begin always @* begin in_last_field = in_data[IN_LAST_H:IN_LAST_L]; end end end endgenerate generate //------------------------------------------------------- //------------------------------------------------------- // Wide-to-Narrow // // For every input cycle, we drive out a bunch'o'output // cycles. Nothing fancier. Yes, it could be more // optimal, but we'll leave that for another day. //------------------------------------------------------- //------------------------------------------------------- if (IN_NUMSYMBOLS > OUT_NUMSYMBOLS) begin wire [31:0] cmd_burst_size = CONSTANT_BURST_SIZE ? IN_NUMSYMBOLS : bytes_in_transfer(in_size_field); // Below mess is just to avoid Quartus warnings about mis-sized assignments. wire [31:0] int_out_numsymbols = OUT_NUMSYMBOLS; wire [clogb2(OUT_NUMSYMBOLS):0] sized_out_numsymbols = int_out_numsymbols[clogb2(OUT_NUMSYMBOLS):0]; wire [31:0] int_out_size = (cmd_burst_size < OUT_NUMSYMBOLS) ? cmd_burst_size : OUT_NUMSYMBOLS; wire [SIZE_W-1:0] sized_out_size = int_out_size[SIZE_W-1:0]; wire [31:0] int_ratio_minus_1 = (cmd_burst_size / OUT_NUMSYMBOLS) - 1; wire [clogb2(RATIO)-1:0] sized_ratio_minus_1 = int_ratio_minus_1[clogb2(RATIO)-1:0]; wire [31:0] int_log2_out_numsymbols = clogb2(OUT_NUMSYMBOLS); wire [BURST_SIZE_W-1:0] log2_out_numsymbols = int_log2_out_numsymbols[BURST_SIZE_W-1:0]; wire [31:0] int_byte_cnt_factor = (in_size_field < log2_out_numsymbols) ? log2_out_numsymbols : in_size_field; wire [BURST_SIZE_W-1:0] sized_byte_cnt_factor = int_byte_cnt_factor[BURST_SIZE_W-1:0]; reg single_response_expected; reg only_one_segment_asserted; reg [RATIO-1:0] segments_with_be_asserted; reg [clogb2(RATIO)-1:0] count; assign single_response_expected = (RESPONSE_PATH && ((only_one_segment_asserted && in_startofpacket && in_endofpacket) || in_write)); always @(posedge clk, posedge reset) begin if (reset) begin address_reg <= '0; byte_cnt_reg <= '0; count <= '0; use_reg <= '0; endofpacket_reg <= '0; data_reg <= '0; byteen_reg <= '0; end else begin // If we're not working on a wide datum, // then wait until one arrives. if (~use_reg) begin if (CONSTANT_BURST_SIZE) begin // when the system contains ONLY Avalon masters and slaves address_reg[ADDRESS_W -1 : WN_ADDR_SELECT] <= in_address_field[ADDRESS_W -1 : WN_ADDR_SELECT]; address_reg[WN_ADDR_SELECT - 1 : 0] <= sized_out_numsymbols; data_reg <= in_data_field[IN_DATA_W-1:OUT_NUMSYMBOLS*SYMBOL_W]; byteen_reg <= in_byteen_field >> OUT_NUMSYMBOLS; byte_cnt_reg <= in_byte_cnt_field - sized_out_numsymbols; end else begin address_reg <= in_address_field + sized_out_size; byte_cnt_reg <= (in_byte_cnt_field >> clogb2(IN_NUMSYMBOLS) << sized_byte_cnt_factor) - sized_out_numsymbols; end endofpacket_reg <= in_endofpacket; if (in_valid && out_ready && !in_cmpr_read && (cmd_burst_size > OUT_NUMSYMBOLS) && !single_response_expected) begin // Data has arrived! count <= sized_ratio_minus_1; use_reg <= 1'b1; end end else begin // if (count == 0) // We have a wide datum in progress. Just wait until // the previous datum is taken, and then set // up the next transfer. if (out_ready) begin if (CONSTANT_BURST_SIZE) begin address_reg[ADDRESS_W -1 : WN_ADDR_SELECT] <= in_address_field[ADDRESS_W -1 : WN_ADDR_SELECT]; address_reg[WN_ADDR_SELECT - 1 : 0] <= address_reg[WN_ADDR_SELECT - 1 : 0] + sized_out_numsymbols; data_reg <= data_reg >> (OUT_NUMSYMBOLS * SYMBOL_W); byteen_reg <= byteen_reg >> (OUT_NUMSYMBOLS); end else begin address_reg <= address_reg + sized_out_size; end byte_cnt_reg <= byte_cnt_reg - sized_out_numsymbols; count <= count - 1'b1; if (count == 1'b1) // We're at the end of this word. use_reg <= '0; end // if (out_ready) end // else: !if(count == 0) end // if (posedge clk) end // always @ (clk, reset) always @* begin // Calculate in_ready. // If count is 0, then we don't have data underway, and we // definitely won't be ready for it the first time 'round. // If count is '1', then we're finishing a set, and we're // ready if the output is. // If count > 1, then we're mid set, and certainly // not ready. in_ready = 0; if ( (cmd_burst_size <= OUT_NUMSYMBOLS) || count == 1 || in_cmpr_read ) in_ready = out_ready; out_valid = in_valid; out_channel = in_channel; out_startofpacket = in_startofpacket; out_endofpacket = 0; out_size_field = (cmd_burst_size < OUT_NUMSYMBOLS) ? in_size_field : log2_out_numsymbols; if (CONSTANT_BURST_SIZE) begin // For Avalon only out_byteen_field = in_byteen_field[OUT_NUMSYMBOLS-1:0]; out_data_field = in_data_field[OUT_NUMSYMBOLS * SYMBOL_W-1:0]; out_byte_cnt_field = in_byte_cnt_field; end else begin out_byte_cnt_field = in_byte_cnt_field >> clogb2(IN_NUMSYMBOLS) << sized_byte_cnt_factor; end out_first_field = in_first_field; out_mid_field = in_mid_field; out_last_field = in_last_field; out_cmpr_read = in_cmpr_read; out_lock_field = in_lock_field; out_burst_type_field = in_burst_type_field; out_response_status_field = in_response_status_field; // Case when command size <= OUT_NUMSYMBOLS: pass the cycle // through, unmodified if (cmd_burst_size <= OUT_NUMSYMBOLS) begin out_endofpacket = in_endofpacket; in_address_field = address_from_packet; end // (cmd_burst_size <= OUT_NUMSYMBOLS) else begin // Case when we need to bus size data (size > OUT_NUMSYMBOLS). out_lock_field = 0; // Change fixed burst type opcodes to the repeated wrap // opcode. if (in_burst_type_field == 2'b00) begin out_burst_type_field = 2'b11; end // On the first address of the burst, align and send this // address to the network in_address_field = address_for_adaptation; end // (cmd_burst_size > OUT_NUMSYMBOLS) out_address_field = in_address_field; int_output_sel = in_address_field >> log2_out_numsymbols ; if (in_cmpr_read) out_endofpacket = 1; if (use_reg) begin out_startofpacket = 0; // If it's the last cycle, or if there's no more data, // we can allow an endofpacket. if (count == 1) out_endofpacket = endofpacket_reg; out_byte_cnt_field = byte_cnt_reg; out_address_field = address_reg; if (CONSTANT_BURST_SIZE) begin // Avalon system out_data_field = data_reg[(OUT_NUMSYMBOLS * SYMBOL_W)-1:0]; out_byteen_field = byteen_reg[OUT_NUMSYMBOLS-1:0]; byteen_array = '{RATIO {0} }; data_array = '{RATIO {0} }; end int_output_sel = address_reg >> log2_out_numsymbols; end output_sel = int_output_sel[WN_ADDR_LSBS-1:0]; if (!CONSTANT_BURST_SIZE) begin out_byteen_field = byteen_array[output_sel]; out_data_field = data_array[output_sel]; end // Check each output-sized segment to see whether it // is enabled (byteenables) segments_with_be_asserted = 0; for (i = 0; i < RATIO; i=i+1) begin segments_with_be_asserted[i] = |in_byteen_field[i*OUT_BYTEEN_W +: OUT_BYTEEN_W]; end // Determine whether only one segment is asserted. This code detects a power of two, // i.e. only 1 bit is asserted. only_one_segment_asserted = (segments_with_be_asserted && !(segments_with_be_asserted & (segments_with_be_asserted - 1))); //----------------------------------------- // Optimization for non-bursting wide-narrow response. // // Only one segment of the wide word will have asserted // byteenables. Just pass that segment through and drop // the rest. This should synthesize to an and-or mux. //----------------------------------------- if (OPTIMIZE_FOR_RSP | single_response_expected) begin out_startofpacket = in_startofpacket; out_endofpacket = in_endofpacket; in_ready = out_ready; //----------------------------------------- // Not correct, but nothing in the response path looks // at these today (10.1). Must be corrected when we allow // multiple width adapters on a path. //----------------------------------------- out_address_field = in_address_field; out_byte_cnt_field = in_byte_cnt_field; out_data_field = '0; out_byteen_field = '0; for (i = 0; i < RATIO; i=i+1) begin mask = '0; for (j = 0; j < OUT_NUMSYMBOLS; j=j+1) begin mask |= {SYMBOL_W{in_byteen_field[i*OUT_NUMSYMBOLS+j]}} << (j*SYMBOL_W); end out_data_field |= mask & in_data_field[i*OUT_SEGMENT_W +: OUT_SEGMENT_W]; out_byteen_field |= in_byteen_field[i*OUT_NUMSYMBOLS +: OUT_NUMSYMBOLS]; end end else begin // to prevent latches j = 0; mask = '0; end end // always @ * //------------------------------------------------------- // Configuration Error Checking //------------------------------------------------------- // synthesis translate_off initial begin if (RATIO * OUT_NUMSYMBOLS != IN_NUMSYMBOLS) begin $display("%m : The ratio of input symbols to output symbols must be an integer."); $stop(); end end // synthesis translate_on if (!CONSTANT_BURST_SIZE) begin integer ibyte; always @* begin for(ibyte=0; ibyte OUT_NUMSYMBOLS) //------------------------------------------------------- //------------------------------------------------------- // Narrow-to-Wide //------------------------------------------------------- //------------------------------------------------------- if (OUT_NUMSYMBOLS > IN_NUMSYMBOLS) begin wire p0_valid; reg p0_startofpacket; reg p0_endofpacket; reg [IN_DATA_W-1:0] p0_data_field; reg [IN_BYTEEN_W-1:0] p0_byteen_field; reg [ADDRESS_W-1:0] p0_address_field; reg [BWRAP_W-1:0] p0_bwrap_field; reg [BYTE_CNT_W-1:0] p0_byte_cnt_field; reg [clogb2(RATIO)-1:0] p0_bitforselect; reg p0_cmpr_read; reg [FIRST_W-1:0] p0_first_field; reg [MID_W-1:0] p0_mid_field; reg [LAST_W-1:0] p0_last_field; reg p0_use_reg; reg [ST_CHANNEL_W-1:0] p0_channel; reg [BURST_SIZE_W-1:0] p0_burst_size; reg [BURST_SIZE_W-1:0] p0_ori_burst_size; reg p0_out_lock_field; reg [BURST_TYPE_W-1:0] p0_burst_type_field; reg [RESPONSE_STATUS_W-1:0] p0_response_status_field; reg p0_reg_startofpacket; reg p0_reg_endofpacket; reg [IN_DATA_W-1:0] p0_reg_data_field; reg [IN_BYTEEN_W-1:0] p0_reg_byteen_field; reg [ADDRESS_W-1:0] p0_reg_address_field; reg [BWRAP_W-1:0] p0_reg_bwrap_field; reg [BYTE_CNT_W-1:0] p0_reg_byte_cnt_field; reg [clogb2(RATIO)-1:0] p0_reg_bitforselect; reg p0_reg_cmpr_read; reg [FIRST_W-1:0] p0_reg_first_field; reg [MID_W-1:0] p0_reg_mid_field; reg [LAST_W-1:0] p0_reg_last_field; reg [ST_CHANNEL_W-1:0] p0_reg_channel; reg [BURST_SIZE_W-1:0] p0_reg_burst_size; reg [BURST_SIZE_W-1:0] p0_reg_ori_burst_size; reg [BURST_TYPE_W-1:0] p0_reg_burst_type_field; reg [RESPONSE_STATUS_W-1:0] p0_reg_response_status_field; reg p0_reg_out_lock_field; wire p1_valid; reg p1_ready; reg p1_startofpacket; reg p1_endofpacket; reg [IN_DATA_W-1:0] p1_data_field; reg [IN_BYTEEN_W-1:0] p1_byteen_field; reg [ADDRESS_W-1:0] p1_address_field; reg [ADDRESS_W-1:0] out_address_field_mask; reg [BYTE_CNT_W-1:0] p1_byte_cnt_field; reg [BURST_SIZE_W-1:0] p1_burst_size; reg [BYTE_CNT_W-1:0] p1_byte_cnt_unpack_field; wire response_data_packing; reg [clogb2(RATIO)-1:0] p1_shift_correct_ouput_segments; reg [clogb2(RATIO)-1:0] p1_push_data_to_output; reg p1_cmpr_read; reg [RESPONSE_STATUS_W-1:0] p1_response_status_field; reg unc_sink_valid; wire unc_sink_ready; wire unc_src_startofpacket; wire unc_src_endofpacket; wire unc_src_valid; wire [ADDRESS_W-1:0] unc_src_addr; wire [BYTE_CNT_W-1:0] unc_src_byte_cnt; wire aligned_addr; wire aligned_byte_cnt; wire unaligned_read; reg [BYTE_CNT_W-1:0] count; reg count_eq_zero; wire [31:0] int_in_numsymbols = IN_NUMSYMBOLS; wire [BYTE_CNT_W-1:0] byte_cnt_sized_in_num_symbols = int_in_numsymbols[BYTE_CNT_W-1:0]; reg [9:0] cmd_burst_size; wire [31:0] out_numsymbols_wire = LOG_OUT_NUMSYMBOLS; wire [31:0] int_encoded_burstsize = NW_BITFORSELECT_R; //NW_BITFORSELECT_R is the log2 of IN_NUMSYMBOLS wire [BURST_SIZE_W-1:0] encoded_burstsize = int_encoded_burstsize[BURST_SIZE_W-1:0]; // Care about burstwrap on command path only if (RESPONSE_PATH == 0) begin assign in_burstwrap_field = in_data[IN_PKT_BURSTWRAP_H:IN_PKT_BURSTWRAP_L]; end else begin assign in_burstwrap_field = {BWRAP_W{1'b1}}; end // To use "read response merging" the Width adapter need to know the size of the command // to check if downside happen. For AXI system, the fifo will store this number (non-packing: we use "combined width adapter") // but in case system without AXI, the system use stand alone width adapter and it cannot read this value // Make a condition incase we see stand alone WA, set this in_command_burst_size to input size //wire [2:0] in_command_burst_size = out_numsymbols_wire[2:0]; //if (!((PACKING == 1) & (CONSTANT_BURST_SIZE == 1))) // stand alone WA // begin // assign in_command_burst_size = in_command_size_data; // end reg [BURST_SIZE_W-1:0] in_ori_size_field; always @* begin in_ori_size_field = in_data[IN_PKT_ORI_BURST_SIZE_H :IN_PKT_ORI_BURST_SIZE_L ]; end reg [9:0] size_ratio; // -------------------------------------------- // Stage 0: buffer the input cycle if read burst // uncompression is going to happen. // // This avoids the possibility of a master receiving a premature // response while its read burst is still being waitrequested. // -------------------------------------------- always @(posedge clk, posedge reset) begin if (reset) begin p0_use_reg <= 1'b0; p0_reg_startofpacket <= 1'b0; p0_reg_endofpacket <= 1'b0; p0_reg_data_field <= '0; p0_reg_bwrap_field <= '0; p0_reg_byteen_field <= '0; p0_reg_address_field <= '0; p0_reg_byte_cnt_field <= '0; p0_reg_cmpr_read <= 1'b0; p0_reg_first_field <= '0; p0_reg_mid_field <= '0; p0_reg_last_field <= '0; p0_reg_channel <= '0; p0_reg_burst_size <= '0; p0_reg_ori_burst_size <= '0; p0_reg_out_lock_field <= '0; p0_reg_burst_type_field <= '0; p0_reg_response_status_field <= '0; end else begin if (unaligned_read & in_valid) p0_use_reg <= 1'b1; if (unc_src_endofpacket & p1_ready) p0_use_reg <= 1'b0; if (unaligned_read) begin p0_reg_startofpacket <= p0_startofpacket; p0_reg_endofpacket <= p0_endofpacket; p0_reg_data_field <= p0_data_field; p0_reg_bwrap_field <= p0_bwrap_field; p0_reg_byteen_field <= p0_byteen_field; p0_reg_address_field <= p0_address_field; p0_reg_byte_cnt_field <= p0_byte_cnt_field; p0_reg_cmpr_read <= p0_cmpr_read; p0_reg_first_field <= p0_first_field; p0_reg_mid_field <= p0_mid_field; p0_reg_last_field <= p0_last_field; p0_reg_channel <= p0_channel; p0_reg_burst_size <= p0_burst_size; p0_reg_ori_burst_size <= p0_ori_burst_size; p0_reg_out_lock_field <= p0_out_lock_field; p0_reg_burst_type_field <= p0_burst_type_field; p0_reg_response_status_field <= p0_response_status_field; end end end always @* begin in_ready = p1_ready; // accept on the first cycle if (unaligned_read & in_valid & ~p0_use_reg) in_ready = 1; if (p0_use_reg) in_ready = 0; end always @* begin p0_startofpacket = in_startofpacket; p0_endofpacket = in_endofpacket; p0_data_field = in_data_field; p0_bwrap_field = in_burstwrap_field; p0_byteen_field = in_byteen_field; //p0_address_field = in_address_field; p0_address_field = address_for_adaptation; // read address from oacket p0_byte_cnt_field = in_byte_cnt_field; p0_cmpr_read = in_cmpr_read; p0_first_field = in_first_field; p0_mid_field = in_mid_field; p0_last_field = in_last_field; p0_channel = in_channel; p0_burst_size = in_size_field; p0_ori_burst_size = in_ori_size_field; p0_out_lock_field = in_lock_field; p0_burst_type_field = in_burst_type_field; p0_response_status_field = in_response_status_field; if (p0_use_reg) begin p0_startofpacket = p0_reg_startofpacket; p0_endofpacket = p0_reg_endofpacket; p0_data_field = p0_reg_data_field; p0_bwrap_field = p0_reg_bwrap_field; p0_byteen_field = p0_reg_byteen_field; p0_address_field = p0_reg_address_field; p0_byte_cnt_field = p0_reg_byte_cnt_field; p0_cmpr_read = p0_reg_cmpr_read; p0_first_field = p0_reg_first_field; p0_mid_field = p0_reg_mid_field; p0_last_field = p0_reg_last_field; p0_channel = p0_reg_channel; p0_burst_size = p0_reg_burst_size; p0_ori_burst_size = p0_reg_ori_burst_size; p0_out_lock_field = p0_reg_out_lock_field; p0_burst_type_field = p0_reg_burst_type_field; p0_response_status_field = p0_reg_response_status_field; end end assign p0_valid = in_valid | p0_use_reg; // -------------------------------------------- // Stage 1: uncompress the input packet if necessary // -------------------------------------------- assign p1_valid = (unaligned_read) ? unc_src_valid : p0_valid; assign aligned_addr = (p0_address_field[ALIGNED_BITS_L:0] == 0); assign aligned_byte_cnt = (p0_byte_cnt_field[ALIGNED_BITS_L:0] == 0); if ((RESPONSE_PATH == 0) && (PACKING == 1)) begin // if this is avalon then checking on aligned, assign unaligned_read = p0_cmpr_read & (~aligned_addr || ~aligned_byte_cnt); end else begin assign unaligned_read = '0; end always @* begin p1_data_field = p0_data_field; p1_byteen_field = p0_byteen_field; p1_startofpacket = p0_startofpacket; p1_endofpacket = p0_endofpacket; p1_address_field = p0_address_field; p1_byte_cnt_field = p0_byte_cnt_field; p1_cmpr_read = p0_cmpr_read; p1_response_status_field = p0_response_status_field; p1_burst_size = p0_burst_size; unc_sink_valid = 0; if (unaligned_read) begin unc_sink_valid = p0_valid; p1_startofpacket = unc_src_startofpacket; p1_endofpacket = unc_src_endofpacket; p1_address_field = unc_src_addr; p1_byte_cnt_field = unc_src_byte_cnt; p1_cmpr_read = 0; end end altera_merlin_burst_uncompressor #( .ADDR_W (ADDRESS_W), .BURSTWRAP_W (BWRAP_W), .BYTE_CNT_W (BYTE_CNT_W), .PKT_SYMBOLS (IN_NUMSYMBOLS), .BURST_SIZE_W(BURST_SIZE_W) ) uncompressor ( .clk (clk), .reset (reset), .sink_startofpacket (p0_startofpacket), .sink_endofpacket (p0_endofpacket), .sink_valid (unc_sink_valid), .sink_ready (unc_sink_ready), .sink_addr (p0_address_field), .sink_burstwrap (p0_bwrap_field), .sink_byte_cnt (p0_byte_cnt_field), .sink_is_compressed (1'b1), // should always be compressed .sink_burstsize (encoded_burstsize), .source_startofpacket (unc_src_startofpacket), .source_endofpacket (unc_src_endofpacket), .source_valid (unc_src_valid), .source_ready (p1_ready), .source_addr (unc_src_addr), .source_burstwrap (), .source_byte_cnt (unc_src_byte_cnt), .source_is_compressed (), .source_burstsize () ); // -------------------------------------------- // Stage 2: perform narrow to wide adaptation on the beats // -------------------------------------------- always @(posedge clk, posedge reset) begin if (reset) begin data_reg <= '0; byteen_reg <= '0; startofpacket_reg <= '0; count <= '0; count_eq_zero <= '1; response_status_reg <= '0; end else begin if (p1_valid && (out_ready || ~out_valid)) begin // Lay input data & input byte enables into // the temp registers data_reg <= data_reg | (p1_data_field << (p1_shift_correct_ouput_segments *IN_NUMSYMBOLS*SYMBOL_W)); byteen_reg <= byteen_reg | (p1_byteen_field << (p1_shift_correct_ouput_segments *IN_NUMSYMBOLS)); response_status_reg <= out_response_status_field; // Capture the stuff that's to be held constant if (count_eq_zero) begin startofpacket_reg <= p1_startofpacket; if (~p1_endofpacket) begin count <= p1_byte_cnt_field - byte_cnt_sized_in_num_symbols; count_eq_zero <= ~|(p1_byte_cnt_field - byte_cnt_sized_in_num_symbols); end end else begin count <= count - byte_cnt_sized_in_num_symbols; count_eq_zero <= ~|(count - byte_cnt_sized_in_num_symbols); end //if (p1_endofpacket || (p1_shift_correct_ouput_segments == '1)) begin if (p1_endofpacket || (p1_push_data_to_output == '1)) begin data_reg <= '0; byteen_reg <= '0; response_status_reg <= '0; end if (out_valid && out_ready) begin startofpacket_reg <= '0; end end // if (p1_valid && (out_ready || ~out_valid)) end // if (posedge clk) end // always @ (clk, reset) always @* begin // Handle narrow-size transaction from the master: // The width of in_bitforselect is // log2(OUT_NUM_SYMBOLS) - log2(IN_NUM_SYMBOLS) = // log2(RATIO) // The msb of in_bitforselect is driven by: in_adress_field[log2(OUT_NUMSYMBOLS) - 1] // The lsb of in_adress_field is driven by: in_adress_field[log2(IN_NUMSYMBOLS)] // The function: mask_to_select_segments_for_size: is used to build a mask that changed at run-time // when narrow-size transaction, It recaculates the width of in_bitforselect base on size ratio // EX: Full-size transaction (2 bytes)N-W: in_bitforselect = in_address[1:0] // Narrow-size transaction(1 byte)N-W: in_bitforselect = {1, in_address[0]} p1_shift_correct_ouput_segments = p1_address_field[NW_BITFORSELECT_L:NW_BITFORSELECT_R]; // size ratio betwen command size and response size //cmd_burst_size = bytes_in_transfer(in_command_burst_size); cmd_burst_size = bytes_in_transfer(p0_ori_burst_size); size_ratio = cmd_burst_size >> in_size_field; if (RESPONSE_PATH == 0) begin // if the WA is on command path, Avalon interconnect default // bitselectfor data packing and push out data are same, compile time p1_push_data_to_output = p1_shift_correct_ouput_segments; end else begin // the WA is on reponse path and default: PACKING = 1 // on response path, need based on size, run-time, to determinite output segment p1_push_data_to_output = mask_to_select_correct_segments_for_size(p1_shift_correct_ouput_segments, size_ratio, clogb2(RATIO)); out_address_field_mask = choose_packed_address_base_on_size(size_ratio, clogb2(RATIO)); end // We push data to the output whenever the input is // an endofpacket, or the input drives the most-significant // segment of the wider output word. out_valid = 0; if (PACKING == 1) begin if (p1_endofpacket || (p1_push_data_to_output == '1)) begin out_valid = p1_valid; end end else begin out_valid = p1_valid; end out_startofpacket = p1_startofpacket || startofpacket_reg; out_endofpacket = p1_endofpacket; // Compressed read with byte_cnt > input interface width: // this is a read burst spanning more than the originating // interface of data, so all byteenables must be asserted. if (p1_cmpr_read && (p1_byte_cnt_field > IN_NUMSYMBOLS)) begin out_byteen_field = '1; end else begin if (PACKING == 1) begin // byteenable only affect on command path out_byteen_field = byteen_reg | (p1_byteen_field << (p1_shift_correct_ouput_segments*IN_NUMSYMBOLS)); end else begin // non-packing: shift input byteenable to correct position out_byteen_field = (p1_byteen_field << (p1_shift_correct_ouput_segments*IN_NUMSYMBOLS)); end end // caculate bytecnt "unpack" according to OUTNUMSYMBOLS p1_byte_cnt_unpack_field = p1_byte_cnt_field << clogb2(RATIO); out_address_field = p1_address_field; if (RESPONSE_PATH == 0) begin if (PACKING == 1) begin // if the WA is on command path, Avalon interconnect default out_data_field = data_reg | (p1_data_field << (p1_shift_correct_ouput_segments *IN_NUMSYMBOLS*SYMBOL_W)); out_byte_cnt_field = quantized_byte_cnt_field; out_address_field[NW_BITFORSELECT_L:0] = 0; out_size_field = out_numsymbols_wire[BURST_SIZE_W-1:0]; // for Avalon the size is converted to slave side end else begin out_data_field = (p1_data_field << (p1_shift_correct_ouput_segments *IN_NUMSYMBOLS*SYMBOL_W)); out_byte_cnt_field = p1_byte_cnt_unpack_field; out_size_field = p1_burst_size; end end else begin // the WA is on reponse path and default: PACKING = 1 //if (in_size_field < in_command_burst_size) begin // downsize happen on command path, the response need packing if (in_size_field < in_ori_size_field) begin // downsize happen on command path, the response need packing out_data_field = data_reg | (p1_data_field << (p1_shift_correct_ouput_segments *IN_NUMSYMBOLS*SYMBOL_W)); out_address_field = p1_address_field & out_address_field_mask; out_size_field = p1_burst_size; out_byte_cnt_field = p1_byte_cnt_field; end else begin // narrow transaction on command path, reponse packet will not packed out_data_field = (p1_data_field << (p1_shift_correct_ouput_segments *IN_NUMSYMBOLS*SYMBOL_W)); out_byte_cnt_field = p1_byte_cnt_field; out_size_field = p1_burst_size; end end //if (in_size_field < in_command_burst_size) begin // downsize happen on command path, the response need packing if (in_size_field < in_ori_size_field) begin // downsize happen on command path, the response need packing // Response merging: rules: DECERR(11) > SLVERR (10) > OKAY (00) // EXOKAY will not happen on merging out_response_status_field = '0; if (response_status_reg >= p1_response_status_field) begin out_response_status_field = response_status_reg; end else begin out_response_status_field = p1_response_status_field; end end else begin // narrow transaction on command path, reponse packet will not packed out_response_status_field = p1_response_status_field; end out_cmpr_read = p1_cmpr_read; // nothing touches these fields, so assign them // directly from the input fields out_first_field = p0_first_field; out_mid_field = p0_mid_field; out_last_field = p0_last_field; out_lock_field = p0_out_lock_field; out_channel = p0_channel; out_burst_type_field = p0_burst_type_field; end // always @ * //------------------------------------------------------- // output byte_cnt, rounded up to alignment with the output-side // address map footprint implied by the input-side access. // // See "option 3" in Appendix C of // merlin_interconnect_architecture_fd_91.doc. //------------------------------------------------------- reg [NW_BITFORSELECT_L:0] low_addr_bits; always @* begin low_addr_bits = p1_address_field[NW_BITFORSELECT_L:0]; quantized_byte_cnt_field = low_addr_bits + p1_byte_cnt_field + {clogb2(OUT_NUMSYMBOLS){1'b1}}; quantized_byte_cnt_field[NW_BITFORSELECT_L:0] = '0; end //------------------------------------------------------- // Backpressure //------------------------------------------------------- always @ * begin p1_ready = out_ready || ~out_valid; end end // if (OUT_NUMSYMBOLS > IN_NUMSYMBOLS) //------------------------------------------------------- //------------------------------------------------------- // Same Width. Seems kind of silly, but let's be complete. //------------------------------------------------------- //------------------------------------------------------- if (OUT_NUMSYMBOLS == IN_NUMSYMBOLS) begin always @* begin in_ready = out_ready; out_valid = in_valid; out_channel = in_channel; out_startofpacket = in_startofpacket; out_endofpacket = in_endofpacket; out_size_field = in_size_field; out_data_field = in_data_field; out_byteen_field = in_byteen_field; out_address_field = in_address_field; out_byte_cnt_field = in_byte_cnt_field; out_response_status_field = in_response_status_field; out_lock_field = in_lock_field; out_burst_type_field = in_burst_type_field; out_cmpr_read = in_cmpr_read; out_first_field = in_first_field; out_mid_field = in_mid_field; out_last_field = in_last_field; end // always @ * end // if (OUT_NUMSYMBOLS == IN_NUMSYMBOLS) endgenerate // --------------------------------------- // Output Field Mapping // // Conditionally assign the pseudo-fields. Assign address and size // last, because they partly override the pseudo-fields. // --------------------------------------- always @* begin if (FIRST_EXISTS) out_data[OUT_FIRST_H:OUT_FIRST_L] = out_first_field; if (MID_EXISTS) out_data[OUT_MID_H:OUT_MID_L] = out_mid_field; if (LAST_EXISTS) out_data[OUT_LAST_H:OUT_LAST_L] = out_last_field; out_data[OUT_PKT_BURST_SIZE_H : OUT_PKT_BURST_SIZE_L ] = out_size_field; out_data[OUT_PKT_DATA_H : OUT_PKT_DATA_L ] = out_data_field; out_data[OUT_PKT_BYTEEN_H : OUT_PKT_BYTEEN_L ] = out_byteen_field; out_data[OUT_PKT_ADDR_H : OUT_PKT_ADDR_L ] = out_address_field; out_data[OUT_PKT_BYTE_CNT_H : OUT_PKT_BYTE_CNT_L ] = out_byte_cnt_field; out_data[OUT_PKT_TRANS_COMPRESSED_READ ] = out_cmpr_read; out_data[OUT_PKT_TRANS_EXCLUSIVE ] = out_lock_field; out_data[OUT_PKT_BURST_TYPE_H : OUT_PKT_BURST_TYPE_L ] = out_burst_type_field; out_data[OUT_PKT_RESPONSE_STATUS_H : OUT_PKT_RESPONSE_STATUS_L] = out_response_status_field; end // always @ * endmodule // width_adapter