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

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [altera_de0_nano_soc/] [doc/] [Terasic/] [DE0_NANO_SOC/] [Demonstrations/] [FPGA/] [DE0_NANO_SOC_ADC/] [DE0_NANO_SOC_QSYS/] [synthesis/] [submodules/] [DE0_NANO_SOC_QSYS_mm_interconnect_0_cmd_mux.sv] - Blame information for rev 221

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 221 olivier.gi
// (C) 2001-2014 Altera Corporation. All rights reserved.
2
// Your use of Altera Corporation's design tools, logic functions and other
3
// software and tools, and its AMPP partner logic functions, and any output
4
// files any of the foregoing (including device programming or simulation
5
// files), and any associated documentation or information are expressly subject
6
// to the terms and conditions of the Altera Program License Subscription
7
// Agreement, Altera MegaCore Function License Agreement, or other applicable
8
// license agreement, including, without limitation, that your use is for the
9
// sole purpose of programming logic devices manufactured by Altera and sold by
10
// Altera or its authorized distributors.  Please refer to the applicable
11
// agreement for further details.
12
 
13
 
14
// $Id: //acds/rel/14.0/ip/merlin/altera_merlin_multiplexer/altera_merlin_multiplexer.sv.terp#1 $
15
// $Revision: #1 $
16
// $Date: 2014/02/16 $
17
// $Author: swbranch $
18
 
19
// ------------------------------------------
20
// Merlin Multiplexer
21
// ------------------------------------------
22
 
