OpenCores
URL https://opencores.org/ocsvn/spacewiresystemc/spacewiresystemc/trunk

Subversion Repositories spacewiresystemc

[/] [spacewiresystemc/] [trunk/] [altera_work/] [spw_fifo_ulight/] [ulight_fifo/] [synthesis/] [submodules/] [ulight_fifo_mm_interconnect_0_cmd_mux.sv] - Diff between revs 32 and 40

Only display areas with differences | Details | Blame | View Log

Rev 32 Rev 40
// (C) 2001-2017 Intel Corporation. All rights reserved.
// (C) 2001-2017 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other
// Your use of Intel Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// software and tools, and its AMPP partner logic functions, and any output
// files any of the foregoing (including device programming or simulation
// files from any of the foregoing (including device programming or simulation
// files), and any associated documentation or information are expressly subject
// files), and any associated documentation or information are expressly subject
// to the terms and conditions of the Intel Program License Subscription
// to the terms and conditions of the Intel Program License Subscription
// Agreement, Intel MegaCore Function License Agreement, or other applicable
// Agreement, Intel FPGA IP License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Intel and sold by
// sole purpose of programming logic devices manufactured by Intel and sold by
// Intel or its authorized distributors.  Please refer to the applicable
// Intel or its authorized distributors.  Please refer to the applicable
// agreement for further details.
// agreement for further details.
// (C) 2001-2014 Altera Corporation. All rights reserved.
// (C) 2001-2014 Altera Corporation. All rights reserved.
// Your use of Altera Corporation's design tools, logic functions and other
// Your use of Altera Corporation's design tools, logic functions and other
// software and tools, and its AMPP partner logic functions, and any output
// software and tools, and its AMPP partner logic functions, and any output
// files any of the foregoing (including device programming or simulation
// files any of the foregoing (including device programming or simulation
// files), and any associated documentation or information are expressly subject
// files), and any associated documentation or information are expressly subject
// to the terms and conditions of the Altera Program License Subscription
// to the terms and conditions of the Altera Program License Subscription
// Agreement, Altera MegaCore Function License Agreement, or other applicable
// Agreement, Altera MegaCore Function License Agreement, or other applicable
// license agreement, including, without limitation, that your use is for the
// license agreement, including, without limitation, that your use is for the
// sole purpose of programming logic devices manufactured by Altera and sold by
// sole purpose of programming logic devices manufactured by Altera and sold by
// Altera or its authorized distributors.  Please refer to the applicable
// Altera or its authorized distributors.  Please refer to the applicable
// agreement for further details.
// agreement for further details.
 
 
// $Id: //acds/rel/17.0std/ip/merlin/altera_merlin_multiplexer/altera_merlin_multiplexer.sv.terp#1 $
// $Id: //acds/rel/17.1std/ip/merlin/altera_merlin_multiplexer/altera_merlin_multiplexer.sv.terp#1 $
// $Revision: #1 $
// $Revision: #1 $
// $Date: 2017/01/22 $
// $Date: 2017/07/30 $
// $Author: swbranch $
// $Author: swbranch $
// ------------------------------------------
// ------------------------------------------
// Merlin Multiplexer
// Merlin Multiplexer
// ------------------------------------------
// ------------------------------------------
`timescale 1 ns / 1 ns
`timescale 1 ns / 1 ns
// ------------------------------------------
// ------------------------------------------
// Generation parameters:
// Generation parameters:
//   output_name:         ulight_fifo_mm_interconnect_0_cmd_mux
//   output_name:         ulight_fifo_mm_interconnect_0_cmd_mux
//   NUM_INPUTS:          2
//   NUM_INPUTS:          2
//   ARBITRATION_SHARES:  1 1
//   ARBITRATION_SHARES:  1 1
//   ARBITRATION_SCHEME   "round-robin"
//   ARBITRATION_SCHEME   "round-robin"
//   PIPELINE_ARB:        1
//   PIPELINE_ARB:        1
//   PKT_TRANS_LOCK:      70 (arbitration locking enabled)
//   PKT_TRANS_LOCK:      70 (arbitration locking enabled)
//   ST_DATA_W:           129
//   ST_DATA_W:           129
//   ST_CHANNEL_W:        22
//   ST_CHANNEL_W:        22
// ------------------------------------------
// ------------------------------------------
module ulight_fifo_mm_interconnect_0_cmd_mux
module ulight_fifo_mm_interconnect_0_cmd_mux
(
(
    // ----------------------
    // ----------------------
    // Sinks
    // Sinks
    // ----------------------
    // ----------------------
    input                       sink0_valid,
    input                       sink0_valid,
    input [129-1   : 0]  sink0_data,
    input [129-1   : 0]  sink0_data,
    input [22-1: 0]  sink0_channel,
    input [22-1: 0]  sink0_channel,
    input                       sink0_startofpacket,
    input                       sink0_startofpacket,
    input                       sink0_endofpacket,
    input                       sink0_endofpacket,
    output                      sink0_ready,
    output                      sink0_ready,
    input                       sink1_valid,
    input                       sink1_valid,
    input [129-1   : 0]  sink1_data,
    input [129-1   : 0]  sink1_data,
    input [22-1: 0]  sink1_channel,
    input [22-1: 0]  sink1_channel,
    input                       sink1_startofpacket,
    input                       sink1_startofpacket,
    input                       sink1_endofpacket,
    input                       sink1_endofpacket,
    output                      sink1_ready,
    output                      sink1_ready,
    // ----------------------
    // ----------------------
    // Source
    // Source
    // ----------------------
    // ----------------------
    output                      src_valid,
    output                      src_valid,
    output [129-1    : 0] src_data,
    output [129-1    : 0] src_data,
    output [22-1 : 0] src_channel,
    output [22-1 : 0] src_channel,
    output                      src_startofpacket,
    output                      src_startofpacket,
    output                      src_endofpacket,
    output                      src_endofpacket,
    input                       src_ready,
    input                       src_ready,
    // ----------------------
    // ----------------------
    // Clock & Reset
    // Clock & Reset
    // ----------------------
    // ----------------------
    input clk,
    input clk,
    input reset
    input reset
);
);
    localparam PAYLOAD_W        = 129 + 22 + 2;
    localparam PAYLOAD_W        = 129 + 22 + 2;
    localparam NUM_INPUTS       = 2;
    localparam NUM_INPUTS       = 2;
    localparam SHARE_COUNTER_W  = 1;
    localparam SHARE_COUNTER_W  = 1;
    localparam PIPELINE_ARB     = 1;
    localparam PIPELINE_ARB     = 1;
    localparam ST_DATA_W        = 129;
    localparam ST_DATA_W        = 129;
    localparam ST_CHANNEL_W     = 22;
    localparam ST_CHANNEL_W     = 22;
    localparam PKT_TRANS_LOCK   = 70;
    localparam PKT_TRANS_LOCK   = 70;
    // ------------------------------------------
    // ------------------------------------------
    // Signals
    // Signals
    // ------------------------------------------
    // ------------------------------------------
    wire [NUM_INPUTS - 1 : 0]      request;
    wire [NUM_INPUTS - 1 : 0]      request;
    wire [NUM_INPUTS - 1 : 0]      valid;
    wire [NUM_INPUTS - 1 : 0]      valid;
    wire [NUM_INPUTS - 1 : 0]      grant;
    wire [NUM_INPUTS - 1 : 0]      grant;
    wire [NUM_INPUTS - 1 : 0]      next_grant;
    wire [NUM_INPUTS - 1 : 0]      next_grant;
    reg [NUM_INPUTS - 1 : 0]       saved_grant;
    reg [NUM_INPUTS - 1 : 0]       saved_grant;
    reg [PAYLOAD_W - 1 : 0]        src_payload;
    reg [PAYLOAD_W - 1 : 0]        src_payload;
    wire                           last_cycle;
    wire                           last_cycle;
    reg                            packet_in_progress;
    reg                            packet_in_progress;
    reg                            update_grant;
    reg                            update_grant;
    wire [PAYLOAD_W - 1 : 0] sink0_payload;
    wire [PAYLOAD_W - 1 : 0] sink0_payload;
    wire [PAYLOAD_W - 1 : 0] sink1_payload;
    wire [PAYLOAD_W - 1 : 0] sink1_payload;
    assign valid[0] = sink0_valid;
    assign valid[0] = sink0_valid;
    assign valid[1] = sink1_valid;
    assign valid[1] = sink1_valid;
    wire [NUM_INPUTS - 1 : 0] eop;
    wire [NUM_INPUTS - 1 : 0] eop;
    assign eop[0] = sink0_endofpacket;
    assign eop[0] = sink0_endofpacket;
    assign eop[1] = sink1_endofpacket;
    assign eop[1] = sink1_endofpacket;
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // Grant Logic & Updates
    // Grant Logic & Updates
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    reg [NUM_INPUTS - 1 : 0] lock;
    reg [NUM_INPUTS - 1 : 0] lock;
    always @* begin
    always @* begin
      lock[0] = sink0_data[70];
      lock[0] = sink0_data[70];
      lock[1] = sink1_data[70];
      lock[1] = sink1_data[70];
    end
    end
    reg [NUM_INPUTS - 1 : 0] locked = '0;
    reg [NUM_INPUTS - 1 : 0] locked = '0;
    always @(posedge clk or posedge reset) begin
    always @(posedge clk or posedge reset) begin
      if (reset) begin
      if (reset) begin
        locked <= '0;
        locked <= '0;
      end
      end
      else begin
      else begin
        locked <= next_grant & lock;
        locked <= next_grant & lock;
      end
      end
    end
    end
    assign last_cycle = src_valid & src_ready & src_endofpacket & ~(|(lock & grant));
    assign last_cycle = src_valid & src_ready & src_endofpacket & ~(|(lock & grant));
    // ------------------------------------------
    // ------------------------------------------
    // We're working on a packet at any time valid is high, except
    // We're working on a packet at any time valid is high, except
    // when this is the endofpacket.
    // when this is the endofpacket.
    // ------------------------------------------
    // ------------------------------------------
    always @(posedge clk or posedge reset) begin
    always @(posedge clk or posedge reset) begin
      if (reset) begin
      if (reset) begin
        packet_in_progress <= 1'b0;
        packet_in_progress <= 1'b0;
      end
      end
      else begin
      else begin
        if (last_cycle)
        if (last_cycle)
          packet_in_progress <= 1'b0;
          packet_in_progress <= 1'b0;
        else if (src_valid)
        else if (src_valid)
          packet_in_progress <= 1'b1;
          packet_in_progress <= 1'b1;
      end
      end
    end
    end
    // ------------------------------------------
    // ------------------------------------------
    // Shares
    // Shares
    //
    //
    // Special case: all-equal shares _should_ be optimized into assigning a
    // Special case: all-equal shares _should_ be optimized into assigning a
    // constant to next_grant_share.
    // constant to next_grant_share.
    // Special case: all-1's shares _should_ result in the share counter
    // Special case: all-1's shares _should_ result in the share counter
    // being optimized away.
    // being optimized away.
    // ------------------------------------------
    // ------------------------------------------
    // Input  |  arb shares  |  counter load value
    // Input  |  arb shares  |  counter load value
    // 0      |      1       |  0
    // 0      |      1       |  0
    // 1      |      1       |  0
    // 1      |      1       |  0
     wire [SHARE_COUNTER_W - 1 : 0] share_0 = 1'd0;
     wire [SHARE_COUNTER_W - 1 : 0] share_0 = 1'd0;
     wire [SHARE_COUNTER_W - 1 : 0] share_1 = 1'd0;
     wire [SHARE_COUNTER_W - 1 : 0] share_1 = 1'd0;
    // ------------------------------------------
    // ------------------------------------------
    // Choose the share value corresponding to the grant.
    // Choose the share value corresponding to the grant.
    // ------------------------------------------
    // ------------------------------------------
    reg [SHARE_COUNTER_W - 1 : 0] next_grant_share;
    reg [SHARE_COUNTER_W - 1 : 0] next_grant_share;
    always @* begin
    always @* begin
      next_grant_share =
      next_grant_share =
    share_0 & { SHARE_COUNTER_W {next_grant[0]} } |
    share_0 & { SHARE_COUNTER_W {next_grant[0]} } |
    share_1 & { SHARE_COUNTER_W {next_grant[1]} };
    share_1 & { SHARE_COUNTER_W {next_grant[1]} };
    end
    end
    // ------------------------------------------
    // ------------------------------------------
    // Flag to indicate first packet of an arb sequence.
    // Flag to indicate first packet of an arb sequence.
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // Compute the next share-count value.
    // Compute the next share-count value.
    // ------------------------------------------
    // ------------------------------------------
    reg [SHARE_COUNTER_W - 1 : 0] p1_share_count;
    reg [SHARE_COUNTER_W - 1 : 0] p1_share_count;
    reg [SHARE_COUNTER_W - 1 : 0] share_count;
    reg [SHARE_COUNTER_W - 1 : 0] share_count;
    reg share_count_zero_flag;
    reg share_count_zero_flag;
    always @* begin
    always @* begin
        // Update the counter, but don't decrement below 0.
        // Update the counter, but don't decrement below 0.
      p1_share_count = share_count_zero_flag ? '0 : share_count - 1'b1;
      p1_share_count = share_count_zero_flag ? '0 : share_count - 1'b1;
     end
     end
    // ------------------------------------------
    // ------------------------------------------
    // Update the share counter and share-counter=zero flag.
    // Update the share counter and share-counter=zero flag.
    // ------------------------------------------
    // ------------------------------------------
    always @(posedge clk or posedge reset) begin
    always @(posedge clk or posedge reset) begin
      if (reset) begin
      if (reset) begin
        share_count <= '0;
        share_count <= '0;
        share_count_zero_flag <= 1'b1;
        share_count_zero_flag <= 1'b1;
      end
      end
      else begin
      else begin
        if (update_grant) begin
        if (update_grant) begin
          share_count <= next_grant_share;
          share_count <= next_grant_share;
          share_count_zero_flag <= (next_grant_share == '0);
          share_count_zero_flag <= (next_grant_share == '0);
        end
        end
        else if (last_cycle) begin
        else if (last_cycle) begin
          share_count <= p1_share_count;
          share_count <= p1_share_count;
          share_count_zero_flag <= (p1_share_count == '0);
          share_count_zero_flag <= (p1_share_count == '0);
        end
        end
      end
      end
    end
    end
    always @* begin
    always @* begin
      update_grant = 0;
      update_grant = 0;
        // ------------------------------------------
        // ------------------------------------------
        // The pipeline delays grant by one cycle, so
        // The pipeline delays grant by one cycle, so
        // we have to calculate the update_grant signal
        // we have to calculate the update_grant signal
        // one cycle ahead of time.
        // one cycle ahead of time.
        //
        //
        // Possible optimization: omit the first clause
        // Possible optimization: omit the first clause
        //    "if (!packet_in_progress & ~src_valid) ..."
        //    "if (!packet_in_progress & ~src_valid) ..."
        //   cost: one idle cycle at the the beginning of each
        //   cost: one idle cycle at the the beginning of each
        //     grant cycle.
        //     grant cycle.
        //   benefit: save a small amount of logic.
        //   benefit: save a small amount of logic.
        // ------------------------------------------
        // ------------------------------------------
    if (!packet_in_progress & !src_valid)
    if (!packet_in_progress & !src_valid)
      update_grant = 1;
      update_grant = 1;
    if (last_cycle && share_count_zero_flag)
    if (last_cycle && share_count_zero_flag)
      update_grant = 1;
      update_grant = 1;
    end
    end
    wire save_grant;
    wire save_grant;
    assign save_grant = update_grant;
    assign save_grant = update_grant;
    assign grant = saved_grant;
    assign grant = saved_grant;
    always @(posedge clk, posedge reset) begin
    always @(posedge clk, posedge reset) begin
      if (reset)
      if (reset)
        saved_grant <= '0;
        saved_grant <= '0;
      else if (save_grant)
      else if (save_grant)
        saved_grant <= next_grant;
        saved_grant <= next_grant;
    end
    end
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // Arbitrator
    // Arbitrator
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // Create a request vector that stays high during
    // Create a request vector that stays high during
    // the packet for unpipelined arbitration.
    // the packet for unpipelined arbitration.
    //
    //
    // The pipelined arbitration scheme does not require
    // The pipelined arbitration scheme does not require
    // request to be held high during the packet.
    // request to be held high during the packet.
    // ------------------------------------------
    // ------------------------------------------
    reg [NUM_INPUTS - 1 : 0] prev_request;
    reg [NUM_INPUTS - 1 : 0] prev_request;
    always @(posedge clk, posedge reset) begin
    always @(posedge clk, posedge reset) begin
      if (reset)
      if (reset)
        prev_request <= '0;
        prev_request <= '0;
      else
      else
        prev_request <= request & ~(valid & eop);
        prev_request <= request & ~(valid & eop);
    end
    end
    assign request = (PIPELINE_ARB == 1) ? valid | locked :
    assign request = (PIPELINE_ARB == 1) ? valid | locked :
    prev_request | valid | locked;
    prev_request | valid | locked;
    wire [NUM_INPUTS - 1 : 0] next_grant_from_arb;
    wire [NUM_INPUTS - 1 : 0] next_grant_from_arb;
    altera_merlin_arbitrator
    altera_merlin_arbitrator
    #(
    #(
    .NUM_REQUESTERS(NUM_INPUTS),
    .NUM_REQUESTERS(NUM_INPUTS),
    .SCHEME ("round-robin"),
    .SCHEME ("round-robin"),
    .PIPELINE (1)
    .PIPELINE (1)
    ) arb (
    ) arb (
    .clk (clk),
    .clk (clk),
    .reset (reset),
    .reset (reset),
    .request (request),
    .request (request),
    .grant (next_grant_from_arb),
    .grant (next_grant_from_arb),
    .save_top_priority (src_valid),
    .save_top_priority (src_valid),
    .increment_top_priority (update_grant)
    .increment_top_priority (update_grant)
    );
    );
   assign next_grant = next_grant_from_arb;
   assign next_grant = next_grant_from_arb;
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // Mux
    // Mux
    //
    //
    // Implemented as a sum of products.
    // Implemented as a sum of products.
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    // ------------------------------------------
    assign sink0_ready = src_ready && grant[0];
    assign sink0_ready = src_ready && grant[0];
    assign sink1_ready = src_ready && grant[1];
    assign sink1_ready = src_ready && grant[1];
    assign src_valid = |(grant & valid);
    assign src_valid = |(grant & valid);
    always @* begin
    always @* begin
      src_payload =
      src_payload =
      sink0_payload & {PAYLOAD_W {grant[0]} } |
      sink0_payload & {PAYLOAD_W {grant[0]} } |
      sink1_payload & {PAYLOAD_W {grant[1]} };
      sink1_payload & {PAYLOAD_W {grant[1]} };
    end
    end
    // ------------------------------------------
    // ------------------------------------------
    // Mux Payload Mapping
    // Mux Payload Mapping
    // ------------------------------------------
    // ------------------------------------------
    assign sink0_payload = {sink0_channel,sink0_data,
    assign sink0_payload = {sink0_channel,sink0_data,
    sink0_startofpacket,sink0_endofpacket};
    sink0_startofpacket,sink0_endofpacket};
    assign sink1_payload = {sink1_channel,sink1_data,
    assign sink1_payload = {sink1_channel,sink1_data,
    sink1_startofpacket,sink1_endofpacket};
    sink1_startofpacket,sink1_endofpacket};
    assign {src_channel,src_data,src_startofpacket,src_endofpacket} = src_payload;
    assign {src_channel,src_data,src_startofpacket,src_endofpacket} = src_payload;
endmodule
endmodule
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.