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_rsp_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_rsp_mux
29
//   NUM_INPUTS:          2
30
//   ARBITRATION_SHARES:  1 1
31
//   ARBITRATION_SCHEME   "no-arb"
32
//   PIPELINE_ARB:        0
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_rsp_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     = 0;
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
 
102
    // ------------------------------------------
103
    // ------------------------------------------
104
    // Grant Logic & Updates
105
    // ------------------------------------------
106
    // ------------------------------------------
107
    reg [NUM_INPUTS - 1 : 0] lock;
108
    always @* begin
109
      lock[0] = sink0_data[60];
110
      lock[1] = sink1_data[60];
111
    end
112
 
113
    assign last_cycle = src_valid & src_ready & src_endofpacket & ~(|(lock & grant));
114
 
115
    // ------------------------------------------
116
    // We're working on a packet at any time valid is high, except
117
    // when this is the endofpacket.
118
    // ------------------------------------------
119
    always @(posedge clk or posedge reset) begin
120
        if (reset) begin
121
            packet_in_progress <= 1'b0;
122
        end
123
        else begin
124
            if (last_cycle)
125
                packet_in_progress <= 1'b0;
126
            else if (src_valid)
127
                packet_in_progress <= 1'b1;
128
        end
129
    end
130
 
131
 
132
    // ------------------------------------------
133
    // Shares
134
    //
135
    // Special case: all-equal shares _should_ be optimized into assigning a
136
    // constant to next_grant_share.
137
    // Special case: all-1's shares _should_ result in the share counter
138
    // being optimized away.
139
    // ------------------------------------------
140
    // Input  |  arb shares  |  counter load value
141
    // 0      |      1       |  0
142
    // 1      |      1       |  0
143
    wire [SHARE_COUNTER_W - 1 : 0] share_0 = 1'd0;
144
    wire [SHARE_COUNTER_W - 1 : 0] share_1 = 1'd0;
145
 
146
    // ------------------------------------------
147
    // Choose the share value corresponding to the grant.
148
    // ------------------------------------------
149
    reg [SHARE_COUNTER_W - 1 : 0] next_grant_share;
150
    always @* begin
151
        next_grant_share =
152
            share_0 & { SHARE_COUNTER_W {next_grant[0]} } |
153
            share_1 & { SHARE_COUNTER_W {next_grant[1]} };
154
    end
155
 
156
    // ------------------------------------------
157
    // Flag to indicate first packet of an arb sequence.
158
    // ------------------------------------------
159
    wire grant_changed = ~packet_in_progress && ~(|(saved_grant & valid));
160
    reg first_packet_r;
161
    wire first_packet = grant_changed | first_packet_r;
162
    always @(posedge clk or posedge reset) begin
163
        if (reset) begin
164
            first_packet_r <= 1'b0;
165
        end
166
        else begin
167
            if (update_grant)
168
                first_packet_r <= 1'b1;
169
            else if (last_cycle)
170
                first_packet_r <= 1'b0;
171
            else if (grant_changed)
172
                first_packet_r <= 1'b1;
173
        end
174
    end
175
 
176
    // ------------------------------------------
177
    // Compute the next share-count value.
178
    // ------------------------------------------
179
    reg [SHARE_COUNTER_W - 1 : 0] p1_share_count;
180
    reg [SHARE_COUNTER_W - 1 : 0] share_count;
181
    reg share_count_zero_flag;
182
 
183
    always @* begin
184
        if (first_packet) begin
185
            p1_share_count = next_grant_share;
186
        end
187
        else begin
188
            // Update the counter, but don't decrement below 0.
189
            p1_share_count = share_count_zero_flag ? '0 : share_count - 1'b1;
190
        end
191
    end
192
 
193
    // ------------------------------------------
194
    // Update the share counter and share-counter=zero flag.
195
    // ------------------------------------------
196
    always @(posedge clk or posedge reset) begin
197
        if (reset) begin
198
            share_count <= '0;
199
            share_count_zero_flag <= 1'b1;
200
        end
201
        else begin
202
            if (last_cycle) begin
203
                share_count <= p1_share_count;