23
`timescale 1 ns / 1 ns
24
 
25
 
26
// ------------------------------------------
27
// Generation parameters:
28
//   output_name:         DE0_NANO_SOC_QSYS_mm_interconnect_0_cmd_mux
29
//   NUM_INPUTS:          2
30
//   ARBITRATION_SHARES:  1 1
31
//   ARBITRATION_SCHEME   "round-robin"
32
//   PIPELINE_ARB:        1
33
//   PKT_TRANS_LOCK:      60 (arbitration locking enabled)
34
//   ST_DATA_W:           96
35
//   ST_CHANNEL_W:        6
36
// ------------------------------------------
37
 
38
module DE0_NANO_SOC_QSYS_mm_interconnect_0_cmd_mux
39
(
40
    // ----------------------
41
    // Sinks
42
    // ----------------------
43
    input                       sink0_valid,
44
    input [96-1   : 0]  sink0_data,
45
    input [6-1: 0]  sink0_channel,
46
    input                       sink0_startofpacket,
47
    input                       sink0_endofpacket,
48
    output                      sink0_ready,
49
 
50
    input                       sink1_valid,
51
    input [96-1   : 0]  sink1_data,
52
    input [6-1: 0]  sink1_channel,
53
    input                       sink1_startofpacket,
54
    input                       sink1_endofpacket,
55
    output                      sink1_ready,
56
 
57
 
58
    // ----------------------
59
    // Source
60
    // ----------------------
61
    output                      src_valid,
62
    output [96-1    : 0] src_data,
63
    output [6-1 : 0] src_channel,
64
    output                      src_startofpacket,
65
    output                      src_endofpacket,
66
    input                       src_ready,
67
 
68
    // ----------------------
69
    // Clock & Reset
70
    // ----------------------
71
    input clk,
72
    input reset
73
);
74
    localparam PAYLOAD_W        = 96 + 6 + 2;
75
    localparam NUM_INPUTS       = 2;
76
    localparam SHARE_COUNTER_W  = 1;
77
    localparam PIPELINE_ARB     = 1;
78
    localparam ST_DATA_W        = 96;
79
    localparam ST_CHANNEL_W     = 6;
80
    localparam PKT_TRANS_LOCK   = 60;
81
 
82
    // ------------------------------------------
83
    // Signals
84
    // ------------------------------------------
85
    wire [NUM_INPUTS - 1 : 0] request;
86
    wire [NUM_INPUTS - 1 : 0] valid;
87
    wire [NUM_INPUTS - 1 : 0] grant;
88
    wire [NUM_INPUTS - 1 : 0] next_grant;
89
    reg  [NUM_INPUTS - 1 : 0] saved_grant;
90
    reg  [PAYLOAD_W - 1 : 0]  src_payload;
91
    wire                      last_cycle;
92
    reg                       packet_in_progress;
93
    reg                       update_grant;
94
 
95
    wire [PAYLOAD_W - 1 : 0]  sink0_payload;
96
    wire [PAYLOAD_W - 1 : 0]  sink1_payload;
97
 
98
    assign valid[0] = sink0_valid;
99
    assign valid[1] = sink1_valid;
100
 
101
   wire [NUM_INPUTS - 1 : 0] eop;
102
      assign eop[0]   = sink0_endofpacket;
103
      assign eop[1]   = sink1_endofpacket;
104
 
105
    // ------------------------------------------
106
    // ------------------------------------------
107
    // Grant Logic & Updates
108
    // ------------------------------------------
109
    // ------------------------------------------
110
    reg [NUM_INPUTS - 1 : 0] lock;
111
    always @* begin
112
      lock[0] = sink0_data[60];
113
      lock[1] = sink1_data[60];
114
    end
115
    reg [NUM_INPUTS - 1 : 0] locked = '0;
116
    always @(posedge clk or posedge reset) begin
117
      if (reset) begin
118
        locked <= '0;
119
      end
120
      else begin
121
        locked <= next_grant & lock;
122
      end
123
    end
124
 
125
    assign last_cycle = src_valid & src_ready & src_endofpacket & ~(|(lock & grant));
126
 
127
    // ------------------------------------------
128
    // We're working on a packet at any time valid is high, except
129
    // when this is the endofpacket.
130
    // ------------------------------------------
131
    always @(posedge clk or posedge reset) begin
132
        if (reset) begin
133
            packet_in_progress <= 1'b0;
134
        end
135
        else begin
136
            if (last_cycle)
137
                packet_in_progress <= 1'b0;
138
            else if (src_valid)
139
                packet_in_progress <= 1'b1;
140
        end
141
    end
142
 
143
 
144
    // ------------------------------------------
145
    // Shares
146
    //
147
    // Special case: all-equal shares _should_ be optimized into assigning a
148
    // constant to next_grant_share.
149
    // Special case: all-1's shares _should_ result in the share counter
150
    // being optimized away.
151
    // ------------------------------------------
152
    // Input  |  arb shares  |  counter load value
153
    // 0      |      1       |  0
154
    // 1      |      1       |  0
155
    wire [SHARE_COUNTER_W - 1 : 0] share_0 = 1'd0;
156
    wire [SHARE_COUNTER_W - 1 : 0] share_1 = 1'd0;
157
 
158
    // ------------------------------------------
159
    // Choose the share value corresponding to the grant.
160
    // ------------------------------------------
161
    reg [SHARE_COUNTER_W - 1 : 0] next_grant_share;
162
    always @* begin
163
        next_grant_share =
164
            share_0 & { SHARE_COUNTER_W {next_grant[0]} } |
165
            share_1 & { SHARE_COUNTER_W {next_grant[1]} };
166
    end
167
 
168
    // ------------------------------------------
169
    // Flag to indicate first packet of an arb sequence.
170
    // ------------------------------------------
171
 
172
    // ------------------------------------------
173
    // Compute the next share-count value.
174
    // ------------------------------------------
175
    reg [SHARE_COUNTER_W - 1 : 0] p1_share_count;
176
    reg [SHARE_COUNTER_W - 1 : 0] share_count;
177
    reg share_count_zero_flag;
178
 
179
    always @* begin
180
        // Update the counter, but don't decrement below 0.
181
        p1_share_count = share_count_zero_flag ? '0 : share_count - 1'b1;
182
    end
183
 
184
    // ------------------------------------------
185
    // Update the share counter and share-counter=zero flag.
186
    // ------------------------------------------
187
    always @(posedge clk or posedge reset) begin
188
        if (reset) begin
189
            share_count <= '0;
190
            share_count_zero_flag <= 1'b1;
191
        end
192
        else begin
193
            if (update_grant) begin
194
                share_count <= next_grant_share;
195
                share_count_zero_flag <= (next_grant_share == '0);
196
            end
197
            else if (last_cycle) begin
198
                share_count <= p1_share_count;
199
                share_count_zero_flag <= (p1_share_count == '0);
200
            end
201
        end
202
    end
203
 
204
 
205
    always @* begin
206
        update_grant = 0;
207
 
208
        // ------------------------------------------
209
        // The pipeline delays grant by one cycle, so
210
        // we have to calculate the update_grant signal
211
        // one cycle ahead of time.
212
        //
213
        // Possible optimization: omit the first clause
214
        //    "if (!packet_in_progress & ~src_valid) ..."
215
        //   cost: one idle cycle at the the beginning of each
216
        //     grant cycle.
217
        //   benefit: save a small amount of logic.
218
        // ------------------------------------------
219
        if (!packet_in_progress & !src_valid)
220
            update_grant = 1;
221
        if (last_cycle && share_count_zero_flag)
222
            update_grant = 1;
223
    end
224
 
225
    wire save_grant;
226
    assign save_grant = update_grant;
227
    assign grant      = saved_grant;
228
 
229
    always @(posedge clk, posedge reset) begin
230
        if (reset)
231
            saved_grant <= '0;
232
        else if (save_grant)
233
            saved_grant <= next_grant;
234
    end
235
 
236
    // ------------------------------------------
237
    // ------------------------------------------
238
    // Arbitrator
239
    // ------------------------------------------
240
    // ------------------------------------------
241
 
242
    // ------------------------------------------
243
    // Create a request vector that stays high during
244
    // the packet for unpipelined arbitration.
245
    //
246
    // The pipelined arbitration scheme does not require
247
    // request to be held high during the packet.
248
    // ------------------------------------------
249
    reg  [NUM_INPUTS - 1 : 0] prev_request;
250
    always @(posedge clk, posedge reset) begin
251
        if (reset)
252
            prev_request <= '0;
253
        else
254
            prev_request <= request & ~(valid & eop);
255
    end
256
 
257
    assign request = (PIPELINE_ARB == 1) ? valid | locked :
258
                                           prev_request | valid | locked;
259
 
260
 
261
    altera_merlin_arbitrator
262
    #(
263
        .NUM_REQUESTERS(NUM_INPUTS),
264
        .SCHEME        ("round-robin"),
265
        .PIPELINE      (1)
266
    ) arb (
267
        .clk                    (clk),
268
        .reset                  (reset),
269
        .request                (request),
270
        .grant                  (next_grant),
271
        .save_top_priority      (src_valid),
272
        .increment_top_priority (update_grant)
273
    );
274
 
275
    // ------------------------------------------
276
    // ------------------------------------------
277
    // Mux
278
    //
279
    // Implemented as a sum of products.
280
    // ------------------------------------------
281
    // ------------------------------------------
282
 
283
    assign sink0_ready = src_ready && grant[0];
284
    assign sink1_ready = src_ready && grant[1];
285
 
286
    assign src_valid = |(grant & valid);
287
 
288
    always @* begin
289
        src_payload =
290
            sink0_payload & {PAYLOAD_W {grant[0]} } |
291
            sink1_payload & {PAYLOAD_W {grant[1]} };
292
    end
293
 
294
    // ------------------------------------------
295
    // Mux Payload Mapping
296
    // ------------------------------------------
297
 
298
    assign sink0_payload = {sink0_channel,sink0_data,
299
        sink0_startofpacket,sink0_endofpacket};
300
    assign sink1_payload = {sink1_channel,sink1_data,
301
        sink1_startofpacket,sink1_endofpacket};
302
 
303
    assign {src_channel,src_data,src_startofpacket,src_endofpacket} = src_payload;
304
endmodule
305
 
306
 
307
 

powered by: WebSVN 2.1.0

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