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

Subversion Repositories async_sdm_noc

[/] [async_sdm_noc/] [branches/] [clos_opt/] [clos_opt/] [src/] [input_buf.v] - Blame information for rev 74

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 wsong0210
/*
2
 Asynchronous SDM NoC
3
 (C)2011 Wei Song
4
 Advanced Processor Technologies Group
5
 Computer Science, the Univ. of Manchester, UK
6
 
7
 Authors:
8
 Wei Song     wsong83@gmail.com
9
 
10
 License: LGPL 3.0 or later
11
 
12
 Input buffer for Wormhole/SDM routers.
13
 *** SystemVerilog is used ***
14
 
15
 References
16
 * Lookahead pipelines
17 17 wsong0210
     Montek Singh and Steven M. Nowick, The design of high-performance dynamic asynchronous pipelines: lookahead style, IEEE Transactions on Very Large Scale Integration (VLSI) Systems, 2007(15), 1256-1269. doi:10.1109/TVLSI.2007.902205
18 16 wsong0210
 * Channel slicing
19
     Wei Song and Doug Edwards, A low latency wormhole router for asynchronous on-chip networks, Asia and South Pacific Design Automation Conference, 2010, 437-443.
20
 * SDM
21
     Wei Song and Doug Edwards, Asynchronous spatial division multiplexing router, Microprocessors and Microsystems, 2011(35), 85-97.
22
 
23
 History:
24
 05/05/2009  Initial version. <wsong83@gmail.com>
25
 20/09/2010  Supporting channel slicing and SDM using macro difinitions. <wsong83@gmail.com>
26
 24/05/2011  Clean up for opensource. <wsong83@gmail.com>
27 47 wsong0210
 01/06/2011  Use the comp4 common comparator rather than the chain_comparator defined in this module. <wsong83@gmail.com>
28 62 wsong0210
 21/06/2011  Move the eof logic in every pipeline stage outside the pipe4 module. <wsong83@gmail.com>
29 72 wsong0210
 12/07/2011  Preparation for the buffered Clos switch. <wsong83@gmail.com>
30
 
31 16 wsong0210
*/
32
 
33
// the router structure definitions
34
`include "define.v"
35
 
36
module inp_buf (/*AUTOARG*/
37
   // Outputs
38 72 wsong0210
   o0, o1, o2, o3, o4, ia, deco,
39 16 wsong0210
   // Inputs
40 72 wsong0210
   rst_n, i0, i1, i2, i3, i4, oa, addrx, addry
41 16 wsong0210
   );
42
 
43
   //-------------------------- parameters ---------------------------------------//
44
   parameter DIR = 0;              // the port direction: south, west, north, east, and local
45
   parameter RN = 4;               // the number of request outputs, must match the direction
46
   parameter DW = 16;              // the data-width of the data-path
47
   parameter PD = 2;               // the depth of the input buffer
48
   parameter SCN = DW/2;
49
 
50
   //-------------------------- I/O ports ---------------------------------------//
51
   input                  rst_n;          // global reset, active low
52
   input [SCN-1:0]         i0, i1, i2, i3; // data input
53
   output [SCN-1:0]        o0, o1, o2, o3; // data output
54
`ifdef ENABLE_CHANNEL_SLICING
55
   input [SCN-1:0]         i4, oa;
56
   output [SCN-1:0]        o4, ia;
57
`else
58
   input                  i4, oa;
59
   output                 o4, ia;
60
`endif
61 72 wsong0210
   input [7:0]             addrx, addry; // local addresses in 1-of-4 encoding
62
   output [RN-1:0]         deco; // the decoded routing requests
63 16 wsong0210
 
64
   //-------------------------- control signals ---------------------------------------//
65 73 wsong0210
   wire                   rta;                 // the ack of the dec reg pipeline stage
66 16 wsong0210
   wire                   frame_end;           // identify the end of a frame
67
   wire [7:0]              pipe_xd, pipe_yd;    // the target address from the incoming frame
68
   wire [PD:0][SCN-1:0]   pd0, pd1, pd2, pd3;  // data wires for the internal pipeline satges
69
   wire [5:0]              raw_dec;             // the routing decision from the comparator
70 73 wsong0210
   wire [5:0]              xy_dec;              // the routing decision of the XY routing algorithm
71 16 wsong0210
   wire [4:0]              dec_reg;             // the routing decision kept by C-gates
