123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- // (C) 2001-2018 Intel Corporation. All rights reserved.
- // Your use of Intel 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 Intel Program License Subscription
- // Agreement, Intel FPGA 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 Intel and sold by
- // Intel 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/18.1std/ip/merlin/altera_merlin_router/altera_merlin_router.sv.terp#1 $
- // $Revision: #1 $
- // $Date: 2018/07/18 $
- // $Author: psgswbuild $
- // -------------------------------------------------------
- // 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 nios2_uc_mm_interconnect_0_router_default_decode
- #(
- parameter DEFAULT_CHANNEL = 3,
- DEFAULT_WR_CHANNEL = -1,
- DEFAULT_RD_CHANNEL = -1,
- DEFAULT_DESTID = 3
- )
- (output [82 - 80 : 0] default_destination_id,
- output [7-1 : 0] default_wr_channel,
- output [7-1 : 0] default_rd_channel,
- output [7-1 : 0] default_src_channel
- );
- assign default_destination_id =
- DEFAULT_DESTID[82 - 80 : 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 = 7'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 = 7'b1 << DEFAULT_WR_CHANNEL;
- assign default_rd_channel = 7'b1 << DEFAULT_RD_CHANNEL;
- end
- endgenerate
- endmodule
- module nios2_uc_mm_interconnect_0_router
- (
- // -------------------
- // Clock & Reset
- // -------------------
- input clk,
- input reset,
- // -------------------
- // Command Sink (Input)
- // -------------------
- input sink_valid,
- input [96-1 : 0] sink_data,
- input sink_startofpacket,
- input sink_endofpacket,
- output sink_ready,
- // -------------------
- // Command Source (Output)
- // -------------------
- output src_valid,
- output reg [96-1 : 0] src_data,
- output reg [7-1 : 0] src_channel,
- output src_startofpacket,
- output src_endofpacket,
- input src_ready
- );
- // -------------------------------------------------------
- // Local parameters and variables
- // -------------------------------------------------------
- localparam PKT_ADDR_H = 55;
- localparam PKT_ADDR_L = 36;
- localparam PKT_DEST_ID_H = 82;
- localparam PKT_DEST_ID_L = 80;
- localparam PKT_PROTECTION_H = 86;
- localparam PKT_PROTECTION_L = 84;
- localparam ST_DATA_W = 96;
- localparam ST_CHANNEL_W = 7;
- localparam DECODER_TYPE = 0;
- localparam PKT_TRANS_WRITE = 58;
- localparam PKT_TRANS_READ = 59;
- 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'h80000 - 64'h40000);
- localparam PAD1 = log2ceil(64'h81000 - 64'h80800);
- localparam PAD2 = log2ceil(64'h81050 - 64'h81040);
- localparam PAD3 = log2ceil(64'h81060 - 64'h81050);
- localparam PAD4 = log2ceil(64'h81070 - 64'h81060);
- localparam PAD5 = log2ceil(64'h81080 - 64'h81070);
- localparam PAD6 = log2ceil(64'h81090 - 64'h81088);
- // -------------------------------------------------------
- // 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'h81090;
- 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 [7-1 : 0] default_src_channel;
- // -------------------------------------------------------
- // Write and read transaction signals
- // -------------------------------------------------------
- wire read_transaction;
- assign read_transaction = sink_data[PKT_TRANS_READ];
- nios2_uc_mm_interconnect_0_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
- // --------------------------------------------------
- // ( 0x40000 .. 0x80000 )
- if ( {address[RG:PAD0],{PAD0{1'b0}}} == 20'h40000 ) begin
- src_channel = 7'b0001000;
- src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 3;
- end
- // ( 0x80800 .. 0x81000 )
- if ( {address[RG:PAD1],{PAD1{1'b0}}} == 20'h80800 ) begin
- src_channel = 7'b0000100;
- src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 2;
- end
- // ( 0x81040 .. 0x81050 )
- if ( {address[RG:PAD2],{PAD2{1'b0}}} == 20'h81040 && read_transaction ) begin
- src_channel = 7'b1000000;
- src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 4;
- end
- // ( 0x81050 .. 0x81060 )
- if ( {address[RG:PAD3],{PAD3{1'b0}}} == 20'h81050 ) begin
- src_channel = 7'b0100000;
- src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 6;
- end
- // ( 0x81060 .. 0x81070 )
- if ( {address[RG:PAD4],{PAD4{1'b0}}} == 20'h81060 ) begin
- src_channel = 7'b0010000;
- src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 5;
- end
- // ( 0x81070 .. 0x81080 )
- if ( {address[RG:PAD5],{PAD5{1'b0}}} == 20'h81070 ) begin
- src_channel = 7'b0000010;
- src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 1;
- end
- // ( 0x81088 .. 0x81090 )
- if ( {address[RG:PAD6],{PAD6{1'b0}}} == 20'h81088 ) begin
- src_channel = 7'b0000001;
- 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
|