204
                share_count_zero_flag <= (p1_share_count == '0);
205
            end
206
        end
207
    end
208
 
209
    // ------------------------------------------
210
    // For each input, maintain a final_packet signal which goes active for the
211
    // last packet of a full-share packet sequence.  Example: if I have 4
212
    // shares and I'm continuously requesting, final_packet is active in the
213
    // 4th packet.
214
    // ------------------------------------------
215
    wire final_packet_0 = 1'b1;
216
 
217
    wire final_packet_1 = 1'b1;
218
 
219
 
220
    // ------------------------------------------
221
    // Concatenate all final_packet signals (wire or reg) into a handy vector.
222
    // ------------------------------------------
223
    wire [NUM_INPUTS - 1 : 0] final_packet = {
224
        final_packet_1,
225
        final_packet_0
226
    };
227
 
228
    // ------------------------------------------
229
    // ------------------------------------------
230
    wire p1_done = |(final_packet & grant);
231
 
232
    // ------------------------------------------
233
    // Flag for the first cycle of packets within an
234
    // arb sequence
235
    // ------------------------------------------
236
    reg first_cycle;
237
    always @(posedge clk, posedge reset) begin
238
        if (reset)
239
            first_cycle <= 0;
240
        else
241
            first_cycle <= last_cycle && ~p1_done;
242
    end
243
 
244
 
245
    always @* begin
246
        update_grant = 0;
247
 
248
        // ------------------------------------------
249
        // No arbitration pipeline, update grant whenever
250
        // the current arb winner has consumed all shares,
251
        // or all requests are low
252
        // ------------------------------------------
253
        update_grant = (last_cycle && p1_done) || (first_cycle && ~(|valid));
254
        update_grant = last_cycle;
255
    end
256
 
257
    wire save_grant;
258
    assign save_grant = 1;
259
    assign grant      = next_grant;
260
 
261
    always @(posedge clk, posedge reset) begin
262
        if (reset)
263
            saved_grant <= '0;
264
        else if (save_grant)
265
            saved_grant <= next_grant;
266
    end
267
 
268
    // ------------------------------------------
269
    // ------------------------------------------
270
    // Arbitrator
271
    // ------------------------------------------
272
    // ------------------------------------------
273
 
274
    // ------------------------------------------
275
    // Create a request vector that stays high during
276
    // the packet for unpipelined arbitration.
277
    //
278
    // The pipelined arbitration scheme does not require
279
    // request to be held high during the packet.
280
    // ------------------------------------------
281
    assign request = valid;
282
 
283
 
284
    altera_merlin_arbitrator
285
    #(
286
        .NUM_REQUESTERS(NUM_INPUTS),
287
        .SCHEME        ("no-arb"),
288
        .PIPELINE      (0)
289
    ) arb (
290
        .clk                    (clk),
291
        .reset                  (reset),
292
        .request                (request),
293
        .grant                  (next_grant),
294
        .save_top_priority      (src_valid),
295
        .increment_top_priority (update_grant)
296
    );
297
 
298
    // ------------------------------------------
299
    // ------------------------------------------
300
    // Mux
301
    //
302
    // Implemented as a sum of products.
303
    // ------------------------------------------
304
    // ------------------------------------------
305
 
306
    assign sink0_ready = src_ready && grant[0];
307
    assign sink1_ready = src_ready && grant[1];
308
 
309
    assign src_valid = |(grant & valid);
310
 
311
    always @* begin
312
        src_payload =
313
            sink0_payload & {PAYLOAD_W {grant[0]} } |
314
            sink1_payload & {PAYLOAD_W {grant[1]} };
315
    end
316
 
317
    // ------------------------------------------
318
    // Mux Payload Mapping
319
    // ------------------------------------------
320
 
321
    assign sink0_payload = {sink0_channel,sink0_data,
322
        sink0_startofpacket,sink0_endofpacket};
323
    assign sink1_payload = {sink1_channel,sink1_data,
324
        sink1_startofpacket,sink1_endofpacket};
325
 
326
    assign {src_channel,src_data,src_startofpacket,src_endofpacket} = src_payload;
327
endmodule
328
 
329
 
330
 

powered by: WebSVN 2.1.0

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