72
   wire                   x_equal;             // addr x = target x
73
   wire                   rt_err;              // route decoder error
74
 
75
`ifdef ENABLE_CHANNEL_SLICING
76 72 wsong0210
   wire [SCN-1:0]          deca; // the ack for routing requests
77 73 wsong0210
   wire [SCN-1:0]          pda1; // the ack for the 1st pipeline stage
78
   wire [SCN-1:0]          acko; // the ack from CB
79 62 wsong0210
   wire [PD:0][SCN-1:0]   pd4, pda, pdan, pd4an; // data wires for the internal pipeline stages
80 16 wsong0210
 
81
`else
82 72 wsong0210
   wire                   deca; // the ack for routing requests
83 73 wsong0210
   wire                   pda1; // the ack for the 1st pipeline stage
84
   wire                   acko; // the ack from CB
85 62 wsong0210
   wire [PD:0]             pd4, pda, pdan, pd4an; // data wires for the internal pipeline satges
86 16 wsong0210
`endif // !`ifdef ENABLE_CHANNEL_SLICING
87 72 wsong0210
   wire                   decan;
88 16 wsong0210
 
89
   genvar                 i, j;
90
 
91
   //------------------------- pipelines ------------------------------------- //
92
   generate for(i=0; i<PD; i++) begin: DP
93
`ifdef ENABLE_CHANNEL_SLICING
94
      for(j=0; j<SCN; j++) begin: SC
95
         pipe4 #(.DW(2))
96
         P (
97
            .o0  ( pd0[i][j]   ),
98
            .o1  ( pd1[i][j]   ),
99
            .o2  ( pd2[i][j]   ),
100
            .o3  ( pd3[i][j]   ),
101
            .ia  ( pda[i+1][j] ),
102
            .i0  ( pd0[i+1][j] ),
103
            .i1  ( pd1[i+1][j] ),
104
            .i2  ( pd2[i+1][j] ),
105
            .i3  ( pd3[i+1][j] ),
106
            .oa  ( pdan[i][j]  )
107
            );
108 62 wsong0210
 
109
         pipen #(.DW(1))
110
         PEoF (
111
               .d_in_a  (             ),
112
               .d_out   ( pd4[i][j]   ),
113
               .d_in    ( pd4[i+1][j] ),
114
               .d_out_a ( pd4an[i][j] )
115
               );
116
 
117 16 wsong0210
      end // block: SC
118
 
119
`else // !`ifdef ENABLE_CHANNEL_SLICING
120
      pipe4 #(.DW(DW))
121
      P (
122
         .o0  ( pd0[i]   ),
123
         .o1  ( pd1[i]   ),
124
         .o2  ( pd2[i]   ),
125
         .o3  ( pd3[i]   ),
126
         .ia  ( pda[i+1] ),
127
         .i0  ( pd0[i+1] ),
128
         .i1  ( pd1[i+1] ),
129
         .i2  ( pd2[i+1] ),
130
         .i3  ( pd3[i+1] ),
131
         .oa  ( pdan[i]  )
132
         );
133 62 wsong0210
 
134
      pipen #(.DW(1))
135
      PEoF (
136
            .d_in_a  (          ),
137
            .d_out   ( pd4[i]   ),
138
            .d_in    ( pd4[i+1] ),
139
            .d_out_a ( pd4an[i] )
140
            );
141
 
142 16 wsong0210
`endif // !`ifdef ENABLE_CHANNEL_SLICING
143
   end // block: DP
144
   endgenerate
145
 
146 74 wsong0210
   generate
147
      for(i=2; i<PD; i++) begin: DPA
148
         assign pdan[i] = rst_n ? ~(pda[i]|pd4[i-1]) : 0;
149
         assign pd4an[i] = pdan[i];
150
      end
151 73 wsong0210
 
152 74 wsong0210
      // in case only one pipeline stage is configured
153 73 wsong0210
      if(PD>1)
154
        assign ia = pda[PD]|pd4[PD-1];
155
      else
156
        assign ia = pda1;
157
 
158 16 wsong0210
   endgenerate
159
 
160 73 wsong0210
   //assign ia = pda[PD]|pd4[PD-1];
161 16 wsong0210
   assign pd0[PD] = i0;
162
   assign pd1[PD] = i1;
163
   assign pd2[PD] = i2;
