Initial commit: retroDE_ps2 — first-of-its-kind PS2 GS FPGA core (DE25-Nano / Agilex 5)

RTL (GS rasterizer, EE core stub, platform bridge, LPDDR4B path), sim regression
(272 TBs), docs, and tooling. Copyrighted PS2 content (BIOS, game code, GS dumps,
and all dump-derived textures/traces) is excluded via .gitignore and stays local.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-29 20:10:50 -04:00
commit ec82764bef
2462 changed files with 2174303 additions and 0 deletions
@@ -0,0 +1,278 @@
// (C) 2001-2026 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 from 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 IP 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/26.1/ip/iconnect/merlin/altera_merlin_burst_adapter/new_source/altera_default_burst_converter.sv#1 $
// $Revision: #1 $
// $Date: 2026/02/05 $
// --------------------------------------------
// Default Burst Converter
// Notes:
// 1) If burst type FIXED and slave is AXI,
// passthrough the transaction.
// 2) Else, converts burst into non-bursting
// transactions (length of 1).
// --------------------------------------------
`timescale 1 ns / 1 ns
module altera_default_burst_converter
#(
parameter PKT_BURST_TYPE_W = 2,
parameter PKT_BURSTWRAP_W = 5,
parameter PKT_ADDR_W = 12,
parameter PKT_BURST_SIZE_W = 3,
parameter IS_AXI_SLAVE = 0,
parameter LEN_W = 2,
parameter SYNC_RESET = 0
)
(
input clk,
input reset,
input enable,
input [PKT_BURST_TYPE_W - 1 : 0] in_bursttype,
input [PKT_BURSTWRAP_W - 1 : 0] in_burstwrap_reg,
input [PKT_BURSTWRAP_W - 1 : 0] in_burstwrap_value,
input [PKT_ADDR_W - 1 : 0] in_addr,
input [PKT_ADDR_W - 1 : 0] in_addr_reg,
input [LEN_W - 1 : 0] in_len,
input [PKT_BURST_SIZE_W - 1 : 0] in_size_value,
input in_is_write,
output reg [PKT_ADDR_W - 1 : 0] out_addr,
output reg [LEN_W - 1 : 0] out_len,
output reg new_burst
);
// ---------------------------------------------------
// AXI Burst Type Encoding
// ---------------------------------------------------
typedef enum bit [1:0]
{
FIXED = 2'b00,
INCR = 2'b01,
WRAP = 2'b10,
RESERVED = 2'b11
} AxiBurstType;
// -------------------------------------------
// Internal Signals
// -------------------------------------------
wire [LEN_W - 1 : 0] unit_len = {{LEN_W - 1 {1'b0}}, 1'b1};
reg [LEN_W - 1 : 0] next_len;
reg [LEN_W - 1 : 0] remaining_len;
reg [PKT_ADDR_W - 1 : 0] next_incr_addr;
reg [PKT_ADDR_W - 1 : 0] incr_wrapped_addr;
reg [PKT_ADDR_W - 1 : 0] extended_burstwrap_value;
reg [PKT_ADDR_W - 1 : 0] addr_incr_variable_size_value;
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= reset;
end
end
endgenerate
// -------------------------------------------
// Byte Count Converter
// -------------------------------------------
// Avalon Slave: Read/Write, the out_len is always 1 (unit_len).
// AXI Slave: Read/Write, the out_len is always the in_len (pass through) of a given cycle.
// If bursttype RESERVED, out_len is always 1 (unit_len).
generate if (IS_AXI_SLAVE == 1)
begin : axi_slave_out_len
always_ff @(posedge clk) begin
if (enable) begin
out_len <= (in_bursttype == FIXED) ? in_len : unit_len;
end
end
//if (SYNC_RESET == 0 ) begin : async_rst1
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_len <= {LEN_W{1'b0}};
// end
// else if (enable) begin
// out_len <= (in_bursttype == FIXED) ? in_len : unit_len;
// end
// end
//end // async_rst1
//else begin // sync_rst1
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_len <= {LEN_W{1'b0}};
// end
// else if (enable) begin
// out_len <= (in_bursttype == FIXED) ? in_len : unit_len;
// end
// end
//end // sync_rst1
end
else // IS_AXI_SLAVE == 0
begin : non_axi_slave_out_len
always_comb begin
out_len = unit_len;
end
end
endgenerate
always_comb begin : proc_extend_burstwrap
extended_burstwrap_value = {{(PKT_ADDR_W - PKT_BURSTWRAP_W){in_burstwrap_reg[PKT_BURSTWRAP_W - 1]}}, in_burstwrap_value};
addr_incr_variable_size_value = {{(PKT_ADDR_W - 1){1'b0}}, 1'b1} << in_size_value;
end
// -------------------------------------------
// Address Converter
// -------------------------------------------
// Write: out_addr = in_addr at every cycle (pass through).
// Read: out_addr = in_addr at every new_burst. Subsequent addresses calculated by converter.
always_ff @(posedge clk) begin
if (enable) begin
next_incr_addr <= next_incr_addr + addr_incr_variable_size_value;
if (new_burst) begin
next_incr_addr <= in_addr + addr_incr_variable_size_value;
end
out_addr <= incr_wrapped_addr;
end
end
//generate
//if (SYNC_RESET == 0) begin : async_rst2
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_incr_addr <= {PKT_ADDR_W{1'b0}};
// out_addr <= {PKT_ADDR_W{1'b0}};
// end
// else if (enable) begin
// next_incr_addr <= next_incr_addr + addr_incr_variable_size_value;
// if (new_burst) begin
// next_incr_addr <= in_addr + addr_incr_variable_size_value;
// end
// out_addr <= incr_wrapped_addr;
// end
// end
// end // async_rst2
// else begin // sync_rst2
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_incr_addr <= {PKT_ADDR_W{1'b0}};
// out_addr <= {PKT_ADDR_W{1'b0}};
// end
// else if (enable) begin
// next_incr_addr <= next_incr_addr + addr_incr_variable_size_value;
// if (new_burst) begin
// next_incr_addr <= in_addr + addr_incr_variable_size_value;
// end
// out_addr <= incr_wrapped_addr;
// end
// end
// end // sync_rst2
//endgenerate
always_comb begin
incr_wrapped_addr = in_addr;
if (!new_burst) begin
// This formula calculates addresses of WRAP bursts and works perfectly fine for other burst types too.
incr_wrapped_addr = (in_addr_reg & ~extended_burstwrap_value) | (next_incr_addr & extended_burstwrap_value);
end
end
// -------------------------------------------
// Control Signals
// -------------------------------------------
// Determine the min_len.
// 1) FIXED read to AXI slave: One-time passthrough, therefore the min_len == in_len.
// 2) FIXED write to AXI slave: min_len == 1.
// 3) FIXED read/write to Avalon slave: min_len == 1.
// 4) RESERVED read/write to AXI/Avalon slave: min_len == 1.
wire [LEN_W - 1 : 0] min_len;
generate if (IS_AXI_SLAVE == 1)
begin : axi_slave_min_len
assign min_len = (!in_is_write && (in_bursttype == FIXED)) ? in_len : unit_len;
end
else // IS_AXI_SLAVE == 0
begin : non_axi_slave_min_len
assign min_len = unit_len;
end
endgenerate
// last_beat calculation.
wire last_beat = (remaining_len == min_len);
// next_len calculation.
always_comb begin
remaining_len = in_len;
if (!new_burst) remaining_len = next_len;
end
always_ff @(posedge clk) begin
if (enable) begin
next_len <= remaining_len - unit_len;
end
end
generate
if (SYNC_RESET == 0) begin : async_rst3
//always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_len <= 1'b0;
// end
// else if (enable) begin
// next_len <= remaining_len - unit_len;
// end
//end
// new_burst calculation.
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
new_burst <= 1'b1;
end
else if (enable) begin
new_burst <= last_beat;
end
end
end // async_rst3
else begin // sync_rst3
//always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_len <= 1'b0;
// end
// else if (enable) begin
// next_len <= remaining_len - unit_len;
// end
//end
// new_burst calculation.
always_ff @(posedge clk) begin
if (internal_sclr) begin
new_burst <= 1'b1;
end
else if (enable) begin
new_burst <= last_beat;
end
end
end // sync_rst3
endgenerate
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZnXzCebnCKJTsi823h62YzED9giUrsXJJm305Cxwn/ZRLE5PqwZtvf+8ZAVJE55kNVZaV60bWlN1N0XZR9KM1WwQkKYejedngoMHZ5SvtJeJU4qT4/oQOvKek5HLy5M6ATeo0EfJB3ak4qOC206cHdjo6jQaq4jVeRzd4W9l5Hk/MsscWd3wt993nAf88yhZUaJ1/mBpRC35cYTaXNnFY84PO+FW8JiMxDjLScLm/9k8wCnKRnF0Hs5P4VIY630mFMHoKoejOV1LqpqaU/cjYNnrlSYDmB49HKeYpESgUpAw/F+kYpWqck871iv0EzYP3Z3dhwLSf70SFr5f6Z0TDE3Gr4JfN9KPx6CcPDKeGzYK+fFSJSbCsCPgEl2xC4MI7ISbMJHOcc/V7ZbFLP6r5n8kZlPYOE9L8TJoc1Vcg8UxGcxzW9pE8AgMTFCoLGmA77bKOzo4BwadS0t585NPOjoR4cRPJfC3+2qNG4cdNvwrKBS2VUO7341urJcK/l9J0S9BxiN6U+1HjmDuBCgG09cqLR8+cnmDRKpiIky8laAqXEDKzhWqlD1ganoZi7z4DWtAwMN8P+YVycreBGZgwssabwyo2LmDpP+Uitsy15PbNMCdOJfMK8bkzkIMh2N67/N3Z4HkFKETIcGtbr7Le7scupVRRszgiRj7sZNNULEGcrKiPlFzfAsmzIiqX9N0klWvUcO95LliNP8e+CZZdzfGcKxZVSLsedLYpqEWGn8MBt0cTrRUPAriDk6XjdkPIN9frlNlJ/d6l4jzxLrmAnT"
`endif
@@ -0,0 +1,520 @@
// (C) 2001-2026 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 from 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 IP 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/26.1/ip/iconnect/merlin/altera_merlin_burst_adapter/new_source/altera_incr_burst_converter.sv#1 $
// $Revision: #1 $
// $Date: 2026/02/05 $
// ----------------------------------------------------------
// This component is used for INCR Avalon slave
// (slave which only supports INCR) or AXI slave.
// It converts burst length of input packet
// to match slave burst.
// ----------------------------------------------------------
`timescale 1 ns / 1 ns
module altera_incr_burst_converter
#(
parameter
// ----------------------------------------
// Burst length Parameters
// (real burst length value, not bytecount)
// ----------------------------------------
MAX_IN_LEN = 16,
MAX_OUT_LEN = 4,
NUM_SYMBOLS = 4,
ADDR_WIDTH = 12,
BNDRY_WIDTH = 12,
BURSTSIZE_WIDTH = 3,
IN_NARROW_SIZE = 0,
PURELY_INCR_AVL_SYS = 0,
SYNC_RESET = 0,
// ------------------
// Derived Parameters
// ------------------
LEN_WIDTH = log2ceil(MAX_IN_LEN) + 1,
OUT_LEN_WIDTH = log2ceil(MAX_OUT_LEN) + 1,
LOG2_NUMSYMBOLS = log2ceil(NUM_SYMBOLS)
)
(
input clk,
input reset,
input enable,
input is_write,
input [LEN_WIDTH - 1 : 0] in_len,
input in_sop,
input [ADDR_WIDTH - 1 : 0] in_addr,
input [ADDR_WIDTH - 1 : 0] in_addr_reg,
input [BNDRY_WIDTH - 1 : 0] in_burstwrap_reg,
input [BURSTSIZE_WIDTH - 1 : 0] in_size_t,
input [BURSTSIZE_WIDTH - 1 : 0] in_size_reg,
// converted output length
// out_len : compressed burst, read
// uncompressed_len: uncompressed, write
output reg [LEN_WIDTH - 1 : 0] out_len,
output reg [LEN_WIDTH - 1 : 0] uncompr_out_len,
// Compressed address output
output reg [ADDR_WIDTH - 1 : 0] out_addr,
output reg new_burst_export
);
// ----------------------------------------
// Signals for wrapping support
// ----------------------------------------
reg [LEN_WIDTH - 1 : 0] remaining_len;
reg [LEN_WIDTH - 1 : 0] next_out_len;
reg [LEN_WIDTH - 1 : 0] next_rem_len;
reg [LEN_WIDTH - 1 : 0] uncompr_remaining_len;
reg [LEN_WIDTH - 1 : 0] next_uncompr_remaining_len;
reg [LEN_WIDTH - 1 : 0] next_uncompr_rem_len;
reg new_burst;
reg uncompr_sub_burst;
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= reset;
end
end
endgenerate
// Avoid QIS warning
wire [OUT_LEN_WIDTH - 1 : 0] max_out_length;
assign max_out_length = MAX_OUT_LEN[OUT_LEN_WIDTH - 1 : 0];
always_comb begin
new_burst_export = new_burst;
end
// -------------------------------------------
// length remaining calculation
// -------------------------------------------
always_comb begin : proc_uncompressed_remaining_len
if ((in_len <= max_out_length) && is_write) begin
uncompr_remaining_len = in_len;
end else begin
uncompr_remaining_len = max_out_length;
end
if (uncompr_sub_burst)
uncompr_remaining_len = next_uncompr_rem_len;
end
always_ff @(posedge clk) begin
if (enable) begin
next_uncompr_rem_len <= uncompr_remaining_len - 1'b1; // in term of length, it just reduces 1
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst1
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_uncompr_rem_len <= 0;
// end
// else if (enable) begin
// next_uncompr_rem_len <= uncompr_remaining_len - 1'b1; // in term of length, it just reduces 1
// end
// end
// end // async_rst1
// else begin // sync_rst1
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_uncompr_rem_len <= 0;
// end
// else if (enable) begin
// next_uncompr_rem_len <= uncompr_remaining_len - 1'b1; // in term of length, it just reduces 1
// end
// end
// end // sync_rst1
//endgenerate
always_comb begin : proc_compressed_remaining_len
remaining_len = in_len;
if (!new_burst)
remaining_len = next_rem_len;
end
always_ff@(posedge clk) begin : proc_next_uncompressed_remaining_len
if (enable) begin
if (in_sop) begin
next_uncompr_remaining_len <= in_len - max_out_length;
end
else if (!uncompr_sub_burst)
next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst2
// always_ff@(posedge clk or posedge reset) begin : proc_next_uncompressed_remaining_len
// if(reset) begin
// next_uncompr_remaining_len <= '0;
// end
// else if (enable) begin
// if (in_sop) begin
// next_uncompr_remaining_len <= in_len - max_out_length;
// end
// else if (!uncompr_sub_burst)
// next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
// end
// end
// end // async_rst2
// else begin // sync_rst2
// always_ff@(posedge clk ) begin : proc_next_uncompressed_remaining_len
// if(internal_sclr) begin
// next_uncompr_remaining_len <= '0;
// end
// else if (enable) begin
// if (in_sop) begin
// next_uncompr_remaining_len <= in_len - max_out_length;
// end
// else if (!uncompr_sub_burst)
// next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
// end
// end
// end // sync_rst2
//endgenerate
always_comb begin
next_out_len = max_out_length;
if (remaining_len < max_out_length) begin
next_out_len = remaining_len;
end
end // always_comb
// --------------------------------------------------
// Length remaining calculation : compressed
// --------------------------------------------------
// length remaining for compressed transaction
// for wrap, need special handling for first out length
always_ff @(posedge clk) begin
if (enable) begin
if (new_burst)
next_rem_len <= in_len - max_out_length;
else
next_rem_len <= next_rem_len - max_out_length;
end
end
generate
if (SYNC_RESET == 0) begin: async_rst3
//always_ff @(posedge clk, posedge reset) begin
// if (reset)
// next_rem_len <= 0;
// else if (enable) begin
// if (new_burst)
// next_rem_len <= in_len - max_out_length;
// else
// next_rem_len <= next_rem_len - max_out_length;
// end
//end
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
uncompr_sub_burst <= 0;
end
else if (enable && is_write) begin
uncompr_sub_burst <= (uncompr_remaining_len > 1'b1);
end
end
end // async_rst3
else begin // sync_rst3
//always_ff @(posedge clk) begin
// if (internal_sclr)
// next_rem_len <= 0;
// else if (enable) begin
// if (new_burst)
// next_rem_len <= in_len - max_out_length;
// else
// next_rem_len <= next_rem_len - max_out_length;
// end
//end
always_ff @(posedge clk) begin
if (internal_sclr) begin
uncompr_sub_burst <= 0;
end
else if (enable && is_write) begin
uncompr_sub_burst <= (uncompr_remaining_len > 1'b1);
end
end
end // sync_rst3
endgenerate
// --------------------------------------------------
// Control signals
// --------------------------------------------------
wire end_compressed_sub_burst;
assign end_compressed_sub_burst = (remaining_len == next_out_len);
// new_burst:
// the converter takes in_len for new calculation
generate
if (SYNC_RESET == 0) begin : async_rst4
always_ff @(posedge clk, posedge reset) begin
if (reset)
new_burst <= 1;
else if (enable)
new_burst <= end_compressed_sub_burst;
end
end // async_rst4
else begin // sync_rst4
always_ff @(posedge clk) begin
if (internal_sclr)
new_burst <= 1;
else if (enable)
new_burst <= end_compressed_sub_burst;
end
end
endgenerate
// --------------------------------------------------
// Output length
// --------------------------------------------------
// register out_len for compressed trans
always_ff @(posedge clk) begin
if (enable) begin
out_len <= next_out_len;
end
end
// register uncompr_out_len for uncompressed trans
always_ff @(posedge clk) begin
if (enable) begin
uncompr_out_len <= uncompr_remaining_len;
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst5
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_len <= 0;
// end
// else if (enable) begin
// out_len <= next_out_len;
// end
// end
// // register uncompr_out_len for uncompressed trans
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// uncompr_out_len <= '0;
// end
// else if (enable) begin
// uncompr_out_len <= uncompr_remaining_len;
// end
// end
//end // async_rst5
//else begin // sync_rst5
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_len <= 0;
// end
// else if (enable) begin
// out_len <= next_out_len;
// end
// end
// // register uncompr_out_len for uncompressed trans
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// uncompr_out_len <= '0;
// end
// else if (enable) begin
// uncompr_out_len <= uncompr_remaining_len;
// end
// end
//end //sync_rst5
//endgenerate
// --------------------------------------------------
// Address Calculation
// --------------------------------------------------
reg [ADDR_WIDTH - 1 : 0] addr_incr_sel;
reg [ADDR_WIDTH - 1 : 0] addr_incr_sel_reg;
reg [ADDR_WIDTH - 1 : 0] addr_incr_full_size;
localparam [ADDR_WIDTH - 1 : 0] ADDR_INCR = MAX_OUT_LEN << LOG2_NUMSYMBOLS;
generate
if (IN_NARROW_SIZE) begin : narrow_addr_incr
reg [ADDR_WIDTH - 1 : 0] addr_incr_variable_size;
reg [ADDR_WIDTH - 1 : 0] addr_incr_variable_size_reg;
assign addr_incr_variable_size = MAX_OUT_LEN << in_size_t;
assign addr_incr_variable_size_reg = MAX_OUT_LEN << in_size_reg;
assign addr_incr_sel = addr_incr_variable_size;
assign addr_incr_sel_reg = addr_incr_variable_size_reg;
end
else begin : full_addr_incr
assign addr_incr_full_size = ADDR_INCR[ADDR_WIDTH - 1 : 0];
assign addr_incr_sel = addr_incr_full_size;
assign addr_incr_sel_reg = addr_incr_full_size;
end
endgenerate
reg [ADDR_WIDTH - 1 : 0] next_out_addr;
reg [ADDR_WIDTH - 1 : 0] incremented_addr;
always_ff @(posedge clk) begin
if (enable) begin
out_addr <= (next_out_addr);
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst6
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_addr <= '0;
// end else begin
// if (enable) begin
// out_addr <= (next_out_addr);
// end
// end
// end
// end // async_rst6
// else begin // sync_rst6
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_addr <= '0;
// end else begin
// if (enable) begin
// out_addr <= (next_out_addr);
// end
// end
// end
// end // sync_rst6
// endgenerate
generate
if (!PURELY_INCR_AVL_SYS) begin : incremented_addr_normal
always_ff @(posedge clk) begin
if (enable) begin
if (new_burst) begin
incremented_addr <= (next_out_addr + addr_incr_sel);
end
else begin
incremented_addr <= (next_out_addr + addr_incr_sel_reg);
end
end
end // always_ff @
//if (SYNC_RESET == 0) begin : async_rst7
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// incremented_addr <= '0;
// end
// else if (enable) begin
// incremented_addr <= (next_out_addr + addr_incr_sel_reg);
// if (new_burst) begin
// incremented_addr <= (next_out_addr + addr_incr_sel);
// end
// end
// end // always_ff @
//end // async_rst7
//else begin // sync_rst7
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// incremented_addr <= '0;
// end
// else if (enable) begin
// incremented_addr <= (next_out_addr + addr_incr_sel_reg);
// if (new_burst) begin
// incremented_addr <= (next_out_addr + addr_incr_sel);
// end
// end
// end // always_ff @
//end // sync_rst7
always_comb begin
next_out_addr = in_addr;
if (!new_burst) begin
next_out_addr = incremented_addr;
end
end
end
else begin : incremented_addr_pure_av
always_ff @(posedge clk) begin
if (enable) begin
incremented_addr <= (next_out_addr + addr_incr_sel_reg);
end
end // always_ff @
//if (SYNC_RESET == 0) begin : async_rst8
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// incremented_addr <= '0;
// end
// else if (enable) begin
// incremented_addr <= (next_out_addr + addr_incr_sel_reg);
// end
// end // always_ff @
//end // async_rst8
//else begin // sync_rst8
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// incremented_addr <= '0;
// end
// else if (enable) begin
// incremented_addr <= (next_out_addr + addr_incr_sel_reg);
// end
// end // always_ff @
// end // sync_rst8
always_comb begin
next_out_addr = in_addr;
if (!new_burst) begin
next_out_addr = (incremented_addr);
end
end
end
endgenerate
// --------------------------------------------------
// Calculates the log2ceil of the input value
// --------------------------------------------------
function integer log2ceil;
input integer val;
reg[31:0] i;
begin
i = 1;
log2ceil = 0;
while (i < val) begin
log2ceil = log2ceil + 1;
i = i[30:0] << 1;
end
end
endfunction
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZm2VnW9Jup+rO8tHn46ia+m1jd1lvf4qalDbWMpZ7/iR078F3NbXmSfszSWG0PYb1O/+IcoZgGEBa4thPbK141luDnU00je40S0l+dVi8sQRSkZ06QX7VOV1HZ58TwdhajcQDrYTBrJ/wnghIvibweYzsQp21UeRH1tHdQb9EX/90LIxErNs9qZn6FdE/wU7Nnk0BApTSHa5j7Oq6whWnvIJLoY+NDfNdmguQ5c5E6FNiZBIhwP/gOXHb/Xm2fDPcMvXcyokY7FuDYoM8BdoUJ+OVZhbg6kE3dGqlFzZ60/+I5AYaHj1YtiTy6zGO1WlQnC9Sov4dHl/nkN231hsVmVVehUnm0X9f6djXsXUCx2V4JBRqjfGugv+XBeZ7HMoK6LH9u4KSTlqLlNrvhPX1VXe6UjwtOzHxYGUWqvESIeNAxWo/4NsdiISuU7Ut75o/3SMGjSlAM7UYSVvfIKi5vhCIKKXWh8sv0pKKrscZmZZ/OnnKio2r2xi88/64nRWpeQLYbzJvOmzzD5662ckE9n2faDKveVDFd+hpDfzkxyJ1LcqlVbHGqIMMAyPaTibmi0MV3Rd4tFFycrgcfYSW2I2CZTl8Rl/mstykAJ+vOi233Cy2RN1EviSi9EtnimDziOtUfW0sHScrdN1sEWY0xL2HM3oZBGMXvTOYwRGqobo4r/v6rfvRDKjzYBDzylQrvPRTibwXUKTDizbO7CXOL30RYfG/EAFhOqWFZBz89zBGyL8kCGAD5mh8/7pcdM1Y52JOHLbDLceUAQRV+5n0po"
`endif
@@ -0,0 +1,305 @@
// (C) 2001-2026 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 from 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 IP 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/main/ip/merlin/altera_merlin_axi_master_ni/address_alignment.sv#3 $
// $Revision: #3 $
// $Date: 2012/07/11 $
//-----------------------------------------
// Address alignment:
// This component will aglin input address with input size
// Support address increment with butst type and burstwrap value
//-----------------------------------------
`timescale 1 ns / 1 ns
module altera_merlin_address_alignment
#(
parameter
ADDR_W = 12,
BURSTWRAP_W = 12,
TYPE_W = 2,
SIZE_W = 3,
INCREMENT_ADDRESS = 1,
NUMSYMBOLS = 8,
SELECT_BITS = log2(NUMSYMBOLS),
IN_DATA_W = ADDR_W + (BURSTWRAP_W-1) + TYPE_W + SIZE_W,
OUT_DATA_W = ADDR_W + SELECT_BITS,
SYNC_RESET = 0
)
(
input clk,
input reset,
input [IN_DATA_W-1:0] in_data, // in_data = {wrap_boundary, address, type, size}
input in_valid,
//output in_ready,
input in_sop,
input in_eop,
output reg [OUT_DATA_W-1:0] out_data,
input out_ready
//output out_valid
);
typedef enum bit [1:0]
{
FIXED = 2'b00,
INCR = 2'b01,
WRAP = 2'b10,
RESERVED = 2'b11
} AxiBurstType;
//----------------------------------------------------
// AXSIZE decoding
//
// Turns the axsize value into the actual number of bytes
// being transferred.
// ---------------------------------------------------
function reg[9:0] bytes_in_transfer;
input [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
//--------------------------------------
// Burst type decode
//--------------------------------------
AxiBurstType write_burst_type;
function AxiBurstType burst_type_decode
(
input [1:0] axburst
);
AxiBurstType burst_type;
begin
case (axburst)
2'b00 : burst_type = FIXED;
2'b01 : burst_type = INCR;
2'b10 : burst_type = WRAP;
2'b11 : burst_type = RESERVED;
default : burst_type = INCR;
endcase
return burst_type;
end
endfunction
//----------------------------------------------------
// Ubiquitous, familiar log2 function
//----------------------------------------------------
function integer log2;
input integer value;
value = value - 1;
for(log2 = 0; value > 0; log2 = log2 + 1)
value = value >> 1;
endfunction
//------------------------------------------------------------------------
// This component will read address and size and check
// if this is aligned or not. If not then it will align this address to the size
// of the transfer:
// Check alignment:
// - With data width, can define maximun how many lower bits of address to indicate this
// address align to the size
// - Ex: 32 bits data => size can be: 1, 2, 4 bytes
// For 4 bytes: when 2 lower bits of address equal 0, this is aligned address
// addr=00|00| (0), 01|00| (4) => align to size of 4 bytes
// addr=00|01| (1) => start addr at 1, is not aligned to size 4 byte
// For 2 bytes: use last one bit to indicate algined or not
// addr=000|0| (0), 001|0| (2) => align to size of 2 bytes
// addr=000|1| (1), 001|1| (3) => not align to 2 bytes
// As size runtime change, creat mask and change accordingly to size, can detect address alignment
// and to align to size, apply this mask with zero to the address.
//-------------------------------------------------------------------------
// THe function return a vector which has width [(SELECT_BITS * 2) -1 : 0]
// in which the first part contains the mask to check if this address aligned or not
// second part contains the mast to mask address to align to size
function reg[(SELECT_BITS*2)-1 : 0] mask_select_and_align_address;
input [ADDR_W-1:0] address;
input [SIZE_W-1:0] size; // size is in AXI coding: 001 -> 2 bytes
integer i;
reg [SELECT_BITS-1:0] mask_address;
reg [SELECT_BITS-1:0] check_unaligned; // any bits =1 -> unalgined (except size = 0; 1 byte)
mask_address = '1;
check_unaligned = '0;
for(i = 0; i < SELECT_BITS ; i = i + 1) begin
if (i < size) begin
check_unaligned[i] = address[i];
mask_address[i] = 1'b0;
end
end
mask_select_and_align_address = {check_unaligned,mask_address};
endfunction
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= ~reset;
end
end
endgenerate
reg [ADDR_W-1 : 0] in_address;
reg [ADDR_W-1 : 0] first_address_aligned;
reg [SIZE_W-1 : 0] in_size;
reg [(SELECT_BITS*2)-1 : 0] output_masks;
// Extract information from input data
assign in_address = in_data[SIZE_W+ADDR_W-1 : SIZE_W];
assign in_size = in_data[SIZE_W-1 : 0];
// Generate the masks
always_comb
begin
output_masks = mask_select_and_align_address(in_address, in_size);
end
// Align address if needed
generate
// SELECT_BITS == 1: input packet has 1 NUMSYMBOLS (1 bytes), it is aligned
if (SELECT_BITS == 0)
assign first_address_aligned = in_address;
else begin
// SELECT_BITS ==1 :input packet 2 bytes (2 SYMBOLS)
wire [SELECT_BITS-1 : 0] aligned_address_bits;
if (SELECT_BITS == 1)
assign aligned_address_bits = in_address[0] & output_masks[0];
else
assign aligned_address_bits = in_address[SELECT_BITS-1:0] & output_masks[SELECT_BITS-1:0];
assign first_address_aligned = {in_address[ADDR_W-1 : SELECT_BITS], aligned_address_bits};
end
endgenerate
// Increment address base on size, first address keep the same
generate
if (INCREMENT_ADDRESS)
begin
reg [ADDR_W-1 : 0] increment_address;
reg [ADDR_W-1 : 0] out_aligned_address_burst;
reg [ADDR_W-1 : 0] address_burst;
reg [ADDR_W-1 : 0] base_address;
reg [9 : 0] number_bytes_transfer;
reg [ADDR_W-1 : 0] burstwrap_mask;
reg [ADDR_W-1 : 0] burst_address_high;
reg [ADDR_W-1 : 0] burst_address_low;
reg [BURSTWRAP_W-2 :0] in_burstwrap_boundary;
reg [TYPE_W-1 : 0] in_type;
//------------------------------------------------
// Use the extended burstwrap value to split the high (constant) and
// low (changing) part of the address
//-----------------------------------------------
assign in_type = in_data[SIZE_W+ADDR_W+TYPE_W-1 : SIZE_W+ADDR_W];
assign in_burstwrap_boundary = in_data[IN_DATA_W-1 : ADDR_W+TYPE_W+SIZE_W];
assign burstwrap_mask = {{(ADDR_W - BURSTWRAP_W){1'b0}}, in_burstwrap_boundary};
assign burst_address_high = out_aligned_address_burst & ~burstwrap_mask;
assign burst_address_low = out_aligned_address_burst;
assign number_bytes_transfer = bytes_in_transfer(in_size);
assign write_burst_type = burst_type_decode(in_type);
always @*
begin
if (in_sop)
begin
out_aligned_address_burst = in_address;
base_address = first_address_aligned;
end
else
begin
out_aligned_address_burst = address_burst;
base_address = out_aligned_address_burst;
end
case (write_burst_type)
INCR:
increment_address = base_address + number_bytes_transfer;
WRAP:
increment_address = ((burst_address_low + number_bytes_transfer) & burstwrap_mask) | burst_address_high;
FIXED:
increment_address = out_aligned_address_burst;
default:
increment_address = base_address + number_bytes_transfer;
endcase // case (write_burst_type)
end // always @ *
if (SYNC_RESET == 0) begin : async_rst0
always_ff @(posedge clk, negedge reset)
begin
if (!reset)
begin
address_burst <= '0;
end
else
begin
if (in_valid & out_ready)
address_burst <= increment_address;
end
end
end : async_rst0
else begin : sync_rst0
always_ff @(posedge clk)
begin
if (internal_sclr)
begin
address_burst <= '0;
end
else
begin
if (in_valid & out_ready)
address_burst <= increment_address;
end
end
end : sync_rst0
// send data to output with 2 part: [mask_t0_algin][address_aligned_increment]
// corner case when SELECT_BITS==0 - total bits in
// [SELECTS_BITS-1:0] ==> 1-:0 ==> 2 bits in total
// leads to warning
if (SELECT_BITS==0)
assign out_data = out_aligned_address_burst;
else
assign out_data = {output_masks[SELECT_BITS-1 : 0], out_aligned_address_burst};
end // if (INCREMENT_ADDRESS)
else
begin
// corner case when SELECT_BITS==0 - total bits in
// [SELECTS_BITS-1:0] ==> 1-:0 ==> 2 bits in total
// leads to warning
if (SELECT_BITS==0)
assign out_data = first_address_aligned;
else
assign out_data = {output_masks[SELECT_BITS-1 : 0], first_address_aligned};
end // else: !if(INCREMENT_ADDRESS)
endgenerate
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZnuSxX8yXxnIFVWsgCk75Z0P+dtbDvmJdtQl1WjW4yFuhoOU6T348GM/xUHtJ4nzM+Ie8UNgnT16AXfoOSoZ6aw4EqtmutAt1g0WrS8Zo7lntdL4Ed4jMhrdzQ2wGXcukpdBXSOlxyVkCs8O5Bx5bsJHA8kY1r+dEjpFU6yRXbht/crFehVXoHCjTTZnCo6ONciQai4cPqisPuj4rwOI0P18Yry6OKgj6AYn8jpBhuXzb8sDJ3t4lulV43YetVoYKIdiLdg9MNtOudp0cdO7C9wiNkMhIPLI2VLiAgdsxlTZo0H7/klMzcS7oMYhgKBYj3rMGfIF8GIfjTv7DXR06ED3LZScux5eFxq7qC9RRhgCFd2O/5OwjkezW2Fe1fos97+/4c0SVIufbIeAiMRsYmglnEcMCPwWnhbxi/B4Q/YpYAH96gY/+ITpxiLlp7H+Wot7TKsR10cNB8FfVYrKfDgFm3aAGBtmVsUAz3X31S6DJdo/eXRPthu3tfuBI4BAB2tQptyaBZIqDMWE/TeUinC41fvbEAe/N84+in0g3XgKSMRshfZ8yKNB5HICw0eV/rxJsVyCdWVsaafsz31CT1ij2Mvr1H7LbAUmPVt546kJCR7d/o6inwycxcb5G7r8r7du8eigB4sXm3QEMQTpHFX0PXZW0KnyL4Dml+CXK43oRj2wIP58dXUWPsi8nphSGr64d8Zt0FlS2NO2Y0jv3ecZkOIjZu+9pPoWGxFSdPY/fBYS18Q736mwIEkGiruEglqw3eKurFsVAnQNbb/cn/1"
`endif
@@ -0,0 +1,96 @@
// (C) 2001-2026 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 from 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 IP 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.
// (C) 2001-2012 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/main/ip/merlin/altera_merlin_burst_adapter/altera_merlin_burst_adapter.sv#68 $
// $Revision: #68 $
// $Date: 2014/01/23 $
`timescale 1 ns / 1 ns
// -------------------------------------------------------
// Adapter for uncompressed transactions only. This adapter will
// typically be used to adapt burst length for non-bursting
// wide to narrow Avalon links.
// -------------------------------------------------------
module altera_merlin_burst_adapter_uncompressed_only
#(
parameter
PKT_BYTE_CNT_H = 5,
PKT_BYTE_CNT_L = 0,
PKT_BYTEEN_H = 83,
PKT_BYTEEN_L = 80,
ST_DATA_W = 84,
ST_CHANNEL_W = 8
)
(
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
);
localparam
PKT_BYTE_CNT_W = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1,
NUM_SYMBOLS = PKT_BYTEEN_H - PKT_BYTEEN_L + 1;
wire [PKT_BYTE_CNT_W - 1 : 0] num_symbols_sig = NUM_SYMBOLS[PKT_BYTE_CNT_W - 1 : 0];
always_comb begin : source0_data_assignments
source0_valid = sink0_valid;
source0_channel = sink0_channel;
source0_startofpacket = sink0_startofpacket;
source0_endofpacket = sink0_endofpacket;
source0_data = sink0_data;
source0_data[PKT_BYTE_CNT_H : PKT_BYTE_CNT_L] = num_symbols_sig;
sink0_ready = source0_ready;
end
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZlEl7U1mwDa2foPMdSqYqEvxrVPv0jMzxA0aRf5GvKemQQYiAUmoPZ/yty49qVq2u4nCWeBwiIOIWm7gDC9G7PUqb6tQOwrlINch7TSLyDBSTQRE9hXc7SldcwRHZbphJdXk8dLtmihOMDJFCjqPdl3yLIyPr7YL6350GrMmyAi0VBnzeb3PXYeJ774WH1+ABTda662GekklRXGy8DtIgPk0IIg3Oj1dwRb3pFTN66nlIPiZBgL8gjO0CYauPX/q9nMQFGeoQZr4+5e98MGAqbEcnhgooJzrOeQs2tRxgUiChvubqPONnP1A1YFtubOn7CcIC2RelzTbXvuG7xBL8BFrgyCRg/DB4902JDspTPYHKTGnATpyW9IaQ1niNwNhdHAEqiIUKBD/YZXcjnXVgHmwCUait0N//YwiEJonwrRzUsNWzXI1Hqd95q5Iyv88LJIqRopX6GB7QDDG42Z8rlNeHcFQnyJKEV5BhNCL8p3A8ygXqZ6pjUDwYOR+Dgarpg9ij6TIXQQHiiEozYHxBY0fcHtNb8FfenfODkF3XaHFzJciEYDrjHK2q3Ns7fTAp+HkmKgxb/S/s3qrHnpl3GVY+nokliANaXmDBgv4PGyFDfOm5ZifW3H7XSXvHNPSnpKxGuEoZt2v0zN2gZIcCaS5smLpTK+Lh0uks2gCvA/v1P41pbHzy/7CM/JZiP8V8q0zQ0ELX/oWMYwC/t43xkpbirj8nuULPIQPAupetsXyCnaz2p2/DdsSsbGj3kyXN8JLoZV990Dl5M4UL/HzKhw"
`endif
@@ -0,0 +1,545 @@
// (C) 2001-2026 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 from 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 IP 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/26.1/ip/iconnect/merlin/altera_merlin_burst_adapter/new_source/altera_wrap_burst_converter.sv#1 $
// $Revision: #1 $
// $Date: 2026/02/05 $
// ------------------------------------------------------
// This component is specially for Wrapping Avalon slave.
// It converts burst length of input packet
// to match slave burst.
// ------------------------------------------------------
`timescale 1 ns / 1 ns
module altera_wrap_burst_converter
#(
parameter
// ----------------------------------------
// Burst length Parameters
// (real burst length value, not bytecount)
// ----------------------------------------
MAX_IN_LEN = 16,
MAX_OUT_LEN = 4,
ADDR_WIDTH = 12,
BNDRY_WIDTH = 12,
NUM_SYMBOLS = 4,
AXI_SLAVE = 0,
OPTIMIZE_WRITE_BURST = 0,
SYNC_RESET = 0,
// ------------------
// Derived Parameters
// ------------------
LEN_WIDTH = log2ceil(MAX_IN_LEN) + 1,
OUT_LEN_WIDTH = log2ceil(MAX_OUT_LEN) + 1,
LOG2_NUMSYMBOLS = log2ceil(NUM_SYMBOLS)
)
(
input clk,
input reset,
input enable_write,
input enable_read,
input [LEN_WIDTH - 1 : 0] in_len,
input [LEN_WIDTH - 1 : 0] first_len,
input in_sop,
input [ADDR_WIDTH - 1 : 0] in_addr,
input [ADDR_WIDTH - 1 : 0] in_addr_reg,
input [BNDRY_WIDTH - 1 : 0] in_boundary,
input [BNDRY_WIDTH - 1 : 0] in_burstwrap,
input [BNDRY_WIDTH - 1 : 0] in_burstwrap_reg,
// converted output length
// out_len : compressed burst, read
// uncompressed_len: uncompressed, write
output reg [LEN_WIDTH - 1 : 0] out_len,
output reg [LEN_WIDTH - 1 : 0] uncompr_out_len,
// Compressed address output
output reg [ADDR_WIDTH - 1 : 0] out_addr,
output reg new_burst_export
);
// ------------------------------
// Local parameters
// ------------------------------
localparam
OUT_BOUNDARY = MAX_OUT_LEN * NUM_SYMBOLS,
ADDR_SEL = log2ceil(OUT_BOUNDARY);
// ----------------------------------------
// Signals for wrapping support
// ----------------------------------------
reg [LEN_WIDTH - 1 : 0] remaining_len;
reg [LEN_WIDTH - 1 : 0] next_out_len;
reg [LEN_WIDTH - 1 : 0] next_rem_len;
reg [LEN_WIDTH - 1 : 0] uncompr_remaining_len;
reg new_burst;
reg uncompr_sub_burst;
reg [LEN_WIDTH - 1 : 0] next_uncompr_out_len;
reg [LEN_WIDTH - 1 : 0] next_uncompr_sub_len;
// Avoid QIS warning
wire [OUT_LEN_WIDTH - 1 : 0] max_out_length;
assign max_out_length = MAX_OUT_LEN[OUT_LEN_WIDTH - 1 : 0];
// ----------------------------------------
// Calculate aligned length for WRAP burst
// ----------------------------------------
reg [ADDR_WIDTH - 1 : 0] extended_burstwrap;
reg [ADDR_WIDTH - 1 : 0] extended_burstwrap_reg;
always_comb begin
extended_burstwrap = {{(ADDR_WIDTH - BNDRY_WIDTH) {in_burstwrap[BNDRY_WIDTH - 1]}}, in_burstwrap};
extended_burstwrap_reg = {{(ADDR_WIDTH - BNDRY_WIDTH) {in_burstwrap_reg[BNDRY_WIDTH - 1]}}, in_burstwrap_reg};
new_burst_export = new_burst;
end
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= reset;
end
end
endgenerate
// -------------------------------------------
// length calculation
// -------------------------------------------
reg [LEN_WIDTH -1 : 0] next_uncompr_remaining_len;
always_comb begin
// Signals name
// *_uncompr_* --> uncompressed transaction
// -------------------------------------------
// Always use max_out_length as possible.
// Else use the remaining length.
// If in length smaller and not cross bndry or same, pass thru.
if (in_sop) begin
uncompr_remaining_len = in_len;
end
else begin
uncompr_remaining_len = next_uncompr_remaining_len;
end
end // always_comb
// compressed transactions
always_comb begin : proc_compressed_read
remaining_len = in_len;
if (!new_burst)
remaining_len = next_rem_len;
end
always_comb begin
next_uncompr_out_len = first_len;
if (in_sop) begin
next_uncompr_out_len = first_len;
end
else begin
if (uncompr_sub_burst)
next_uncompr_out_len = next_uncompr_sub_len;
else begin
if (uncompr_remaining_len < max_out_length)
next_uncompr_out_len = uncompr_remaining_len;
else
next_uncompr_out_len = max_out_length;
end
end
end
// Compressed transaction: Always try to send MAX out_len then remaining length.
// Seperate it as the main difference is the first out len.
// For a WRAP burst, the first beat is the aligned length, then similar to INCR.
always_comb begin
if (new_burst) begin
next_out_len = first_len;
end
else begin
next_out_len = max_out_length;
if (remaining_len < max_out_length) begin
next_out_len = remaining_len;
end
end
end // always_comb
// --------------------------------------------------
// Length remaining calculation : Compressed
// --------------------------------------------------
// length remaining for compressed transaction
// for wrap, need special handling for first out length
always_ff @(posedge clk) begin
if (enable_read) begin
if (new_burst)
next_rem_len <= in_len - first_len;
else
next_rem_len <= next_rem_len - max_out_length;
end
end // always_ff @
//generate
// if (SYNC_RESET == 0) begin : async_rst1
// always_ff @(posedge clk, posedge reset) begin
// if (reset)
// next_rem_len <= 0;
// else if (enable_read) begin
// if (new_burst)
// next_rem_len <= in_len - first_len;
// else
// next_rem_len <= next_rem_len - max_out_length;
// end
// end // always_ff @
// end // async_rst1
// else begin // sync_rst1
// always_ff @(posedge clk) begin
// if (internal_sclr)
// next_rem_len <= 0;
// else if (enable_read) begin
// if (new_burst)
// next_rem_len <= in_len - first_len;
// else
// next_rem_len <= next_rem_len - max_out_length;
// end
// end // always_ff @
// end // sync_rst1
// endgenerate
// --------------------------------------------------
// Length remaining calculation : Uncompressed
// --------------------------------------------------
always_ff @(posedge clk) begin
if (enable_write) begin
if (in_sop)
next_uncompr_remaining_len <= in_len - first_len;
else if (!uncompr_sub_burst)
next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
end
end // always_ff @
// length for each sub-burst if it needs to chop the burst
always_ff @(posedge clk) begin
if (enable_write) begin
next_uncompr_sub_len <= next_uncompr_out_len - 1'b1; // in term of length, it just reduces 1
end
end
generate
if (SYNC_RESET == 0) begin : async_rst2
//always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_uncompr_remaining_len <= 0;
// end
// else if (enable_write) begin
// if (in_sop)
// next_uncompr_remaining_len <= in_len - first_len;
// else if (!uncompr_sub_burst)
// next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
// end
//end // always_ff @
//// length for each sub-burst if it needs to chop the burst
//always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_uncompr_sub_len <= 0;
// end
// else if (enable_write) begin
// next_uncompr_sub_len <= next_uncompr_out_len - 1'b1; // in term of length, it just reduces 1
// end
//end
// the sub-burst still active
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
uncompr_sub_burst <= 0;
end
else if (enable_write) begin
uncompr_sub_burst <= (next_uncompr_out_len > 1'b1);
end
end
end // async_rst1
else begin // sync_rst2
//always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_uncompr_remaining_len <= 0;
// end
// else if (enable_write) begin
// if (in_sop)
// next_uncompr_remaining_len <= in_len - first_len;
// else if (!uncompr_sub_burst)
// next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
// end
//end // always_ff @
//
//// length for each sub-burst if it needs to chop the burst
//always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_uncompr_sub_len <= 0;
// end
// else if (enable_write) begin
// next_uncompr_sub_len <= next_uncompr_out_len - 1'b1; // in term of length, it just reduces 1
// end
//end
// the sub-burst still active
always_ff @(posedge clk) begin
if (internal_sclr) begin
uncompr_sub_burst <= 0;
end
else if (enable_write) begin
uncompr_sub_burst <= (next_uncompr_out_len > 1'b1);
end
end
end // sync_rst2
endgenerate
// --------------------------------------------------
// Control signals
// --------------------------------------------------
wire end_compressed_sub_burst;
assign end_compressed_sub_burst = (remaining_len == next_out_len);
// new_burst:
// the converter takes in_len for new caculation
generate
if (SYNC_RESET == 0) begin : async_rst3
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
new_burst <= 1;
end
else if (enable_read) begin
new_burst <= end_compressed_sub_burst;
end
end
end // async_rst3
else begin // sync_rst3
always_ff @(posedge clk) begin
if (internal_sclr) begin
new_burst <= 1;
end
else if (enable_read) begin
new_burst <= end_compressed_sub_burst;
end
end
end // sync_rst3
endgenerate
// --------------------------------------------------
// Output length
// --------------------------------------------------
// register out_len for compressed trans
always_ff @(posedge clk) begin
if (enable_read) begin
out_len <= next_out_len;
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst4
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_len <= 0;
// end
// else if (enable_read) begin
// out_len <= next_out_len;
// end
// end
// end // async_rst4
// else begin // sync_rst4
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_len <= 0;
// end
// else if (enable_read) begin
// out_len <= next_out_len;
// end
// end
// end // sync_rst4
//endgenerate
// register uncompr_out_len for uncompressed trans
generate
if (OPTIMIZE_WRITE_BURST) begin : optimized_write_burst_len
always_ff @(posedge clk) begin
if (enable_read) begin
uncompr_out_len <= first_len;
end
end
//if (SYNC_RESET == 0) begin : async_rst5
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// uncompr_out_len <= '0;
// end
// //else if (enable_write) begin
// else if (enable_read) begin
// uncompr_out_len <= first_len;
// end
// end
//end // async_rst5
//else begin // sync_rst5
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// uncompr_out_len <= '0;
// end
// //else if (enable_write) begin
// else if (enable_read) begin
// uncompr_out_len <= first_len;
// end
// end
//end // sync_rst5
end
else begin : unoptimized_write_burst_len
always_ff @(posedge clk) begin
if (enable_write) begin
uncompr_out_len <= next_uncompr_out_len;
end
end
//if (SYNC_RESET == 0) begin : async_rst6
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// uncompr_out_len <= '0;
// end
// else if (enable_write) begin
// uncompr_out_len <= next_uncompr_out_len;
// end
// end
// end // async_rst6
// else begin // sync_rst6
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// uncompr_out_len <= '0;
// end
// else if (enable_write) begin
// uncompr_out_len <= next_uncompr_out_len;
// end
// end
// end // sync_rst6
end // else unoptimized
endgenerate
// --------------------------------------------------
// Address calculation
// --------------------------------------------------
reg [ADDR_WIDTH - 1 : 0] addr_incr;
localparam [ADDR_WIDTH - 1 : 0] ADDR_INCR = MAX_OUT_LEN << LOG2_NUMSYMBOLS;
assign addr_incr = ADDR_INCR[ADDR_WIDTH - 1 : 0];
reg [ADDR_WIDTH - 1 : 0] next_out_addr;
reg [ADDR_WIDTH - 1 : 0] incremented_addr;
always_ff @(posedge clk) begin
if (enable_read) begin
out_addr <= (next_out_addr);
end
end // always_ff @
//generate
// if (SYNC_RESET == 0) begin : async_rst7
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_addr <= '0;
// end
// else begin
// if (enable_read) begin
// out_addr <= (next_out_addr);
// end
// end
// end // always_ff @
// end // async_rst7
// else begin // sync_rst7
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_addr <= '0;
// end
// else begin
// if (enable_read) begin
// out_addr <= (next_out_addr);
// end
// end
// end // always_ff @
// end // sync_rst7
// endgenerate
// use burstwrap/burstwrap_reg to calculate address incrementing
always_ff @(posedge clk) begin
if (enable_read) begin
incremented_addr <= ((next_out_addr + addr_incr) & extended_burstwrap_reg);
if (new_burst) begin
incremented_addr <= ((next_out_addr + (first_len << LOG2_NUMSYMBOLS)) & extended_burstwrap); //byte address
end
end
end // always_ff @
//generate
// if (SYNC_RESET == 0) begin : async_rst8
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// incremented_addr <= '0;
// end
// else if (enable_read) begin
// incremented_addr <= ((next_out_addr + addr_incr) & extended_burstwrap_reg);
// if (new_burst) begin
// incremented_addr <= ((next_out_addr + (first_len << LOG2_NUMSYMBOLS)) & extended_burstwrap); //byte address
// end
// end
// end // always_ff @
// end // async_rst8
// else begin // sync_rst8
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// incremented_addr <= '0;
// end
// else if (enable_read) begin
// incremented_addr <= ((next_out_addr + addr_incr) & extended_burstwrap_reg);
// if (new_burst) begin
// incremented_addr <= ((next_out_addr + (first_len << LOG2_NUMSYMBOLS)) & extended_burstwrap); //byte address
// end
// end
// end // always_ff @
// end // sync_rst8
// endgenerate
always_comb begin
next_out_addr = in_addr;
if (!new_burst) begin
next_out_addr = in_addr_reg & ~extended_burstwrap_reg | incremented_addr;
end
end
// --------------------------------------------------
// Calculates the log2ceil of the input value
// --------------------------------------------------
function integer log2ceil;
input integer val;
reg[31:0] i;
begin
i = 1;
log2ceil = 0;
while (i < val) begin
log2ceil = log2ceil + 1;
i = i[30:0] << 1;
end
end
endfunction
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZllKnWAX9N5dw2ADgRBGnFz2jF7qT9llBrp2SnRSqQQqPwDlEJk2UeGJPg3ES1cQXyK7KIOLJhXnkePUfQ+bKASdNX8T7B/JBvWmq4yvDwftVX9k5+DhxB4OJiOiGMqZKtpOPRfmNUafND1njfnIo2+Il2fpo21b+lm2UGn2crz+4Ezg30kTMwDWGkjPxTpP+2w7tTrZzHLDzMZ89zy8rTRiEFhl1zRMzfRBlxZEdr8KZeO1XX5rQSctBdRLCrIlqVgsWi3TEoSoxumsqHaOLlStKdjywMkU8JDDdO6voRm5WiU/LSmcDRdX/TQX9Ml2MORWtmZi32gRfAxwBnIj8Gi3bWIbi4v9r55CeoZqWe2dia2mOA6SwlKOd1EnFKwLwNrUsR2ia05vFXplhOCqXNZPp0BEo7XnkZjZ5dtrHxxGrr7g08uOjFbYbAd38T3KlaPDq41azfwlaky8agCeG50E5Vq0me3pK7xJBMr5JAACNM1tlbLvx+CtxMrVouByfc6xI/1b9Az/bxjsHy0MHAYHq4PPn5FlFDrk1iOBUD7zef+6Dy0a1pN7+YgZIw19YBJo2i9FTEcRCEt4qTdjY9z4N2KltJPRl5OFjEONQnCrTLlZcJJHzuHoW3RbnWyk6bdJ+OnsHUq+R7dIBiuetQcIcAw5nICBm106qEL6rTdp4xSX4a5uMgRvkm22XjXE1nbADFmkPKafOWwnPFon9mLQnL6a2qObBM3miUYE8VCVI/iTtB8oWJ9/SnA6EEyCHYZ6crWU3hwkln3/4RQRXw6"
`endif
@@ -0,0 +1,361 @@
// (C) 2001-2026 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 from 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 IP 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.
`timescale 1 ns / 1 ns
// -----------------------------------------------------
// Top level for the burst adapter. This selects the
// implementation for the adapter, based on the
// parameterization.
// -----------------------------------------------------
module qsys_top_altera_merlin_burst_adapter_1940_6zvwdfy
#(
parameter
// Indicates the implementation to instantiate:
// "13.1" means the slow, inexpensive generic burst converter.
// "new" means the fast, expensive per-burst converter.
ADAPTER_VERSION = "13.1",
// Indicates if this adapter needs to support read bursts
// (almost always true).
COMPRESSED_READ_SUPPORT = 1,
// 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,
PKT_SAI_H = 89,
PKT_SAI_L = 89,
PKT_EOP_OOO = 90,
PKT_SOP_OOO = 91,
ST_DATA_W = 92,
ST_CHANNEL_W = 8,
ROLE_BASED_USER = 0,
ENABLE_AXI5 = 0,
ENABLE_OOO = 0,
// Component-specific parameters. Explained
// in the implementation levels
IN_NARROW_SIZE = 0,
NO_WRAP_SUPPORT = 0,
INCOMPLETE_WRAP_SUPPORT = 1,
BURSTWRAP_CONST_MASK = 0,
BURSTWRAP_CONST_VALUE = 2147483647, //equivalent to {31{1'b1}} -- ncsim does not like negative values (-1), or the replication format
OUT_NARROW_SIZE = 0,
OUT_FIXED = 0,
OUT_COMPLETE_WRAP = 0,
BYTEENABLE_SYNTHESIS = 0,
PIPE_INPUTS = 0,
OUT_BYTE_CNT_H = 5,
OUT_BURSTWRAP_H = 11,
SYNC_RESET = 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 wire source0_valid,
output wire [ST_DATA_W-1 : 0] source0_data,
output wire [ST_CHANNEL_W-1 : 0] source0_channel,
output wire source0_startofpacket,
output wire source0_endofpacket,
input source0_ready
);
localparam PKT_BURSTWRAP_W = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1;
generate if (COMPRESSED_READ_SUPPORT == 0) begin : altera_merlin_burst_adapter_uncompressed_only
// -------------------------------------------------------------------
// The reduced version of the adapter is only meant to be used on
// non-bursting wide to narrow links.
// -------------------------------------------------------------------
altera_merlin_burst_adapter_uncompressed_only #(
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L),
.PKT_BYTEEN_H (PKT_BYTEEN_H),
.PKT_BYTEEN_L (PKT_BYTEEN_L),
.ST_DATA_W (ST_DATA_W),
.ST_CHANNEL_W (ST_CHANNEL_W)
) burst_adapter (
.clk (clk),
.reset (reset),
.sink0_valid (sink0_valid),
.sink0_data (sink0_data),
.sink0_channel (sink0_channel),
.sink0_startofpacket (sink0_startofpacket),
.sink0_endofpacket (sink0_endofpacket),
.sink0_ready (sink0_ready),
.source0_valid (source0_valid),
.source0_data (source0_data),
.source0_channel (source0_channel),
.source0_startofpacket (source0_startofpacket),
.source0_endofpacket (source0_endofpacket),
.source0_ready (source0_ready)
);
end
else if (ADAPTER_VERSION == "13.1") begin : altera_merlin_burst_adapter_13_1
// -----------------------------------------------------
// This is the generic converter implementation, which attempts
// to convert all burst types with a generalized conversion
// function. This results in low area, but low fmax.
// -----------------------------------------------------
altera_merlin_burst_adapter_13_1 #(
.PKT_BEGIN_BURST (PKT_BEGIN_BURST),
.PKT_ADDR_H (PKT_ADDR_H ),
.PKT_ADDR_L (PKT_ADDR_L),
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L ),
.PKT_BURSTWRAP_H (PKT_BURSTWRAP_H),
.PKT_BURSTWRAP_L (PKT_BURSTWRAP_L),
.PKT_TRANS_COMPRESSED_READ (PKT_TRANS_COMPRESSED_READ),
.PKT_TRANS_WRITE (PKT_TRANS_WRITE),
.PKT_TRANS_READ (PKT_TRANS_READ),
.PKT_BYTEEN_H (PKT_BYTEEN_H),
.PKT_BYTEEN_L (PKT_BYTEEN_L),
.PKT_BURST_TYPE_H (PKT_BURST_TYPE_H),
.PKT_BURST_TYPE_L (PKT_BURST_TYPE_L),
.PKT_BURST_SIZE_H (PKT_BURST_SIZE_H),
.PKT_BURST_SIZE_L (PKT_BURST_SIZE_L),
.PKT_SAI_H (PKT_SAI_H),
.PKT_SAI_L (PKT_SAI_L),
.PKT_EOP_OOO (PKT_EOP_OOO),
.PKT_SOP_OOO (PKT_SOP_OOO),
.ENABLE_OOO (ENABLE_OOO),
.IN_NARROW_SIZE (IN_NARROW_SIZE),
.BYTEENABLE_SYNTHESIS (BYTEENABLE_SYNTHESIS),
.OUT_NARROW_SIZE (OUT_NARROW_SIZE),
.OUT_FIXED (OUT_FIXED),
.OUT_COMPLETE_WRAP (OUT_COMPLETE_WRAP),
.ST_DATA_W (ST_DATA_W),
.ST_CHANNEL_W (ST_CHANNEL_W),
.ROLE_BASED_USER (ROLE_BASED_USER),
.ENABLE_AXI5 (ENABLE_AXI5),
.BURSTWRAP_CONST_MASK (BURSTWRAP_CONST_MASK),
.BURSTWRAP_CONST_VALUE (BURSTWRAP_CONST_VALUE),
.PIPE_INPUTS (PIPE_INPUTS),
.NO_WRAP_SUPPORT (NO_WRAP_SUPPORT),
.OUT_BYTE_CNT_H (OUT_BYTE_CNT_H),
.OUT_BURSTWRAP_H (OUT_BURSTWRAP_H),
.SYNC_RESET (SYNC_RESET)
) burst_adapter (
.clk (clk),
.reset (reset),
.sink0_valid (sink0_valid),
.sink0_data (sink0_data),
.sink0_channel (sink0_channel),
.sink0_startofpacket (sink0_startofpacket),
.sink0_endofpacket (sink0_endofpacket),
.sink0_ready (sink0_ready),
.source0_valid (source0_valid),
.source0_data (source0_data),
.source0_channel (source0_channel),
.source0_startofpacket (source0_startofpacket),
.source0_endofpacket (source0_endofpacket),
.source0_ready (source0_ready)
);
end
else begin : altera_merlin_burst_adapter_new
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;
// -----------------------------------------------------
// This is the per-burst-type converter implementation. This attempts
// to convert bursts with specialized functions for each burst
// type. This typically results in higher area, but higher fmax.
// -----------------------------------------------------
altera_merlin_burst_adapter_new #(
.PKT_BEGIN_BURST (PKT_BEGIN_BURST),
.PKT_ADDR_H (PKT_ADDR_H ),
.PKT_ADDR_L (PKT_ADDR_L),
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L ),
.PKT_BURSTWRAP_H (PKT_BURSTWRAP_H),
.PKT_BURSTWRAP_L (PKT_BURSTWRAP_L),
.PKT_TRANS_COMPRESSED_READ (PKT_TRANS_COMPRESSED_READ),
.PKT_TRANS_WRITE (PKT_TRANS_WRITE),
.PKT_TRANS_READ (PKT_TRANS_READ),
.PKT_BYTEEN_H (PKT_BYTEEN_H),
.PKT_BYTEEN_L (PKT_BYTEEN_L),
.PKT_BURST_TYPE_H (PKT_BURST_TYPE_H),
.PKT_BURST_TYPE_L (PKT_BURST_TYPE_L),
.PKT_BURST_SIZE_H (PKT_BURST_SIZE_H),
.PKT_BURST_SIZE_L (PKT_BURST_SIZE_L),
.PKT_SAI_H (PKT_SAI_H),
.PKT_SAI_L (PKT_SAI_L),
.PKT_EOP_OOO (PKT_EOP_OOO),
.PKT_SOP_OOO (PKT_SOP_OOO),
.ENABLE_OOO (ENABLE_OOO),
.IN_NARROW_SIZE (IN_NARROW_SIZE),
.BYTEENABLE_SYNTHESIS (BYTEENABLE_SYNTHESIS),
.OUT_NARROW_SIZE (OUT_NARROW_SIZE),
.OUT_FIXED (OUT_FIXED),
.OUT_COMPLETE_WRAP (OUT_COMPLETE_WRAP),
.ST_DATA_W (ST_DATA_W),
.ROLE_BASED_USER (ROLE_BASED_USER),
.ENABLE_AXI5 (ENABLE_AXI5),
.ST_CHANNEL_W (ST_CHANNEL_W),
.BURSTWRAP_CONST_MASK (BURSTWRAP_CONST_MASK),
.BURSTWRAP_CONST_VALUE (BURSTWRAP_CONST_VALUE),
.PIPE_INPUTS (PIPE_INPUTS),
.NO_WRAP_SUPPORT (NO_WRAP_SUPPORT),
.INCOMPLETE_WRAP_SUPPORT (INCOMPLETE_WRAP_SUPPORT),
.OUT_BYTE_CNT_H (OUT_BYTE_CNT_H),
.OUT_BURSTWRAP_H (OUT_BURSTWRAP_H),
.SYNC_RESET (SYNC_RESET)
) burst_adapter (
.clk (clk),
.reset (reset),
.sink0_valid (sink0_pipe_valid),
.sink0_data (sink0_pipe_data),
.sink0_channel (sink0_pipe_channel),
.sink0_startofpacket (sink0_pipe_sop),
.sink0_endofpacket (sink0_pipe_eop),
.sink0_ready (sink0_pipe_ready),
.source0_valid (source0_valid),
.source0_data (source0_data),
.source0_channel (source0_channel),
.source0_startofpacket (source0_startofpacket),
.source0_endofpacket (source0_endofpacket),
.source0_ready (source0_ready)
);
if(PIPE_INPUTS == 1) begin: pipe_inputs
qsys_top_altera_merlin_burst_adapter_altera_avalon_st_pipeline_stage_1940_ykdw6di # (
.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),
.SYNC_RESET (SYNC_RESET)
) pipe_stage (
.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)
);
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
end
endgenerate
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= reset;
end
end
endgenerate
// synthesis translate_off
// -----------------------------------------------------
// Simulation-only check for incoming burstwrap values inconsistent with
// BURSTWRAP_CONST_MASK, which would indicate a paramerization error.
//
// Should be turned into an assertion, really.
// -----------------------------------------------------
generate
if (SYNC_RESET == 0) begin : async_rst0
always @(posedge clk or posedge reset) begin
if (reset) begin
end
else if (sink0_valid &&
BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0] &
(BURSTWRAP_CONST_VALUE[PKT_BURSTWRAP_W - 1:0] ^ sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L])
) begin
$display("%t: %m: Error: burstwrap value %X is inconsistent with BURSTWRAP_CONST_MASK value %X", $time(), sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L], BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0]);
end
end
end : async_rst0
else begin : sync_rst0
always @(posedge clk ) begin
if ((internal_sclr == 1'b0) && sink0_valid &&
BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0] &
(BURSTWRAP_CONST_VALUE[PKT_BURSTWRAP_W - 1:0] ^ sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L])
) begin
$display("%t: %m: Error: burstwrap value %X is inconsistent with BURSTWRAP_CONST_MASK value %X", $time(), sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L], BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0]);
end
end
end : sync_rst0
endgenerate
// synthesis translate_on
endmodule
@@ -0,0 +1,66 @@
// qsys_top_altera_merlin_burst_adapter_altera_avalon_st_pipeline_stage_1940_ykdw6di.v
// Generated using ACDS version 26.1 110
`timescale 1 ps / 1 ps
module qsys_top_altera_merlin_burst_adapter_altera_avalon_st_pipeline_stage_1940_ykdw6di #(
parameter SYMBOLS_PER_BEAT = 1,
parameter BITS_PER_SYMBOL = 171,
parameter USE_PACKETS = 1,
parameter USE_EMPTY = 0,
parameter EMPTY_WIDTH = 0,
parameter CHANNEL_WIDTH = 2,
parameter PACKET_WIDTH = 2,
parameter ERROR_WIDTH = 0,
parameter PIPELINE_READY = 1,
parameter SYNC_RESET = 1
) (
input wire clk, // cr0.clk, Clock input
input wire reset, // cr0_reset.reset, Reset input
output wire in_ready, // sink0.ready, Ready port of Avalon Streaming Sink Interface; indicates when sink interface is ready to receive data
input wire in_valid, // .valid, Valid data port of Avalon Streaming Sink Interface; high when input data is valid
input wire in_startofpacket, // .startofpacket, Start of packet port of Avalon Streaming Sink Interface;Indicates start of incoming packet
input wire in_endofpacket, // .endofpacket, End of packet port of Avalon Streaming Sink Interface; Indicates end of incoming packet
input wire [170:0] in_data, // .data, Input Data port of Avalon Streaming Sink Interface
input wire [1:0] in_channel, // .channel, Channel input port of Avalon Streaming Sink Interface
input wire out_ready, // source0.ready, Ready port of Avalon Streaming Source Interface; indicates to source that data can be sent
output wire out_valid, // .valid, Valid data port of Avalon Streaming Source Interface; high when output data is valid
output wire out_startofpacket, // .startofpacket, Start of packet port of Avalon Streaming Source Interface; Indicates start of outgoing packet
output wire out_endofpacket, // .endofpacket, End of packet port of Avalon Streaming Source Interface; Indicates end of outgoing packet
output wire [170:0] out_data, // .data, Output Data port of Avalon Streaming Source Interface
output wire [1:0] out_channel // .channel, Channel output port of Avalon Streaming Source Interface
);
qsys_top_altera_avalon_st_pipeline_stage_1930_oiupeiq #(
.SYMBOLS_PER_BEAT (SYMBOLS_PER_BEAT),
.BITS_PER_SYMBOL (BITS_PER_SYMBOL),
.USE_PACKETS (USE_PACKETS),
.USE_EMPTY (USE_EMPTY),
.EMPTY_WIDTH (EMPTY_WIDTH),
.CHANNEL_WIDTH (CHANNEL_WIDTH),
.PACKET_WIDTH (PACKET_WIDTH),
.ERROR_WIDTH (ERROR_WIDTH),
.PIPELINE_READY (PIPELINE_READY),
.SYNC_RESET (SYNC_RESET)
) my_altera_avalon_st_pipeline_stage (
.clk (clk), // input, width = 1, cr0.clk
.reset (reset), // input, width = 1, cr0_reset.reset
.in_ready (in_ready), // output, width = 1, sink0.ready
.in_valid (in_valid), // input, width = 1, .valid
.in_startofpacket (in_startofpacket), // input, width = 1, .startofpacket
.in_endofpacket (in_endofpacket), // input, width = 1, .endofpacket
.in_data (in_data), // input, width = 171, .data
.in_channel (in_channel), // input, width = 2, .channel
.out_ready (out_ready), // input, width = 1, source0.ready
.out_valid (out_valid), // output, width = 1, .valid
.out_startofpacket (out_startofpacket), // output, width = 1, .startofpacket
.out_endofpacket (out_endofpacket), // output, width = 1, .endofpacket
.out_data (out_data), // output, width = 171, .data
.out_channel (out_channel), // output, width = 2, .channel
.in_empty (1'b0), // (terminated),
.out_empty (), // (terminated),
.out_error (), // (terminated),
.in_error (1'b0) // (terminated),
);
endmodule
@@ -0,0 +1,278 @@
// (C) 2001-2026 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 from 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 IP 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/26.1/ip/iconnect/merlin/altera_merlin_burst_adapter/new_source/altera_default_burst_converter.sv#1 $
// $Revision: #1 $
// $Date: 2026/02/05 $
// --------------------------------------------
// Default Burst Converter
// Notes:
// 1) If burst type FIXED and slave is AXI,
// passthrough the transaction.
// 2) Else, converts burst into non-bursting
// transactions (length of 1).
// --------------------------------------------
`timescale 1 ns / 1 ns
module altera_default_burst_converter
#(
parameter PKT_BURST_TYPE_W = 2,
parameter PKT_BURSTWRAP_W = 5,
parameter PKT_ADDR_W = 12,
parameter PKT_BURST_SIZE_W = 3,
parameter IS_AXI_SLAVE = 0,
parameter LEN_W = 2,
parameter SYNC_RESET = 0
)
(
input clk,
input reset,
input enable,
input [PKT_BURST_TYPE_W - 1 : 0] in_bursttype,
input [PKT_BURSTWRAP_W - 1 : 0] in_burstwrap_reg,
input [PKT_BURSTWRAP_W - 1 : 0] in_burstwrap_value,
input [PKT_ADDR_W - 1 : 0] in_addr,
input [PKT_ADDR_W - 1 : 0] in_addr_reg,
input [LEN_W - 1 : 0] in_len,
input [PKT_BURST_SIZE_W - 1 : 0] in_size_value,
input in_is_write,
output reg [PKT_ADDR_W - 1 : 0] out_addr,
output reg [LEN_W - 1 : 0] out_len,
output reg new_burst
);
// ---------------------------------------------------
// AXI Burst Type Encoding
// ---------------------------------------------------
typedef enum bit [1:0]
{
FIXED = 2'b00,
INCR = 2'b01,
WRAP = 2'b10,
RESERVED = 2'b11
} AxiBurstType;
// -------------------------------------------
// Internal Signals
// -------------------------------------------
wire [LEN_W - 1 : 0] unit_len = {{LEN_W - 1 {1'b0}}, 1'b1};
reg [LEN_W - 1 : 0] next_len;
reg [LEN_W - 1 : 0] remaining_len;
reg [PKT_ADDR_W - 1 : 0] next_incr_addr;
reg [PKT_ADDR_W - 1 : 0] incr_wrapped_addr;
reg [PKT_ADDR_W - 1 : 0] extended_burstwrap_value;
reg [PKT_ADDR_W - 1 : 0] addr_incr_variable_size_value;
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= reset;
end
end
endgenerate
// -------------------------------------------
// Byte Count Converter
// -------------------------------------------
// Avalon Slave: Read/Write, the out_len is always 1 (unit_len).
// AXI Slave: Read/Write, the out_len is always the in_len (pass through) of a given cycle.
// If bursttype RESERVED, out_len is always 1 (unit_len).
generate if (IS_AXI_SLAVE == 1)
begin : axi_slave_out_len
always_ff @(posedge clk) begin
if (enable) begin
out_len <= (in_bursttype == FIXED) ? in_len : unit_len;
end
end
//if (SYNC_RESET == 0 ) begin : async_rst1
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_len <= {LEN_W{1'b0}};
// end
// else if (enable) begin
// out_len <= (in_bursttype == FIXED) ? in_len : unit_len;
// end
// end
//end // async_rst1
//else begin // sync_rst1
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_len <= {LEN_W{1'b0}};
// end
// else if (enable) begin
// out_len <= (in_bursttype == FIXED) ? in_len : unit_len;
// end
// end
//end // sync_rst1
end
else // IS_AXI_SLAVE == 0
begin : non_axi_slave_out_len
always_comb begin
out_len = unit_len;
end
end
endgenerate
always_comb begin : proc_extend_burstwrap
extended_burstwrap_value = {{(PKT_ADDR_W - PKT_BURSTWRAP_W){in_burstwrap_reg[PKT_BURSTWRAP_W - 1]}}, in_burstwrap_value};
addr_incr_variable_size_value = {{(PKT_ADDR_W - 1){1'b0}}, 1'b1} << in_size_value;
end
// -------------------------------------------
// Address Converter
// -------------------------------------------
// Write: out_addr = in_addr at every cycle (pass through).
// Read: out_addr = in_addr at every new_burst. Subsequent addresses calculated by converter.
always_ff @(posedge clk) begin
if (enable) begin
next_incr_addr <= next_incr_addr + addr_incr_variable_size_value;
if (new_burst) begin
next_incr_addr <= in_addr + addr_incr_variable_size_value;
end
out_addr <= incr_wrapped_addr;
end
end
//generate
//if (SYNC_RESET == 0) begin : async_rst2
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_incr_addr <= {PKT_ADDR_W{1'b0}};
// out_addr <= {PKT_ADDR_W{1'b0}};
// end
// else if (enable) begin
// next_incr_addr <= next_incr_addr + addr_incr_variable_size_value;
// if (new_burst) begin
// next_incr_addr <= in_addr + addr_incr_variable_size_value;
// end
// out_addr <= incr_wrapped_addr;
// end
// end
// end // async_rst2
// else begin // sync_rst2
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_incr_addr <= {PKT_ADDR_W{1'b0}};
// out_addr <= {PKT_ADDR_W{1'b0}};
// end
// else if (enable) begin
// next_incr_addr <= next_incr_addr + addr_incr_variable_size_value;
// if (new_burst) begin
// next_incr_addr <= in_addr + addr_incr_variable_size_value;
// end
// out_addr <= incr_wrapped_addr;
// end
// end
// end // sync_rst2
//endgenerate
always_comb begin
incr_wrapped_addr = in_addr;
if (!new_burst) begin
// This formula calculates addresses of WRAP bursts and works perfectly fine for other burst types too.
incr_wrapped_addr = (in_addr_reg & ~extended_burstwrap_value) | (next_incr_addr & extended_burstwrap_value);
end
end
// -------------------------------------------
// Control Signals
// -------------------------------------------
// Determine the min_len.
// 1) FIXED read to AXI slave: One-time passthrough, therefore the min_len == in_len.
// 2) FIXED write to AXI slave: min_len == 1.
// 3) FIXED read/write to Avalon slave: min_len == 1.
// 4) RESERVED read/write to AXI/Avalon slave: min_len == 1.
wire [LEN_W - 1 : 0] min_len;
generate if (IS_AXI_SLAVE == 1)
begin : axi_slave_min_len
assign min_len = (!in_is_write && (in_bursttype == FIXED)) ? in_len : unit_len;
end
else // IS_AXI_SLAVE == 0
begin : non_axi_slave_min_len
assign min_len = unit_len;
end
endgenerate
// last_beat calculation.
wire last_beat = (remaining_len == min_len);
// next_len calculation.
always_comb begin
remaining_len = in_len;
if (!new_burst) remaining_len = next_len;
end
always_ff @(posedge clk) begin
if (enable) begin
next_len <= remaining_len - unit_len;
end
end
generate
if (SYNC_RESET == 0) begin : async_rst3
//always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_len <= 1'b0;
// end
// else if (enable) begin
// next_len <= remaining_len - unit_len;
// end
//end
// new_burst calculation.
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
new_burst <= 1'b1;
end
else if (enable) begin
new_burst <= last_beat;
end
end
end // async_rst3
else begin // sync_rst3
//always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_len <= 1'b0;
// end
// else if (enable) begin
// next_len <= remaining_len - unit_len;
// end
//end
// new_burst calculation.
always_ff @(posedge clk) begin
if (internal_sclr) begin
new_burst <= 1'b1;
end
else if (enable) begin
new_burst <= last_beat;
end
end
end // sync_rst3
endgenerate
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZnXzCebnCKJTsi823h62YzED9giUrsXJJm305Cxwn/ZRLE5PqwZtvf+8ZAVJE55kNVZaV60bWlN1N0XZR9KM1WwQkKYejedngoMHZ5SvtJeJU4qT4/oQOvKek5HLy5M6ATeo0EfJB3ak4qOC206cHdjo6jQaq4jVeRzd4W9l5Hk/MsscWd3wt993nAf88yhZUaJ1/mBpRC35cYTaXNnFY84PO+FW8JiMxDjLScLm/9k8wCnKRnF0Hs5P4VIY630mFMHoKoejOV1LqpqaU/cjYNnrlSYDmB49HKeYpESgUpAw/F+kYpWqck871iv0EzYP3Z3dhwLSf70SFr5f6Z0TDE3Gr4JfN9KPx6CcPDKeGzYK+fFSJSbCsCPgEl2xC4MI7ISbMJHOcc/V7ZbFLP6r5n8kZlPYOE9L8TJoc1Vcg8UxGcxzW9pE8AgMTFCoLGmA77bKOzo4BwadS0t585NPOjoR4cRPJfC3+2qNG4cdNvwrKBS2VUO7341urJcK/l9J0S9BxiN6U+1HjmDuBCgG09cqLR8+cnmDRKpiIky8laAqXEDKzhWqlD1ganoZi7z4DWtAwMN8P+YVycreBGZgwssabwyo2LmDpP+Uitsy15PbNMCdOJfMK8bkzkIMh2N67/N3Z4HkFKETIcGtbr7Le7scupVRRszgiRj7sZNNULEGcrKiPlFzfAsmzIiqX9N0klWvUcO95LliNP8e+CZZdzfGcKxZVSLsedLYpqEWGn8MBt0cTrRUPAriDk6XjdkPIN9frlNlJ/d6l4jzxLrmAnT"
`endif
@@ -0,0 +1,520 @@
// (C) 2001-2026 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 from 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 IP 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/26.1/ip/iconnect/merlin/altera_merlin_burst_adapter/new_source/altera_incr_burst_converter.sv#1 $
// $Revision: #1 $
// $Date: 2026/02/05 $
// ----------------------------------------------------------
// This component is used for INCR Avalon slave
// (slave which only supports INCR) or AXI slave.
// It converts burst length of input packet
// to match slave burst.
// ----------------------------------------------------------
`timescale 1 ns / 1 ns
module altera_incr_burst_converter
#(
parameter
// ----------------------------------------
// Burst length Parameters
// (real burst length value, not bytecount)
// ----------------------------------------
MAX_IN_LEN = 16,
MAX_OUT_LEN = 4,
NUM_SYMBOLS = 4,
ADDR_WIDTH = 12,
BNDRY_WIDTH = 12,
BURSTSIZE_WIDTH = 3,
IN_NARROW_SIZE = 0,
PURELY_INCR_AVL_SYS = 0,
SYNC_RESET = 0,
// ------------------
// Derived Parameters
// ------------------
LEN_WIDTH = log2ceil(MAX_IN_LEN) + 1,
OUT_LEN_WIDTH = log2ceil(MAX_OUT_LEN) + 1,
LOG2_NUMSYMBOLS = log2ceil(NUM_SYMBOLS)
)
(
input clk,
input reset,
input enable,
input is_write,
input [LEN_WIDTH - 1 : 0] in_len,
input in_sop,
input [ADDR_WIDTH - 1 : 0] in_addr,
input [ADDR_WIDTH - 1 : 0] in_addr_reg,
input [BNDRY_WIDTH - 1 : 0] in_burstwrap_reg,
input [BURSTSIZE_WIDTH - 1 : 0] in_size_t,
input [BURSTSIZE_WIDTH - 1 : 0] in_size_reg,
// converted output length
// out_len : compressed burst, read
// uncompressed_len: uncompressed, write
output reg [LEN_WIDTH - 1 : 0] out_len,
output reg [LEN_WIDTH - 1 : 0] uncompr_out_len,
// Compressed address output
output reg [ADDR_WIDTH - 1 : 0] out_addr,
output reg new_burst_export
);
// ----------------------------------------
// Signals for wrapping support
// ----------------------------------------
reg [LEN_WIDTH - 1 : 0] remaining_len;
reg [LEN_WIDTH - 1 : 0] next_out_len;
reg [LEN_WIDTH - 1 : 0] next_rem_len;
reg [LEN_WIDTH - 1 : 0] uncompr_remaining_len;
reg [LEN_WIDTH - 1 : 0] next_uncompr_remaining_len;
reg [LEN_WIDTH - 1 : 0] next_uncompr_rem_len;
reg new_burst;
reg uncompr_sub_burst;
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= reset;
end
end
endgenerate
// Avoid QIS warning
wire [OUT_LEN_WIDTH - 1 : 0] max_out_length;
assign max_out_length = MAX_OUT_LEN[OUT_LEN_WIDTH - 1 : 0];
always_comb begin
new_burst_export = new_burst;
end
// -------------------------------------------
// length remaining calculation
// -------------------------------------------
always_comb begin : proc_uncompressed_remaining_len
if ((in_len <= max_out_length) && is_write) begin
uncompr_remaining_len = in_len;
end else begin
uncompr_remaining_len = max_out_length;
end
if (uncompr_sub_burst)
uncompr_remaining_len = next_uncompr_rem_len;
end
always_ff @(posedge clk) begin
if (enable) begin
next_uncompr_rem_len <= uncompr_remaining_len - 1'b1; // in term of length, it just reduces 1
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst1
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_uncompr_rem_len <= 0;
// end
// else if (enable) begin
// next_uncompr_rem_len <= uncompr_remaining_len - 1'b1; // in term of length, it just reduces 1
// end
// end
// end // async_rst1
// else begin // sync_rst1
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_uncompr_rem_len <= 0;
// end
// else if (enable) begin
// next_uncompr_rem_len <= uncompr_remaining_len - 1'b1; // in term of length, it just reduces 1
// end
// end
// end // sync_rst1
//endgenerate
always_comb begin : proc_compressed_remaining_len
remaining_len = in_len;
if (!new_burst)
remaining_len = next_rem_len;
end
always_ff@(posedge clk) begin : proc_next_uncompressed_remaining_len
if (enable) begin
if (in_sop) begin
next_uncompr_remaining_len <= in_len - max_out_length;
end
else if (!uncompr_sub_burst)
next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst2
// always_ff@(posedge clk or posedge reset) begin : proc_next_uncompressed_remaining_len
// if(reset) begin
// next_uncompr_remaining_len <= '0;
// end
// else if (enable) begin
// if (in_sop) begin
// next_uncompr_remaining_len <= in_len - max_out_length;
// end
// else if (!uncompr_sub_burst)
// next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
// end
// end
// end // async_rst2
// else begin // sync_rst2
// always_ff@(posedge clk ) begin : proc_next_uncompressed_remaining_len
// if(internal_sclr) begin
// next_uncompr_remaining_len <= '0;
// end
// else if (enable) begin
// if (in_sop) begin
// next_uncompr_remaining_len <= in_len - max_out_length;
// end
// else if (!uncompr_sub_burst)
// next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
// end
// end
// end // sync_rst2
//endgenerate
always_comb begin
next_out_len = max_out_length;
if (remaining_len < max_out_length) begin
next_out_len = remaining_len;
end
end // always_comb
// --------------------------------------------------
// Length remaining calculation : compressed
// --------------------------------------------------
// length remaining for compressed transaction
// for wrap, need special handling for first out length
always_ff @(posedge clk) begin
if (enable) begin
if (new_burst)
next_rem_len <= in_len - max_out_length;
else
next_rem_len <= next_rem_len - max_out_length;
end
end
generate
if (SYNC_RESET == 0) begin: async_rst3
//always_ff @(posedge clk, posedge reset) begin
// if (reset)
// next_rem_len <= 0;
// else if (enable) begin
// if (new_burst)
// next_rem_len <= in_len - max_out_length;
// else
// next_rem_len <= next_rem_len - max_out_length;
// end
//end
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
uncompr_sub_burst <= 0;
end
else if (enable && is_write) begin
uncompr_sub_burst <= (uncompr_remaining_len > 1'b1);
end
end
end // async_rst3
else begin // sync_rst3
//always_ff @(posedge clk) begin
// if (internal_sclr)
// next_rem_len <= 0;
// else if (enable) begin
// if (new_burst)
// next_rem_len <= in_len - max_out_length;
// else
// next_rem_len <= next_rem_len - max_out_length;
// end
//end
always_ff @(posedge clk) begin
if (internal_sclr) begin
uncompr_sub_burst <= 0;
end
else if (enable && is_write) begin
uncompr_sub_burst <= (uncompr_remaining_len > 1'b1);
end
end
end // sync_rst3
endgenerate
// --------------------------------------------------
// Control signals
// --------------------------------------------------
wire end_compressed_sub_burst;
assign end_compressed_sub_burst = (remaining_len == next_out_len);
// new_burst:
// the converter takes in_len for new calculation
generate
if (SYNC_RESET == 0) begin : async_rst4
always_ff @(posedge clk, posedge reset) begin
if (reset)
new_burst <= 1;
else if (enable)
new_burst <= end_compressed_sub_burst;
end
end // async_rst4
else begin // sync_rst4
always_ff @(posedge clk) begin
if (internal_sclr)
new_burst <= 1;
else if (enable)
new_burst <= end_compressed_sub_burst;
end
end
endgenerate
// --------------------------------------------------
// Output length
// --------------------------------------------------
// register out_len for compressed trans
always_ff @(posedge clk) begin
if (enable) begin
out_len <= next_out_len;
end
end
// register uncompr_out_len for uncompressed trans
always_ff @(posedge clk) begin
if (enable) begin
uncompr_out_len <= uncompr_remaining_len;
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst5
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_len <= 0;
// end
// else if (enable) begin
// out_len <= next_out_len;
// end
// end
// // register uncompr_out_len for uncompressed trans
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// uncompr_out_len <= '0;
// end
// else if (enable) begin
// uncompr_out_len <= uncompr_remaining_len;
// end
// end
//end // async_rst5
//else begin // sync_rst5
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_len <= 0;
// end
// else if (enable) begin
// out_len <= next_out_len;
// end
// end
// // register uncompr_out_len for uncompressed trans
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// uncompr_out_len <= '0;
// end
// else if (enable) begin
// uncompr_out_len <= uncompr_remaining_len;
// end
// end
//end //sync_rst5
//endgenerate
// --------------------------------------------------
// Address Calculation
// --------------------------------------------------
reg [ADDR_WIDTH - 1 : 0] addr_incr_sel;
reg [ADDR_WIDTH - 1 : 0] addr_incr_sel_reg;
reg [ADDR_WIDTH - 1 : 0] addr_incr_full_size;
localparam [ADDR_WIDTH - 1 : 0] ADDR_INCR = MAX_OUT_LEN << LOG2_NUMSYMBOLS;
generate
if (IN_NARROW_SIZE) begin : narrow_addr_incr
reg [ADDR_WIDTH - 1 : 0] addr_incr_variable_size;
reg [ADDR_WIDTH - 1 : 0] addr_incr_variable_size_reg;
assign addr_incr_variable_size = MAX_OUT_LEN << in_size_t;
assign addr_incr_variable_size_reg = MAX_OUT_LEN << in_size_reg;
assign addr_incr_sel = addr_incr_variable_size;
assign addr_incr_sel_reg = addr_incr_variable_size_reg;
end
else begin : full_addr_incr
assign addr_incr_full_size = ADDR_INCR[ADDR_WIDTH - 1 : 0];
assign addr_incr_sel = addr_incr_full_size;
assign addr_incr_sel_reg = addr_incr_full_size;
end
endgenerate
reg [ADDR_WIDTH - 1 : 0] next_out_addr;
reg [ADDR_WIDTH - 1 : 0] incremented_addr;
always_ff @(posedge clk) begin
if (enable) begin
out_addr <= (next_out_addr);
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst6
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_addr <= '0;
// end else begin
// if (enable) begin
// out_addr <= (next_out_addr);
// end
// end
// end
// end // async_rst6
// else begin // sync_rst6
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_addr <= '0;
// end else begin
// if (enable) begin
// out_addr <= (next_out_addr);
// end
// end
// end
// end // sync_rst6
// endgenerate
generate
if (!PURELY_INCR_AVL_SYS) begin : incremented_addr_normal
always_ff @(posedge clk) begin
if (enable) begin
if (new_burst) begin
incremented_addr <= (next_out_addr + addr_incr_sel);
end
else begin
incremented_addr <= (next_out_addr + addr_incr_sel_reg);
end
end
end // always_ff @
//if (SYNC_RESET == 0) begin : async_rst7
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// incremented_addr <= '0;
// end
// else if (enable) begin
// incremented_addr <= (next_out_addr + addr_incr_sel_reg);
// if (new_burst) begin
// incremented_addr <= (next_out_addr + addr_incr_sel);
// end
// end
// end // always_ff @
//end // async_rst7
//else begin // sync_rst7
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// incremented_addr <= '0;
// end
// else if (enable) begin
// incremented_addr <= (next_out_addr + addr_incr_sel_reg);
// if (new_burst) begin
// incremented_addr <= (next_out_addr + addr_incr_sel);
// end
// end
// end // always_ff @
//end // sync_rst7
always_comb begin
next_out_addr = in_addr;
if (!new_burst) begin
next_out_addr = incremented_addr;
end
end
end
else begin : incremented_addr_pure_av
always_ff @(posedge clk) begin
if (enable) begin
incremented_addr <= (next_out_addr + addr_incr_sel_reg);
end
end // always_ff @
//if (SYNC_RESET == 0) begin : async_rst8
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// incremented_addr <= '0;
// end
// else if (enable) begin
// incremented_addr <= (next_out_addr + addr_incr_sel_reg);
// end
// end // always_ff @
//end // async_rst8
//else begin // sync_rst8
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// incremented_addr <= '0;
// end
// else if (enable) begin
// incremented_addr <= (next_out_addr + addr_incr_sel_reg);
// end
// end // always_ff @
// end // sync_rst8
always_comb begin
next_out_addr = in_addr;
if (!new_burst) begin
next_out_addr = (incremented_addr);
end
end
end
endgenerate
// --------------------------------------------------
// Calculates the log2ceil of the input value
// --------------------------------------------------
function integer log2ceil;
input integer val;
reg[31:0] i;
begin
i = 1;
log2ceil = 0;
while (i < val) begin
log2ceil = log2ceil + 1;
i = i[30:0] << 1;
end
end
endfunction
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZm2VnW9Jup+rO8tHn46ia+m1jd1lvf4qalDbWMpZ7/iR078F3NbXmSfszSWG0PYb1O/+IcoZgGEBa4thPbK141luDnU00je40S0l+dVi8sQRSkZ06QX7VOV1HZ58TwdhajcQDrYTBrJ/wnghIvibweYzsQp21UeRH1tHdQb9EX/90LIxErNs9qZn6FdE/wU7Nnk0BApTSHa5j7Oq6whWnvIJLoY+NDfNdmguQ5c5E6FNiZBIhwP/gOXHb/Xm2fDPcMvXcyokY7FuDYoM8BdoUJ+OVZhbg6kE3dGqlFzZ60/+I5AYaHj1YtiTy6zGO1WlQnC9Sov4dHl/nkN231hsVmVVehUnm0X9f6djXsXUCx2V4JBRqjfGugv+XBeZ7HMoK6LH9u4KSTlqLlNrvhPX1VXe6UjwtOzHxYGUWqvESIeNAxWo/4NsdiISuU7Ut75o/3SMGjSlAM7UYSVvfIKi5vhCIKKXWh8sv0pKKrscZmZZ/OnnKio2r2xi88/64nRWpeQLYbzJvOmzzD5662ckE9n2faDKveVDFd+hpDfzkxyJ1LcqlVbHGqIMMAyPaTibmi0MV3Rd4tFFycrgcfYSW2I2CZTl8Rl/mstykAJ+vOi233Cy2RN1EviSi9EtnimDziOtUfW0sHScrdN1sEWY0xL2HM3oZBGMXvTOYwRGqobo4r/v6rfvRDKjzYBDzylQrvPRTibwXUKTDizbO7CXOL30RYfG/EAFhOqWFZBz89zBGyL8kCGAD5mh8/7pcdM1Y52JOHLbDLceUAQRV+5n0po"
`endif
@@ -0,0 +1,305 @@
// (C) 2001-2026 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 from 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 IP 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/main/ip/merlin/altera_merlin_axi_master_ni/address_alignment.sv#3 $
// $Revision: #3 $
// $Date: 2012/07/11 $
//-----------------------------------------
// Address alignment:
// This component will aglin input address with input size
// Support address increment with butst type and burstwrap value
//-----------------------------------------
`timescale 1 ns / 1 ns
module altera_merlin_address_alignment
#(
parameter
ADDR_W = 12,
BURSTWRAP_W = 12,
TYPE_W = 2,
SIZE_W = 3,
INCREMENT_ADDRESS = 1,
NUMSYMBOLS = 8,
SELECT_BITS = log2(NUMSYMBOLS),
IN_DATA_W = ADDR_W + (BURSTWRAP_W-1) + TYPE_W + SIZE_W,
OUT_DATA_W = ADDR_W + SELECT_BITS,
SYNC_RESET = 0
)
(
input clk,
input reset,
input [IN_DATA_W-1:0] in_data, // in_data = {wrap_boundary, address, type, size}
input in_valid,
//output in_ready,
input in_sop,
input in_eop,
output reg [OUT_DATA_W-1:0] out_data,
input out_ready
//output out_valid
);
typedef enum bit [1:0]
{
FIXED = 2'b00,
INCR = 2'b01,
WRAP = 2'b10,
RESERVED = 2'b11
} AxiBurstType;
//----------------------------------------------------
// AXSIZE decoding
//
// Turns the axsize value into the actual number of bytes
// being transferred.
// ---------------------------------------------------
function reg[9:0] bytes_in_transfer;
input [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
//--------------------------------------
// Burst type decode
//--------------------------------------
AxiBurstType write_burst_type;
function AxiBurstType burst_type_decode
(
input [1:0] axburst
);
AxiBurstType burst_type;
begin
case (axburst)
2'b00 : burst_type = FIXED;
2'b01 : burst_type = INCR;
2'b10 : burst_type = WRAP;
2'b11 : burst_type = RESERVED;
default : burst_type = INCR;
endcase
return burst_type;
end
endfunction
//----------------------------------------------------
// Ubiquitous, familiar log2 function
//----------------------------------------------------
function integer log2;
input integer value;
value = value - 1;
for(log2 = 0; value > 0; log2 = log2 + 1)
value = value >> 1;
endfunction
//------------------------------------------------------------------------
// This component will read address and size and check
// if this is aligned or not. If not then it will align this address to the size
// of the transfer:
// Check alignment:
// - With data width, can define maximun how many lower bits of address to indicate this
// address align to the size
// - Ex: 32 bits data => size can be: 1, 2, 4 bytes
// For 4 bytes: when 2 lower bits of address equal 0, this is aligned address
// addr=00|00| (0), 01|00| (4) => align to size of 4 bytes
// addr=00|01| (1) => start addr at 1, is not aligned to size 4 byte
// For 2 bytes: use last one bit to indicate algined or not
// addr=000|0| (0), 001|0| (2) => align to size of 2 bytes
// addr=000|1| (1), 001|1| (3) => not align to 2 bytes
// As size runtime change, creat mask and change accordingly to size, can detect address alignment
// and to align to size, apply this mask with zero to the address.
//-------------------------------------------------------------------------
// THe function return a vector which has width [(SELECT_BITS * 2) -1 : 0]
// in which the first part contains the mask to check if this address aligned or not
// second part contains the mast to mask address to align to size
function reg[(SELECT_BITS*2)-1 : 0] mask_select_and_align_address;
input [ADDR_W-1:0] address;
input [SIZE_W-1:0] size; // size is in AXI coding: 001 -> 2 bytes
integer i;
reg [SELECT_BITS-1:0] mask_address;
reg [SELECT_BITS-1:0] check_unaligned; // any bits =1 -> unalgined (except size = 0; 1 byte)
mask_address = '1;
check_unaligned = '0;
for(i = 0; i < SELECT_BITS ; i = i + 1) begin
if (i < size) begin
check_unaligned[i] = address[i];
mask_address[i] = 1'b0;
end
end
mask_select_and_align_address = {check_unaligned,mask_address};
endfunction
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= ~reset;
end
end
endgenerate
reg [ADDR_W-1 : 0] in_address;
reg [ADDR_W-1 : 0] first_address_aligned;
reg [SIZE_W-1 : 0] in_size;
reg [(SELECT_BITS*2)-1 : 0] output_masks;
// Extract information from input data
assign in_address = in_data[SIZE_W+ADDR_W-1 : SIZE_W];
assign in_size = in_data[SIZE_W-1 : 0];
// Generate the masks
always_comb
begin
output_masks = mask_select_and_align_address(in_address, in_size);
end
// Align address if needed
generate
// SELECT_BITS == 1: input packet has 1 NUMSYMBOLS (1 bytes), it is aligned
if (SELECT_BITS == 0)
assign first_address_aligned = in_address;
else begin
// SELECT_BITS ==1 :input packet 2 bytes (2 SYMBOLS)
wire [SELECT_BITS-1 : 0] aligned_address_bits;
if (SELECT_BITS == 1)
assign aligned_address_bits = in_address[0] & output_masks[0];
else
assign aligned_address_bits = in_address[SELECT_BITS-1:0] & output_masks[SELECT_BITS-1:0];
assign first_address_aligned = {in_address[ADDR_W-1 : SELECT_BITS], aligned_address_bits};
end
endgenerate
// Increment address base on size, first address keep the same
generate
if (INCREMENT_ADDRESS)
begin
reg [ADDR_W-1 : 0] increment_address;
reg [ADDR_W-1 : 0] out_aligned_address_burst;
reg [ADDR_W-1 : 0] address_burst;
reg [ADDR_W-1 : 0] base_address;
reg [9 : 0] number_bytes_transfer;
reg [ADDR_W-1 : 0] burstwrap_mask;
reg [ADDR_W-1 : 0] burst_address_high;
reg [ADDR_W-1 : 0] burst_address_low;
reg [BURSTWRAP_W-2 :0] in_burstwrap_boundary;
reg [TYPE_W-1 : 0] in_type;
//------------------------------------------------
// Use the extended burstwrap value to split the high (constant) and
// low (changing) part of the address
//-----------------------------------------------
assign in_type = in_data[SIZE_W+ADDR_W+TYPE_W-1 : SIZE_W+ADDR_W];
assign in_burstwrap_boundary = in_data[IN_DATA_W-1 : ADDR_W+TYPE_W+SIZE_W];
assign burstwrap_mask = {{(ADDR_W - BURSTWRAP_W){1'b0}}, in_burstwrap_boundary};
assign burst_address_high = out_aligned_address_burst & ~burstwrap_mask;
assign burst_address_low = out_aligned_address_burst;
assign number_bytes_transfer = bytes_in_transfer(in_size);
assign write_burst_type = burst_type_decode(in_type);
always @*
begin
if (in_sop)
begin
out_aligned_address_burst = in_address;
base_address = first_address_aligned;
end
else
begin
out_aligned_address_burst = address_burst;
base_address = out_aligned_address_burst;
end
case (write_burst_type)
INCR:
increment_address = base_address + number_bytes_transfer;
WRAP:
increment_address = ((burst_address_low + number_bytes_transfer) & burstwrap_mask) | burst_address_high;
FIXED:
increment_address = out_aligned_address_burst;
default:
increment_address = base_address + number_bytes_transfer;
endcase // case (write_burst_type)
end // always @ *
if (SYNC_RESET == 0) begin : async_rst0
always_ff @(posedge clk, negedge reset)
begin
if (!reset)
begin
address_burst <= '0;
end
else
begin
if (in_valid & out_ready)
address_burst <= increment_address;
end
end
end : async_rst0
else begin : sync_rst0
always_ff @(posedge clk)
begin
if (internal_sclr)
begin
address_burst <= '0;
end
else
begin
if (in_valid & out_ready)
address_burst <= increment_address;
end
end
end : sync_rst0
// send data to output with 2 part: [mask_t0_algin][address_aligned_increment]
// corner case when SELECT_BITS==0 - total bits in
// [SELECTS_BITS-1:0] ==> 1-:0 ==> 2 bits in total
// leads to warning
if (SELECT_BITS==0)
assign out_data = out_aligned_address_burst;
else
assign out_data = {output_masks[SELECT_BITS-1 : 0], out_aligned_address_burst};
end // if (INCREMENT_ADDRESS)
else
begin
// corner case when SELECT_BITS==0 - total bits in
// [SELECTS_BITS-1:0] ==> 1-:0 ==> 2 bits in total
// leads to warning
if (SELECT_BITS==0)
assign out_data = first_address_aligned;
else
assign out_data = {output_masks[SELECT_BITS-1 : 0], first_address_aligned};
end // else: !if(INCREMENT_ADDRESS)
endgenerate
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZnuSxX8yXxnIFVWsgCk75Z0P+dtbDvmJdtQl1WjW4yFuhoOU6T348GM/xUHtJ4nzM+Ie8UNgnT16AXfoOSoZ6aw4EqtmutAt1g0WrS8Zo7lntdL4Ed4jMhrdzQ2wGXcukpdBXSOlxyVkCs8O5Bx5bsJHA8kY1r+dEjpFU6yRXbht/crFehVXoHCjTTZnCo6ONciQai4cPqisPuj4rwOI0P18Yry6OKgj6AYn8jpBhuXzb8sDJ3t4lulV43YetVoYKIdiLdg9MNtOudp0cdO7C9wiNkMhIPLI2VLiAgdsxlTZo0H7/klMzcS7oMYhgKBYj3rMGfIF8GIfjTv7DXR06ED3LZScux5eFxq7qC9RRhgCFd2O/5OwjkezW2Fe1fos97+/4c0SVIufbIeAiMRsYmglnEcMCPwWnhbxi/B4Q/YpYAH96gY/+ITpxiLlp7H+Wot7TKsR10cNB8FfVYrKfDgFm3aAGBtmVsUAz3X31S6DJdo/eXRPthu3tfuBI4BAB2tQptyaBZIqDMWE/TeUinC41fvbEAe/N84+in0g3XgKSMRshfZ8yKNB5HICw0eV/rxJsVyCdWVsaafsz31CT1ij2Mvr1H7LbAUmPVt546kJCR7d/o6inwycxcb5G7r8r7du8eigB4sXm3QEMQTpHFX0PXZW0KnyL4Dml+CXK43oRj2wIP58dXUWPsi8nphSGr64d8Zt0FlS2NO2Y0jv3ecZkOIjZu+9pPoWGxFSdPY/fBYS18Q736mwIEkGiruEglqw3eKurFsVAnQNbb/cn/1"
`endif
@@ -0,0 +1,96 @@
// (C) 2001-2026 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 from 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 IP 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.
// (C) 2001-2012 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/main/ip/merlin/altera_merlin_burst_adapter/altera_merlin_burst_adapter.sv#68 $
// $Revision: #68 $
// $Date: 2014/01/23 $
`timescale 1 ns / 1 ns
// -------------------------------------------------------
// Adapter for uncompressed transactions only. This adapter will
// typically be used to adapt burst length for non-bursting
// wide to narrow Avalon links.
// -------------------------------------------------------
module altera_merlin_burst_adapter_uncompressed_only
#(
parameter
PKT_BYTE_CNT_H = 5,
PKT_BYTE_CNT_L = 0,
PKT_BYTEEN_H = 83,
PKT_BYTEEN_L = 80,
ST_DATA_W = 84,
ST_CHANNEL_W = 8
)
(
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
);
localparam
PKT_BYTE_CNT_W = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1,
NUM_SYMBOLS = PKT_BYTEEN_H - PKT_BYTEEN_L + 1;
wire [PKT_BYTE_CNT_W - 1 : 0] num_symbols_sig = NUM_SYMBOLS[PKT_BYTE_CNT_W - 1 : 0];
always_comb begin : source0_data_assignments
source0_valid = sink0_valid;
source0_channel = sink0_channel;
source0_startofpacket = sink0_startofpacket;
source0_endofpacket = sink0_endofpacket;
source0_data = sink0_data;
source0_data[PKT_BYTE_CNT_H : PKT_BYTE_CNT_L] = num_symbols_sig;
sink0_ready = source0_ready;
end
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZlEl7U1mwDa2foPMdSqYqEvxrVPv0jMzxA0aRf5GvKemQQYiAUmoPZ/yty49qVq2u4nCWeBwiIOIWm7gDC9G7PUqb6tQOwrlINch7TSLyDBSTQRE9hXc7SldcwRHZbphJdXk8dLtmihOMDJFCjqPdl3yLIyPr7YL6350GrMmyAi0VBnzeb3PXYeJ774WH1+ABTda662GekklRXGy8DtIgPk0IIg3Oj1dwRb3pFTN66nlIPiZBgL8gjO0CYauPX/q9nMQFGeoQZr4+5e98MGAqbEcnhgooJzrOeQs2tRxgUiChvubqPONnP1A1YFtubOn7CcIC2RelzTbXvuG7xBL8BFrgyCRg/DB4902JDspTPYHKTGnATpyW9IaQ1niNwNhdHAEqiIUKBD/YZXcjnXVgHmwCUait0N//YwiEJonwrRzUsNWzXI1Hqd95q5Iyv88LJIqRopX6GB7QDDG42Z8rlNeHcFQnyJKEV5BhNCL8p3A8ygXqZ6pjUDwYOR+Dgarpg9ij6TIXQQHiiEozYHxBY0fcHtNb8FfenfODkF3XaHFzJciEYDrjHK2q3Ns7fTAp+HkmKgxb/S/s3qrHnpl3GVY+nokliANaXmDBgv4PGyFDfOm5ZifW3H7XSXvHNPSnpKxGuEoZt2v0zN2gZIcCaS5smLpTK+Lh0uks2gCvA/v1P41pbHzy/7CM/JZiP8V8q0zQ0ELX/oWMYwC/t43xkpbirj8nuULPIQPAupetsXyCnaz2p2/DdsSsbGj3kyXN8JLoZV990Dl5M4UL/HzKhw"
`endif
@@ -0,0 +1,545 @@
// (C) 2001-2026 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 from 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 IP 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/26.1/ip/iconnect/merlin/altera_merlin_burst_adapter/new_source/altera_wrap_burst_converter.sv#1 $
// $Revision: #1 $
// $Date: 2026/02/05 $
// ------------------------------------------------------
// This component is specially for Wrapping Avalon slave.
// It converts burst length of input packet
// to match slave burst.
// ------------------------------------------------------
`timescale 1 ns / 1 ns
module altera_wrap_burst_converter
#(
parameter
// ----------------------------------------
// Burst length Parameters
// (real burst length value, not bytecount)
// ----------------------------------------
MAX_IN_LEN = 16,
MAX_OUT_LEN = 4,
ADDR_WIDTH = 12,
BNDRY_WIDTH = 12,
NUM_SYMBOLS = 4,
AXI_SLAVE = 0,
OPTIMIZE_WRITE_BURST = 0,
SYNC_RESET = 0,
// ------------------
// Derived Parameters
// ------------------
LEN_WIDTH = log2ceil(MAX_IN_LEN) + 1,
OUT_LEN_WIDTH = log2ceil(MAX_OUT_LEN) + 1,
LOG2_NUMSYMBOLS = log2ceil(NUM_SYMBOLS)
)
(
input clk,
input reset,
input enable_write,
input enable_read,
input [LEN_WIDTH - 1 : 0] in_len,
input [LEN_WIDTH - 1 : 0] first_len,
input in_sop,
input [ADDR_WIDTH - 1 : 0] in_addr,
input [ADDR_WIDTH - 1 : 0] in_addr_reg,
input [BNDRY_WIDTH - 1 : 0] in_boundary,
input [BNDRY_WIDTH - 1 : 0] in_burstwrap,
input [BNDRY_WIDTH - 1 : 0] in_burstwrap_reg,
// converted output length
// out_len : compressed burst, read
// uncompressed_len: uncompressed, write
output reg [LEN_WIDTH - 1 : 0] out_len,
output reg [LEN_WIDTH - 1 : 0] uncompr_out_len,
// Compressed address output
output reg [ADDR_WIDTH - 1 : 0] out_addr,
output reg new_burst_export
);
// ------------------------------
// Local parameters
// ------------------------------
localparam
OUT_BOUNDARY = MAX_OUT_LEN * NUM_SYMBOLS,
ADDR_SEL = log2ceil(OUT_BOUNDARY);
// ----------------------------------------
// Signals for wrapping support
// ----------------------------------------
reg [LEN_WIDTH - 1 : 0] remaining_len;
reg [LEN_WIDTH - 1 : 0] next_out_len;
reg [LEN_WIDTH - 1 : 0] next_rem_len;
reg [LEN_WIDTH - 1 : 0] uncompr_remaining_len;
reg new_burst;
reg uncompr_sub_burst;
reg [LEN_WIDTH - 1 : 0] next_uncompr_out_len;
reg [LEN_WIDTH - 1 : 0] next_uncompr_sub_len;
// Avoid QIS warning
wire [OUT_LEN_WIDTH - 1 : 0] max_out_length;
assign max_out_length = MAX_OUT_LEN[OUT_LEN_WIDTH - 1 : 0];
// ----------------------------------------
// Calculate aligned length for WRAP burst
// ----------------------------------------
reg [ADDR_WIDTH - 1 : 0] extended_burstwrap;
reg [ADDR_WIDTH - 1 : 0] extended_burstwrap_reg;
always_comb begin
extended_burstwrap = {{(ADDR_WIDTH - BNDRY_WIDTH) {in_burstwrap[BNDRY_WIDTH - 1]}}, in_burstwrap};
extended_burstwrap_reg = {{(ADDR_WIDTH - BNDRY_WIDTH) {in_burstwrap_reg[BNDRY_WIDTH - 1]}}, in_burstwrap_reg};
new_burst_export = new_burst;
end
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= reset;
end
end
endgenerate
// -------------------------------------------
// length calculation
// -------------------------------------------
reg [LEN_WIDTH -1 : 0] next_uncompr_remaining_len;
always_comb begin
// Signals name
// *_uncompr_* --> uncompressed transaction
// -------------------------------------------
// Always use max_out_length as possible.
// Else use the remaining length.
// If in length smaller and not cross bndry or same, pass thru.
if (in_sop) begin
uncompr_remaining_len = in_len;
end
else begin
uncompr_remaining_len = next_uncompr_remaining_len;
end
end // always_comb
// compressed transactions
always_comb begin : proc_compressed_read
remaining_len = in_len;
if (!new_burst)
remaining_len = next_rem_len;
end
always_comb begin
next_uncompr_out_len = first_len;
if (in_sop) begin
next_uncompr_out_len = first_len;
end
else begin
if (uncompr_sub_burst)
next_uncompr_out_len = next_uncompr_sub_len;
else begin
if (uncompr_remaining_len < max_out_length)
next_uncompr_out_len = uncompr_remaining_len;
else
next_uncompr_out_len = max_out_length;
end
end
end
// Compressed transaction: Always try to send MAX out_len then remaining length.
// Seperate it as the main difference is the first out len.
// For a WRAP burst, the first beat is the aligned length, then similar to INCR.
always_comb begin
if (new_burst) begin
next_out_len = first_len;
end
else begin
next_out_len = max_out_length;
if (remaining_len < max_out_length) begin
next_out_len = remaining_len;
end
end
end // always_comb
// --------------------------------------------------
// Length remaining calculation : Compressed
// --------------------------------------------------
// length remaining for compressed transaction
// for wrap, need special handling for first out length
always_ff @(posedge clk) begin
if (enable_read) begin
if (new_burst)
next_rem_len <= in_len - first_len;
else
next_rem_len <= next_rem_len - max_out_length;
end
end // always_ff @
//generate
// if (SYNC_RESET == 0) begin : async_rst1
// always_ff @(posedge clk, posedge reset) begin
// if (reset)
// next_rem_len <= 0;
// else if (enable_read) begin
// if (new_burst)
// next_rem_len <= in_len - first_len;
// else
// next_rem_len <= next_rem_len - max_out_length;
// end
// end // always_ff @
// end // async_rst1
// else begin // sync_rst1
// always_ff @(posedge clk) begin
// if (internal_sclr)
// next_rem_len <= 0;
// else if (enable_read) begin
// if (new_burst)
// next_rem_len <= in_len - first_len;
// else
// next_rem_len <= next_rem_len - max_out_length;
// end
// end // always_ff @
// end // sync_rst1
// endgenerate
// --------------------------------------------------
// Length remaining calculation : Uncompressed
// --------------------------------------------------
always_ff @(posedge clk) begin
if (enable_write) begin
if (in_sop)
next_uncompr_remaining_len <= in_len - first_len;
else if (!uncompr_sub_burst)
next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
end
end // always_ff @
// length for each sub-burst if it needs to chop the burst
always_ff @(posedge clk) begin
if (enable_write) begin
next_uncompr_sub_len <= next_uncompr_out_len - 1'b1; // in term of length, it just reduces 1
end
end
generate
if (SYNC_RESET == 0) begin : async_rst2
//always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_uncompr_remaining_len <= 0;
// end
// else if (enable_write) begin
// if (in_sop)
// next_uncompr_remaining_len <= in_len - first_len;
// else if (!uncompr_sub_burst)
// next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
// end
//end // always_ff @
//// length for each sub-burst if it needs to chop the burst
//always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// next_uncompr_sub_len <= 0;
// end
// else if (enable_write) begin
// next_uncompr_sub_len <= next_uncompr_out_len - 1'b1; // in term of length, it just reduces 1
// end
//end
// the sub-burst still active
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
uncompr_sub_burst <= 0;
end
else if (enable_write) begin
uncompr_sub_burst <= (next_uncompr_out_len > 1'b1);
end
end
end // async_rst1
else begin // sync_rst2
//always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_uncompr_remaining_len <= 0;
// end
// else if (enable_write) begin
// if (in_sop)
// next_uncompr_remaining_len <= in_len - first_len;
// else if (!uncompr_sub_burst)
// next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
// end
//end // always_ff @
//
//// length for each sub-burst if it needs to chop the burst
//always_ff @(posedge clk) begin
// if (internal_sclr) begin
// next_uncompr_sub_len <= 0;
// end
// else if (enable_write) begin
// next_uncompr_sub_len <= next_uncompr_out_len - 1'b1; // in term of length, it just reduces 1
// end
//end
// the sub-burst still active
always_ff @(posedge clk) begin
if (internal_sclr) begin
uncompr_sub_burst <= 0;
end
else if (enable_write) begin
uncompr_sub_burst <= (next_uncompr_out_len > 1'b1);
end
end
end // sync_rst2
endgenerate
// --------------------------------------------------
// Control signals
// --------------------------------------------------
wire end_compressed_sub_burst;
assign end_compressed_sub_burst = (remaining_len == next_out_len);
// new_burst:
// the converter takes in_len for new caculation
generate
if (SYNC_RESET == 0) begin : async_rst3
always_ff @(posedge clk, posedge reset) begin
if (reset) begin
new_burst <= 1;
end
else if (enable_read) begin
new_burst <= end_compressed_sub_burst;
end
end
end // async_rst3
else begin // sync_rst3
always_ff @(posedge clk) begin
if (internal_sclr) begin
new_burst <= 1;
end
else if (enable_read) begin
new_burst <= end_compressed_sub_burst;
end
end
end // sync_rst3
endgenerate
// --------------------------------------------------
// Output length
// --------------------------------------------------
// register out_len for compressed trans
always_ff @(posedge clk) begin
if (enable_read) begin
out_len <= next_out_len;
end
end
//generate
// if (SYNC_RESET == 0) begin : async_rst4
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_len <= 0;
// end
// else if (enable_read) begin
// out_len <= next_out_len;
// end
// end
// end // async_rst4
// else begin // sync_rst4
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_len <= 0;
// end
// else if (enable_read) begin
// out_len <= next_out_len;
// end
// end
// end // sync_rst4
//endgenerate
// register uncompr_out_len for uncompressed trans
generate
if (OPTIMIZE_WRITE_BURST) begin : optimized_write_burst_len
always_ff @(posedge clk) begin
if (enable_read) begin
uncompr_out_len <= first_len;
end
end
//if (SYNC_RESET == 0) begin : async_rst5
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// uncompr_out_len <= '0;
// end
// //else if (enable_write) begin
// else if (enable_read) begin
// uncompr_out_len <= first_len;
// end
// end
//end // async_rst5
//else begin // sync_rst5
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// uncompr_out_len <= '0;
// end
// //else if (enable_write) begin
// else if (enable_read) begin
// uncompr_out_len <= first_len;
// end
// end
//end // sync_rst5
end
else begin : unoptimized_write_burst_len
always_ff @(posedge clk) begin
if (enable_write) begin
uncompr_out_len <= next_uncompr_out_len;
end
end
//if (SYNC_RESET == 0) begin : async_rst6
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// uncompr_out_len <= '0;
// end
// else if (enable_write) begin
// uncompr_out_len <= next_uncompr_out_len;
// end
// end
// end // async_rst6
// else begin // sync_rst6
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// uncompr_out_len <= '0;
// end
// else if (enable_write) begin
// uncompr_out_len <= next_uncompr_out_len;
// end
// end
// end // sync_rst6
end // else unoptimized
endgenerate
// --------------------------------------------------
// Address calculation
// --------------------------------------------------
reg [ADDR_WIDTH - 1 : 0] addr_incr;
localparam [ADDR_WIDTH - 1 : 0] ADDR_INCR = MAX_OUT_LEN << LOG2_NUMSYMBOLS;
assign addr_incr = ADDR_INCR[ADDR_WIDTH - 1 : 0];
reg [ADDR_WIDTH - 1 : 0] next_out_addr;
reg [ADDR_WIDTH - 1 : 0] incremented_addr;
always_ff @(posedge clk) begin
if (enable_read) begin
out_addr <= (next_out_addr);
end
end // always_ff @
//generate
// if (SYNC_RESET == 0) begin : async_rst7
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// out_addr <= '0;
// end
// else begin
// if (enable_read) begin
// out_addr <= (next_out_addr);
// end
// end
// end // always_ff @
// end // async_rst7
// else begin // sync_rst7
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// out_addr <= '0;
// end
// else begin
// if (enable_read) begin
// out_addr <= (next_out_addr);
// end
// end
// end // always_ff @
// end // sync_rst7
// endgenerate
// use burstwrap/burstwrap_reg to calculate address incrementing
always_ff @(posedge clk) begin
if (enable_read) begin
incremented_addr <= ((next_out_addr + addr_incr) & extended_burstwrap_reg);
if (new_burst) begin
incremented_addr <= ((next_out_addr + (first_len << LOG2_NUMSYMBOLS)) & extended_burstwrap); //byte address
end
end
end // always_ff @
//generate
// if (SYNC_RESET == 0) begin : async_rst8
// always_ff @(posedge clk, posedge reset) begin
// if (reset) begin
// incremented_addr <= '0;
// end
// else if (enable_read) begin
// incremented_addr <= ((next_out_addr + addr_incr) & extended_burstwrap_reg);
// if (new_burst) begin
// incremented_addr <= ((next_out_addr + (first_len << LOG2_NUMSYMBOLS)) & extended_burstwrap); //byte address
// end
// end
// end // always_ff @
// end // async_rst8
// else begin // sync_rst8
// always_ff @(posedge clk) begin
// if (internal_sclr) begin
// incremented_addr <= '0;
// end
// else if (enable_read) begin
// incremented_addr <= ((next_out_addr + addr_incr) & extended_burstwrap_reg);
// if (new_burst) begin
// incremented_addr <= ((next_out_addr + (first_len << LOG2_NUMSYMBOLS)) & extended_burstwrap); //byte address
// end
// end
// end // always_ff @
// end // sync_rst8
// endgenerate
always_comb begin
next_out_addr = in_addr;
if (!new_burst) begin
next_out_addr = in_addr_reg & ~extended_burstwrap_reg | incremented_addr;
end
end
// --------------------------------------------------
// Calculates the log2ceil of the input value
// --------------------------------------------------
function integer log2ceil;
input integer val;
reg[31:0] i;
begin
i = 1;
log2ceil = 0;
while (i < val) begin
log2ceil = log2ceil + 1;
i = i[30:0] << 1;
end
end
endfunction
endmodule
`ifdef QUESTA_INTEL_OEM
`pragma questa_oem_00 "mfufSZOYfNPxmSfS+FkCl32e9bHGnpakqHX1nHXvrhE4J6x8qGVCEAJRqHIBXSp/FcyWPq9/UmljeMey51E9VTMH3OCNEvZdEUSPU4/Vf6DgtU26zIfR3Ws2AtmUBXEHD5yEeHuHpEMedz5PLIdzFsBxJ/9OiyM+8A3UVG3icM2FQlZPfaXli71zX1obNH4Hi4tyLUZvYQoJv7xSQMqW1lxant16XP5C2V2aZfTOCZllKnWAX9N5dw2ADgRBGnFz2jF7qT9llBrp2SnRSqQQqPwDlEJk2UeGJPg3ES1cQXyK7KIOLJhXnkePUfQ+bKASdNX8T7B/JBvWmq4yvDwftVX9k5+DhxB4OJiOiGMqZKtpOPRfmNUafND1njfnIo2+Il2fpo21b+lm2UGn2crz+4Ezg30kTMwDWGkjPxTpP+2w7tTrZzHLDzMZ89zy8rTRiEFhl1zRMzfRBlxZEdr8KZeO1XX5rQSctBdRLCrIlqVgsWi3TEoSoxumsqHaOLlStKdjywMkU8JDDdO6voRm5WiU/LSmcDRdX/TQX9Ml2MORWtmZi32gRfAxwBnIj8Gi3bWIbi4v9r55CeoZqWe2dia2mOA6SwlKOd1EnFKwLwNrUsR2ia05vFXplhOCqXNZPp0BEo7XnkZjZ5dtrHxxGrr7g08uOjFbYbAd38T3KlaPDq41azfwlaky8agCeG50E5Vq0me3pK7xJBMr5JAACNM1tlbLvx+CtxMrVouByfc6xI/1b9Az/bxjsHy0MHAYHq4PPn5FlFDrk1iOBUD7zef+6Dy0a1pN7+YgZIw19YBJo2i9FTEcRCEt4qTdjY9z4N2KltJPRl5OFjEONQnCrTLlZcJJHzuHoW3RbnWyk6bdJ+OnsHUq+R7dIBiuetQcIcAw5nICBm106qEL6rTdp4xSX4a5uMgRvkm22XjXE1nbADFmkPKafOWwnPFon9mLQnL6a2qObBM3miUYE8VCVI/iTtB8oWJ9/SnA6EEyCHYZ6crWU3hwkln3/4RQRXw6"
`endif
@@ -0,0 +1,361 @@
// (C) 2001-2026 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 from 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 IP 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.
`timescale 1 ns / 1 ns
// -----------------------------------------------------
// Top level for the burst adapter. This selects the
// implementation for the adapter, based on the
// parameterization.
// -----------------------------------------------------
module qsys_top_altera_merlin_burst_adapter_1940_6zvwdfy
#(
parameter
// Indicates the implementation to instantiate:
// "13.1" means the slow, inexpensive generic burst converter.
// "new" means the fast, expensive per-burst converter.
ADAPTER_VERSION = "13.1",
// Indicates if this adapter needs to support read bursts
// (almost always true).
COMPRESSED_READ_SUPPORT = 1,
// 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,
PKT_SAI_H = 89,
PKT_SAI_L = 89,
PKT_EOP_OOO = 90,
PKT_SOP_OOO = 91,
ST_DATA_W = 92,
ST_CHANNEL_W = 8,
ROLE_BASED_USER = 0,
ENABLE_AXI5 = 0,
ENABLE_OOO = 0,
// Component-specific parameters. Explained
// in the implementation levels
IN_NARROW_SIZE = 0,
NO_WRAP_SUPPORT = 0,
INCOMPLETE_WRAP_SUPPORT = 1,
BURSTWRAP_CONST_MASK = 0,
BURSTWRAP_CONST_VALUE = 2147483647, //equivalent to {31{1'b1}} -- ncsim does not like negative values (-1), or the replication format
OUT_NARROW_SIZE = 0,
OUT_FIXED = 0,
OUT_COMPLETE_WRAP = 0,
BYTEENABLE_SYNTHESIS = 0,
PIPE_INPUTS = 0,
OUT_BYTE_CNT_H = 5,
OUT_BURSTWRAP_H = 11,
SYNC_RESET = 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 wire source0_valid,
output wire [ST_DATA_W-1 : 0] source0_data,
output wire [ST_CHANNEL_W-1 : 0] source0_channel,
output wire source0_startofpacket,
output wire source0_endofpacket,
input source0_ready
);
localparam PKT_BURSTWRAP_W = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1;
generate if (COMPRESSED_READ_SUPPORT == 0) begin : altera_merlin_burst_adapter_uncompressed_only
// -------------------------------------------------------------------
// The reduced version of the adapter is only meant to be used on
// non-bursting wide to narrow links.
// -------------------------------------------------------------------
altera_merlin_burst_adapter_uncompressed_only #(
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L),
.PKT_BYTEEN_H (PKT_BYTEEN_H),
.PKT_BYTEEN_L (PKT_BYTEEN_L),
.ST_DATA_W (ST_DATA_W),
.ST_CHANNEL_W (ST_CHANNEL_W)
) burst_adapter (
.clk (clk),
.reset (reset),
.sink0_valid (sink0_valid),
.sink0_data (sink0_data),
.sink0_channel (sink0_channel),
.sink0_startofpacket (sink0_startofpacket),
.sink0_endofpacket (sink0_endofpacket),
.sink0_ready (sink0_ready),
.source0_valid (source0_valid),
.source0_data (source0_data),
.source0_channel (source0_channel),
.source0_startofpacket (source0_startofpacket),
.source0_endofpacket (source0_endofpacket),
.source0_ready (source0_ready)
);
end
else if (ADAPTER_VERSION == "13.1") begin : altera_merlin_burst_adapter_13_1
// -----------------------------------------------------
// This is the generic converter implementation, which attempts
// to convert all burst types with a generalized conversion
// function. This results in low area, but low fmax.
// -----------------------------------------------------
altera_merlin_burst_adapter_13_1 #(
.PKT_BEGIN_BURST (PKT_BEGIN_BURST),
.PKT_ADDR_H (PKT_ADDR_H ),
.PKT_ADDR_L (PKT_ADDR_L),
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L ),
.PKT_BURSTWRAP_H (PKT_BURSTWRAP_H),
.PKT_BURSTWRAP_L (PKT_BURSTWRAP_L),
.PKT_TRANS_COMPRESSED_READ (PKT_TRANS_COMPRESSED_READ),
.PKT_TRANS_WRITE (PKT_TRANS_WRITE),
.PKT_TRANS_READ (PKT_TRANS_READ),
.PKT_BYTEEN_H (PKT_BYTEEN_H),
.PKT_BYTEEN_L (PKT_BYTEEN_L),
.PKT_BURST_TYPE_H (PKT_BURST_TYPE_H),
.PKT_BURST_TYPE_L (PKT_BURST_TYPE_L),
.PKT_BURST_SIZE_H (PKT_BURST_SIZE_H),
.PKT_BURST_SIZE_L (PKT_BURST_SIZE_L),
.PKT_SAI_H (PKT_SAI_H),
.PKT_SAI_L (PKT_SAI_L),
.PKT_EOP_OOO (PKT_EOP_OOO),
.PKT_SOP_OOO (PKT_SOP_OOO),
.ENABLE_OOO (ENABLE_OOO),
.IN_NARROW_SIZE (IN_NARROW_SIZE),
.BYTEENABLE_SYNTHESIS (BYTEENABLE_SYNTHESIS),
.OUT_NARROW_SIZE (OUT_NARROW_SIZE),
.OUT_FIXED (OUT_FIXED),
.OUT_COMPLETE_WRAP (OUT_COMPLETE_WRAP),
.ST_DATA_W (ST_DATA_W),
.ST_CHANNEL_W (ST_CHANNEL_W),
.ROLE_BASED_USER (ROLE_BASED_USER),
.ENABLE_AXI5 (ENABLE_AXI5),
.BURSTWRAP_CONST_MASK (BURSTWRAP_CONST_MASK),
.BURSTWRAP_CONST_VALUE (BURSTWRAP_CONST_VALUE),
.PIPE_INPUTS (PIPE_INPUTS),
.NO_WRAP_SUPPORT (NO_WRAP_SUPPORT),
.OUT_BYTE_CNT_H (OUT_BYTE_CNT_H),
.OUT_BURSTWRAP_H (OUT_BURSTWRAP_H),
.SYNC_RESET (SYNC_RESET)
) burst_adapter (
.clk (clk),
.reset (reset),
.sink0_valid (sink0_valid),
.sink0_data (sink0_data),
.sink0_channel (sink0_channel),
.sink0_startofpacket (sink0_startofpacket),
.sink0_endofpacket (sink0_endofpacket),
.sink0_ready (sink0_ready),
.source0_valid (source0_valid),
.source0_data (source0_data),
.source0_channel (source0_channel),
.source0_startofpacket (source0_startofpacket),
.source0_endofpacket (source0_endofpacket),
.source0_ready (source0_ready)
);
end
else begin : altera_merlin_burst_adapter_new
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;
// -----------------------------------------------------
// This is the per-burst-type converter implementation. This attempts
// to convert bursts with specialized functions for each burst
// type. This typically results in higher area, but higher fmax.
// -----------------------------------------------------
altera_merlin_burst_adapter_new #(
.PKT_BEGIN_BURST (PKT_BEGIN_BURST),
.PKT_ADDR_H (PKT_ADDR_H ),
.PKT_ADDR_L (PKT_ADDR_L),
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L ),
.PKT_BURSTWRAP_H (PKT_BURSTWRAP_H),
.PKT_BURSTWRAP_L (PKT_BURSTWRAP_L),
.PKT_TRANS_COMPRESSED_READ (PKT_TRANS_COMPRESSED_READ),
.PKT_TRANS_WRITE (PKT_TRANS_WRITE),
.PKT_TRANS_READ (PKT_TRANS_READ),
.PKT_BYTEEN_H (PKT_BYTEEN_H),
.PKT_BYTEEN_L (PKT_BYTEEN_L),
.PKT_BURST_TYPE_H (PKT_BURST_TYPE_H),
.PKT_BURST_TYPE_L (PKT_BURST_TYPE_L),
.PKT_BURST_SIZE_H (PKT_BURST_SIZE_H),
.PKT_BURST_SIZE_L (PKT_BURST_SIZE_L),
.PKT_SAI_H (PKT_SAI_H),
.PKT_SAI_L (PKT_SAI_L),
.PKT_EOP_OOO (PKT_EOP_OOO),
.PKT_SOP_OOO (PKT_SOP_OOO),
.ENABLE_OOO (ENABLE_OOO),
.IN_NARROW_SIZE (IN_NARROW_SIZE),
.BYTEENABLE_SYNTHESIS (BYTEENABLE_SYNTHESIS),
.OUT_NARROW_SIZE (OUT_NARROW_SIZE),
.OUT_FIXED (OUT_FIXED),
.OUT_COMPLETE_WRAP (OUT_COMPLETE_WRAP),
.ST_DATA_W (ST_DATA_W),
.ROLE_BASED_USER (ROLE_BASED_USER),
.ENABLE_AXI5 (ENABLE_AXI5),
.ST_CHANNEL_W (ST_CHANNEL_W),
.BURSTWRAP_CONST_MASK (BURSTWRAP_CONST_MASK),
.BURSTWRAP_CONST_VALUE (BURSTWRAP_CONST_VALUE),
.PIPE_INPUTS (PIPE_INPUTS),
.NO_WRAP_SUPPORT (NO_WRAP_SUPPORT),
.INCOMPLETE_WRAP_SUPPORT (INCOMPLETE_WRAP_SUPPORT),
.OUT_BYTE_CNT_H (OUT_BYTE_CNT_H),
.OUT_BURSTWRAP_H (OUT_BURSTWRAP_H),
.SYNC_RESET (SYNC_RESET)
) burst_adapter (
.clk (clk),
.reset (reset),
.sink0_valid (sink0_pipe_valid),
.sink0_data (sink0_pipe_data),
.sink0_channel (sink0_pipe_channel),
.sink0_startofpacket (sink0_pipe_sop),
.sink0_endofpacket (sink0_pipe_eop),
.sink0_ready (sink0_pipe_ready),
.source0_valid (source0_valid),
.source0_data (source0_data),
.source0_channel (source0_channel),
.source0_startofpacket (source0_startofpacket),
.source0_endofpacket (source0_endofpacket),
.source0_ready (source0_ready)
);
if(PIPE_INPUTS == 1) begin: pipe_inputs
qsys_top_altera_merlin_burst_adapter_altera_avalon_st_pipeline_stage_1940_ykdw6di # (
.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),
.SYNC_RESET (SYNC_RESET)
) pipe_stage (
.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)
);
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
end
endgenerate
// Generation of internal reset synchronization
reg internal_sclr;
generate if (SYNC_RESET == 1) begin : rst_syncronizer
always @ (posedge clk) begin
internal_sclr <= reset;
end
end
endgenerate
// synthesis translate_off
// -----------------------------------------------------
// Simulation-only check for incoming burstwrap values inconsistent with
// BURSTWRAP_CONST_MASK, which would indicate a paramerization error.
//
// Should be turned into an assertion, really.
// -----------------------------------------------------
generate
if (SYNC_RESET == 0) begin : async_rst0
always @(posedge clk or posedge reset) begin
if (reset) begin
end
else if (sink0_valid &&
BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0] &
(BURSTWRAP_CONST_VALUE[PKT_BURSTWRAP_W - 1:0] ^ sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L])
) begin
$display("%t: %m: Error: burstwrap value %X is inconsistent with BURSTWRAP_CONST_MASK value %X", $time(), sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L], BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0]);
end
end
end : async_rst0
else begin : sync_rst0
always @(posedge clk ) begin
if ((internal_sclr == 1'b0) && sink0_valid &&
BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0] &
(BURSTWRAP_CONST_VALUE[PKT_BURSTWRAP_W - 1:0] ^ sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L])
) begin
$display("%t: %m: Error: burstwrap value %X is inconsistent with BURSTWRAP_CONST_MASK value %X", $time(), sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L], BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0]);
end
end
end : sync_rst0
endgenerate
// synthesis translate_on
endmodule
@@ -0,0 +1,66 @@
// qsys_top_altera_merlin_burst_adapter_altera_avalon_st_pipeline_stage_1940_ykdw6di.v
// Generated using ACDS version 26.1 110
`timescale 1 ps / 1 ps
module qsys_top_altera_merlin_burst_adapter_altera_avalon_st_pipeline_stage_1940_ykdw6di #(
parameter SYMBOLS_PER_BEAT = 1,
parameter BITS_PER_SYMBOL = 171,
parameter USE_PACKETS = 1,
parameter USE_EMPTY = 0,
parameter EMPTY_WIDTH = 0,
parameter CHANNEL_WIDTH = 2,
parameter PACKET_WIDTH = 2,
parameter ERROR_WIDTH = 0,
parameter PIPELINE_READY = 1,
parameter SYNC_RESET = 1
) (
input wire clk, // cr0.clk, Clock input
input wire reset, // cr0_reset.reset, Reset input
output wire in_ready, // sink0.ready, Ready port of Avalon Streaming Sink Interface; indicates when sink interface is ready to receive data
input wire in_valid, // .valid, Valid data port of Avalon Streaming Sink Interface; high when input data is valid
input wire in_startofpacket, // .startofpacket, Start of packet port of Avalon Streaming Sink Interface;Indicates start of incoming packet
input wire in_endofpacket, // .endofpacket, End of packet port of Avalon Streaming Sink Interface; Indicates end of incoming packet
input wire [170:0] in_data, // .data, Input Data port of Avalon Streaming Sink Interface
input wire [1:0] in_channel, // .channel, Channel input port of Avalon Streaming Sink Interface
input wire out_ready, // source0.ready, Ready port of Avalon Streaming Source Interface; indicates to source that data can be sent
output wire out_valid, // .valid, Valid data port of Avalon Streaming Source Interface; high when output data is valid
output wire out_startofpacket, // .startofpacket, Start of packet port of Avalon Streaming Source Interface; Indicates start of outgoing packet
output wire out_endofpacket, // .endofpacket, End of packet port of Avalon Streaming Source Interface; Indicates end of outgoing packet
output wire [170:0] out_data, // .data, Output Data port of Avalon Streaming Source Interface
output wire [1:0] out_channel // .channel, Channel output port of Avalon Streaming Source Interface
);
qsys_top_altera_avalon_st_pipeline_stage_1930_oiupeiq #(
.SYMBOLS_PER_BEAT (SYMBOLS_PER_BEAT),
.BITS_PER_SYMBOL (BITS_PER_SYMBOL),
.USE_PACKETS (USE_PACKETS),
.USE_EMPTY (USE_EMPTY),
.EMPTY_WIDTH (EMPTY_WIDTH),
.CHANNEL_WIDTH (CHANNEL_WIDTH),
.PACKET_WIDTH (PACKET_WIDTH),
.ERROR_WIDTH (ERROR_WIDTH),
.PIPELINE_READY (PIPELINE_READY),
.SYNC_RESET (SYNC_RESET)
) my_altera_avalon_st_pipeline_stage (
.clk (clk), // input, width = 1, cr0.clk
.reset (reset), // input, width = 1, cr0_reset.reset
.in_ready (in_ready), // output, width = 1, sink0.ready
.in_valid (in_valid), // input, width = 1, .valid
.in_startofpacket (in_startofpacket), // input, width = 1, .startofpacket
.in_endofpacket (in_endofpacket), // input, width = 1, .endofpacket
.in_data (in_data), // input, width = 171, .data
.in_channel (in_channel), // input, width = 2, .channel
.out_ready (out_ready), // input, width = 1, source0.ready
.out_valid (out_valid), // output, width = 1, .valid
.out_startofpacket (out_startofpacket), // output, width = 1, .startofpacket
.out_endofpacket (out_endofpacket), // output, width = 1, .endofpacket
.out_data (out_data), // output, width = 171, .data
.out_channel (out_channel), // output, width = 2, .channel
.in_empty (1'b0), // (terminated),
.out_empty (), // (terminated),
.out_error (), // (terminated),
.in_error (1'b0) // (terminated),
);
endmodule