// (C) 2001-2015 Altera Corporation. All rights reserved. // Your use of Altera Corporation's design tools, logic functions and other // software and tools, and its AMPP partner logic functions, and any output // files any of the foregoing (including device programming or simulation // files), and any associated documentation or information are expressly subject // to the terms and conditions of the Altera Program License Subscription // Agreement, Altera MegaCore Function License Agreement, or other applicable // license agreement, including, without limitation, that your use is for the // sole purpose of programming logic devices manufactured by Altera and sold by // Altera or its authorized distributors. Please refer to the applicable // agreement for further details. // Your use of Altera Corporation's design tools, logic functions and other // software and tools, and its AMPP partner logic functions, and any output // files any of the foregoing (including device programming or simulation // files), and any associated documentation or information are expressly subject // to the terms and conditions of the Altera Program License Subscription // Agreement, Altera MegaCore Function License Agreement, or other applicable // license agreement, including, without limitation, that your use is for the // sole purpose of programming logic devices manufactured by Altera and sold by // Altera or its authorized distributors. Please refer to the applicable // agreement for further details. // $Id: //acds/rel/15.1/ip/merlin/altera_merlin_router/altera_merlin_router.sv.terp#1 $ // $Revision: #1 $ // $Date: 2015/08/09 $ // $Author: swbranch $ // ------------------------------------------------------- // Merlin Router // // Asserts the appropriate one-hot encoded channel based on // either (a) the address or (b) the dest id. The DECODER_TYPE // parameter controls this behaviour. 0 means address decoder, // 1 means dest id decoder. // // In the case of (a), it also sets the destination id. // ------------------------------------------------------- `timescale 1 ns / 1 ns module ddr3_mm_interconnect_2_router_default_decode #( parameter DEFAULT_CHANNEL = 0, DEFAULT_WR_CHANNEL = -1, DEFAULT_RD_CHANNEL = -1, DEFAULT_DESTID = 1 ) (output [88 - 88 : 0] default_destination_id, output [2-1 : 0] default_wr_channel, output [2-1 : 0] default_rd_channel, output [2-1 : 0] default_src_channel ); assign default_destination_id = DEFAULT_DESTID[88 - 88 : 0]; generate if (DEFAULT_CHANNEL == -1) begin : no_default_channel_assignment assign default_src_channel = '0; end else begin : default_channel_assignment assign default_src_channel = 2'b1 << DEFAULT_CHANNEL; end endgenerate generate if (DEFAULT_RD_CHANNEL == -1) begin : no_default_rw_channel_assignment assign default_wr_channel = '0; assign default_rd_channel = '0; end else begin : default_rw_channel_assignment assign default_wr_channel = 2'b1 << DEFAULT_WR_CHANNEL; assign default_rd_channel = 2'b1 << DEFAULT_RD_CHANNEL; end endgenerate endmodule module ddr3_mm_interconnect_2_router ( // ------------------- // Clock & Reset // ------------------- input clk, input reset, // ------------------- // Command Sink (Input) // ------------------- input sink_valid, input [102-1 : 0] sink_data, input sink_startofpacket, input sink_endofpacket, output sink_ready, // ------------------- // Command Source (Output) // ------------------- output src_valid, output reg [102-1 : 0] src_data, output reg [2-1 : 0] src_channel, output src_startofpacket, output src_endofpacket, input src_ready ); // ------------------------------------------------------- // Local parameters and variables // ------------------------------------------------------- localparam PKT_ADDR_H = 67; localparam PKT_ADDR_L = 36; localparam PKT_DEST_ID_H = 88; localparam PKT_DEST_ID_L = 88; localparam PKT_PROTECTION_H = 92; localparam PKT_PROTECTION_L = 90; localparam ST_DATA_W = 102; localparam ST_CHANNEL_W = 2; localparam DECODER_TYPE = 0; localparam PKT_TRANS_WRITE = 70; localparam PKT_TRANS_READ = 71; localparam PKT_ADDR_W = PKT_ADDR_H-PKT_ADDR_L + 1; localparam PKT_DEST_ID_W = PKT_DEST_ID_H-PKT_DEST_ID_L + 1; // ------------------------------------------------------- // Figure out the number of bits to mask off for each slave span // during address decoding // ------------------------------------------------------- localparam PAD0 = log2ceil(64'h400 - 64'h0); localparam PAD1 = log2ceil(64'h800 - 64'h400); // ------------------------------------------------------- // Work out which address bits are significant based on the // address range of the slaves. If the required width is too // large or too small, we use the address field width instead. // ------------------------------------------------------- localparam ADDR_RANGE = 64'h800; localparam RANGE_ADDR_WIDTH = log2ceil(ADDR_RANGE); localparam OPTIMIZED_ADDR_H = (RANGE_ADDR_WIDTH > PKT_ADDR_W) || (RANGE_ADDR_WIDTH == 0) ? PKT_ADDR_H : PKT_ADDR_L + RANGE_ADDR_WIDTH - 1; localparam RG = RANGE_ADDR_WIDTH-1; localparam REAL_ADDRESS_RANGE = OPTIMIZED_ADDR_H - PKT_ADDR_L; reg [PKT_ADDR_W-1 : 0] address; always @* begin address = {PKT_ADDR_W{1'b0}}; address [REAL_ADDRESS_RANGE:0] = sink_data[OPTIMIZED_ADDR_H : PKT_ADDR_L]; end // ------------------------------------------------------- // Pass almost everything through, untouched // ------------------------------------------------------- assign sink_ready = src_ready; assign src_valid = sink_valid; assign src_startofpacket = sink_startofpacket; assign src_endofpacket = sink_endofpacket; wire [PKT_DEST_ID_W-1:0] default_destid; wire [2-1 : 0] default_src_channel; ddr3_mm_interconnect_2_router_default_decode the_default_decode( .default_destination_id (default_destid), .default_wr_channel (), .default_rd_channel (), .default_src_channel (default_src_channel) ); always @* begin src_data = sink_data; src_channel = default_src_channel; src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = default_destid; // -------------------------------------------------- // Address Decoder // Sets the channel and destination ID based on the address // -------------------------------------------------- // ( 0x0 .. 0x400 ) if ( {address[RG:PAD0],{PAD0{1'b0}}} == 11'h0 ) begin src_channel = 2'b01; src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 1; end // ( 0x400 .. 0x800 ) if ( {address[RG:PAD1],{PAD1{1'b0}}} == 11'h400 ) begin src_channel = 2'b10; src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 0; end end // -------------------------------------------------- // Ceil(log2()) function // -------------------------------------------------- function integer log2ceil; input reg[65:0] val; reg [65:0] i; begin i = 1; log2ceil = 0; while (i < val) begin log2ceil = log2ceil + 1; i = i << 1; end end endfunction endmodule