164
   assign pd3[PD] = i3;
165
   assign pd4[PD] = i4;
166
   assign o0 = pd0[0];
167
   assign o1 = pd1[0];
168
   assign o2 = pd2[0];
169
   assign o3 = pd3[0];
170
   assign o4 = pd4[0];
171
 
172
   //---------------------------- route decoder related -------------------------- //
173
   // fetch the x and y target
174 73 wsong0210
   and Px_0 (pipe_xd[0], ~rta, pd0[1][0]);
175
   and Px_1 (pipe_xd[1], ~rta, pd1[1][0]);
176
   and Px_2 (pipe_xd[2], ~rta, pd2[1][0]);
177
   and Px_3 (pipe_xd[3], ~rta, pd3[1][0]);
178
   and Px_4 (pipe_xd[4], ~rta, pd0[1][1]);
179
   and Px_5 (pipe_xd[5], ~rta, pd1[1][1]);
180
   and Px_6 (pipe_xd[6], ~rta, pd2[1][1]);
181
   and Px_7 (pipe_xd[7], ~rta, pd3[1][1]);
182
   and Py_0 (pipe_yd[0], ~rta, pd0[1][2]);
183
   and Py_1 (pipe_yd[1], ~rta, pd1[1][2]);
184
   and Py_2 (pipe_yd[2], ~rta, pd2[1][2]);
185
   and Py_3 (pipe_yd[3], ~rta, pd3[1][2]);
186
   and Py_4 (pipe_yd[4], ~rta, pd0[1][3]);
187
   and Py_5 (pipe_yd[5], ~rta, pd1[1][3]);
188
   and Py_6 (pipe_yd[6], ~rta, pd2[1][3]);
189
   and Py_7 (pipe_yd[7], ~rta, pd3[1][3]);
190 16 wsong0210
 
191
 
192
   routing_decision      // the comparator
193
   RTD(
194 74 wsong0210
       .addrx     ( addrx   ),
195
       .addry     ( addry   ),
196
       .pipe_xd   ( pipe_xd ),
197
       .pipe_yd   ( pipe_yd ),
198
       .decision  ( raw_dec )
199 16 wsong0210
       );
200
 
201 73 wsong0210
   // translate it into the XY dec; not QDI here as the circuit can be slow
202
   assign xy_dec[1:0] = raw_dec[1:0];
203
   assign xy_dec[4:2] = raw_dec[2] ? raw_dec[5:3] : 0;
204
 
205
   // the decoded routing requests
206
   pipen #(.DW(RN))
207
   PDEC (
208
         .d_in_a  ( rta      ),
209
         .d_out   ( dec_reg  ),
210 74 wsong0210
         .d_in    ( xy_dec   ),
211
         .d_out_a ( decan    )
212 73 wsong0210
         );
213 16 wsong0210
 
214 74 wsong0210
   assign decan = ~(&deca);
215
 
216 16 wsong0210
   // generate the arbiter request signals
217 73 wsong0210
   assign deco =
218 16 wsong0210
                  DIR == 0 ? {dec_reg[4],dec_reg[2],dec_reg[1],dec_reg[3]} :   // south port
219
                  DIR == 1 ? {dec_reg[4],dec_reg[2]}                       :   // west port
220
                  DIR == 2 ? {dec_reg[4],dec_reg[2],dec_reg[3],dec_reg[0]} :   // north port
221
                  DIR == 3 ? {dec_reg[4],dec_reg[3]}                       :   // east port
222
                             {dec_reg[2],dec_reg[1],dec_reg[3],dec_reg[0]} ;   // local port
223
 
224
 
225
   assign rt_err =
226
                  DIR == 0 ? |{dec_reg[0]}                        :   // south port
227
                  DIR == 1 ? |{dec_reg[0],dec_reg[1],dec_reg[3]}  :   // west port
228
                  DIR == 2 ? |{dec_reg[1]}                        :   // north port
229
                  DIR == 3 ? |{dec_reg[0],dec_reg[1],dec_reg[2]}  :   // east port
230
                             |{dec_reg[4]}                        ;   // local port
231
 
232
   // ------------------------ pipeline control ------------------------------ //
233
 
234
`ifdef ENABLE_CHANNEL_SLICING
235
   for(j=0; j<SCN; j++) begin: SC
236
      // the sub-channel controller
237 73 wsong0210
      ppc SCH_C (
238
                 .deca     ( deca[j]    ),
239
                 .dia      ( pda1[j]    ),
240
                 .eof      ( pd4[0][j]  ),
241
                 .doa      ( acko[j]|(pda[0][j]&rt_err) ),  // to handle faulty frames
242
                 .dec      ( rta        )
243
                 );
244 74 wsong0210
 
245
      // the lookahead pipeline
246 73 wsong0210
 `ifdef ENABLE_LOOKAHEAD
247
      c2n CD (.q(acko[j]), .a(oa[j]), .b(pda[0][j])); // the C2N gate to avoid early withdrawal
248
 `else
249 74 wsong0210
      assign acko[j] = oa[j];
250 73 wsong0210
 `endif
251 74 wsong0210
 
252
      // the ack lines for the last two pipeline stages
253
      assign pdan[0][j] = (~oa[j])&rst_n;
254
      assign pda4n[0][j] = (~deca[j])&rst_n;
255
      assign pdan[1][j] = (~pda1[j])&rst_n;
256
      assign pda4n[1][j] = pdan[1][j];
257
 
258 16 wsong0210
   end // block: SC
259
`else // !`ifdef ENABLE_CHANNEL_SLICING
260 74 wsong0210
   ppc SCH_C (
261
              .deca     ( deca    ),
262
              .dia      ( pda1    ),
263
              .eof      ( pd4[0]  ),
264
              .doa      ( acko|(pda[0]&rt_err) ),  // to handle faulty frames
265
              .dec      ( rta     )
266
              );
267
 
268
   // the lookahead pipeline
269
 `ifdef ENABLE_LOOKAHEAD
270
   c2n CD (.q(acko), .a(oa), .b(pda[0])); // the C2N gate to avoid early withdrawal
271
 `else
272
   assign acko = oa;
273
 `endif
274
 
275
   // the ack lines for the last two pipeline stages
276
   assign pdan[0] = (~oa)&rst_n;
277
   assign pda4n[0] = (~deca)&rst_n;
278
   assign pdan[1] = (~pda1)&rst_n;
279
   assign pda4n[1] = pdan[1];
280
 
281 16 wsong0210
`endif // !`ifdef ENABLE_CHANNEL_SLICING
282
 
283 74 wsong0210
 
284 16 wsong0210
endmodule // inp_buf
285
 
286
 
287
// the routing decision making procedure, comparitors
288
module routing_decision (
289
                         addrx
290
                         ,addry
291
                         ,pipe_xd
292
                         ,pipe_yd
293
                         ,decision
294
                         );
295
 
296
   // compare with (2,3)
297
   input [7:0] addrx;
298
   input [7:0] addry;
299
 
300
   input   [7:0]   pipe_xd;
301
   input [7:0]      pipe_yd;
302
   output [5:0]    decision;
303
 
304
   wire [2:0]       x_cmp [1:0];
305
   wire [2:0]       y_cmp [1:0];
306
 
307 47 wsong0210
   comp4 X0 ( .a(pipe_xd[3:0]), .b(addrx[3:0]), .q(x_cmp[0]));
308
   comp4 X1 ( .a(pipe_xd[7:4]), .b(addrx[7:4]), .q(x_cmp[1]));
309
   comp4 Y0 ( .a(pipe_yd[3:0]), .b(addry[3:0]), .q(y_cmp[0]));
310
   comp4 Y1 ( .a(pipe_yd[7:4]), .b(addry[7:4]), .q(y_cmp[1]));
311 16 wsong0210
 
312
   assign decision[0] = x_cmp[1][0] | (x_cmp[1][2]&x_cmp[0][0]);       // frame x > addr x
313
   assign decision[1] = x_cmp[1][1] | (x_cmp[1][2]&x_cmp[0][1]);       // frame x < addr x
314
   assign decision[2] = x_cmp[1][2] & x_cmp[0][2];                     // frame x = addr x
315
   assign decision[3] = y_cmp[1][0] | (y_cmp[1][2]&y_cmp[0][0]);       // frame y > addr y
316
   assign decision[4] = y_cmp[1][1] | (y_cmp[1][2]&y_cmp[0][1]);       // frame y < addr y
317
   assign decision[5] = y_cmp[1][2] & y_cmp[0][2];                     // frame y = addr y
318
 
319
endmodule // routing_decision

powered by: WebSVN 2.1.0

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