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

Subversion Repositories async_sdm_noc

[/] [async_sdm_noc/] [trunk/] [sdm/] [src/] [input_buf.v] - Blame information for rev 28

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
 
28
*/
29
 
30
// the router structure definitions
31
`include "define.v"
32
 
33
module inp_buf (/*AUTOARG*/
34
   // Outputs
35
   o0, o1, o2, o3, o4, ia, arb_r,
36
   // Inputs
37
   rst_n, i0, i1, i2, i3, i4, oa, addrx, addry, arb_ra
38
   );
39
 
40
   //-------------------------- parameters ---------------------------------------//
41
   parameter DIR = 0;              // the port direction: south, west, north, east, and local
42
   parameter RN = 4;               // the number of request outputs, must match the direction
43
   parameter DW = 16;              // the data-width of the data-path
44
   parameter PD = 2;               // the depth of the input buffer
45
   parameter SCN = DW/2;
46
 
47
   //-------------------------- I/O ports ---------------------------------------//
48
   input                  rst_n;          // global reset, active low
49
   input [SCN-1:0]         i0, i1, i2, i3; // data input
50
   output [SCN-1:0]        o0, o1, o2, o3; // data output
51
`ifdef ENABLE_CHANNEL_SLICING
52
   input [SCN-1:0]         i4, oa;
53
   output [SCN-1:0]        o4, ia;
54
`else
55
   input                  i4, oa;
56
   output                 o4, ia;
57
`endif
58
   input [7:0]             addrx, addry;
59
   output [RN-1:0]         arb_r;
60
   input                  arb_ra;
61
 
62
   //-------------------------- control signals ---------------------------------------//
63
   wire                   rten;                // routing enable
64
   wire                   frame_end;           // identify the end of a frame
65
   wire [7:0]              pipe_xd, pipe_yd;    // the target address from the incoming frame
66
   wire [PD:0][SCN-1:0]   pd0, pd1, pd2, pd3;  // data wires for the internal pipeline satges
67
   wire [5:0]              raw_dec;             // the routing decision from the comparator
68
   wire [4:0]              dec_reg;             // the routing decision kept by C-gates
69
   wire                   x_equal;             // addr x = target x
70
   wire                   rt_err;              // route decoder error
71
   wire                   rt_ack;              // route build ack
72
 
73
`ifdef ENABLE_CHANNEL_SLICING
74
   wire [SCN-1:0]          rtrst;               // rt decoder reset for each sub-channel
75
   wire [PD:0][SCN-1:0]   pd4, pda, pdan;      // data wires for the internal pipeline stages
76
 
77
`else
78
   wire                   rtrst;               // rt decode reset
79
   wire [PD:0]             pd4, pda, pdan;      // data wires for the internal pipeline satges
80
`endif // !`ifdef ENABLE_CHANNEL_SLICING
81
 
82
   genvar                 i, j;
83
 
84
   //------------------------- pipelines ------------------------------------- //
85
   generate for(i=0; i<PD; i++) begin: DP
86
`ifdef ENABLE_CHANNEL_SLICING
87
      for(j=0; j<SCN; j++) begin: SC
88
         pipe4 #(.DW(2))
89
         P (
90
            .o0  ( pd0[i][j]   ),
91
            .o1  ( pd1[i][j]   ),
92
            .o2  ( pd2[i][j]   ),
93
            .o3  ( pd3[i][j]   ),
94
            .o4  ( pd4[i][j]   ),
95
            .ia  ( pda[i+1][j] ),
96
            .i0  ( pd0[i+1][j] ),
97
            .i1  ( pd1[i+1][j] ),
98
            .i2  ( pd2[i+1][j] ),
99
            .i3  ( pd3[i+1][j] ),
100
            .i4  ( pd4[i+1][j] ),
101
            .oa  ( pdan[i][j]  )
102
            );
103
      end // block: SC
104
 
105
`else // !`ifdef ENABLE_CHANNEL_SLICING
106
      pipe4 #(.DW(DW))
107
      P (
108
         .o0  ( pd0[i]   ),
109
         .o1  ( pd1[i]   ),
110
         .o2  ( pd2[i]   ),
111
         .o3  ( pd3[i]   ),
112
         .o4  ( pd4[i]   ),
113
         .ia  ( pda[i+1] ),
114
         .i0  ( pd0[i+1] ),
115
         .i1  ( pd1[i+1] ),
116
         .i2  ( pd2[i+1] ),
117
         .i3  ( pd3[i+1] ),
118
         .i4  ( pd4[i+1] ),
119
         .oa  ( pdan[i]  )
120
         );
121
`endif // !`ifdef ENABLE_CHANNEL_SLICING
122
   end // block: DP
123
   endgenerate
124
 
125
   generate for(i=1; i<PD; i++) begin: DPA
126
      assign pdan[i] = rst_n ? ~(pda[i]|pd4[i-1]) : 0;
127
   end
128
   endgenerate
129
 
130
   assign ia = pda[PD]|pd4[PD-1];
131
   assign pd0[PD] = i0;
132
   assign pd1[PD] = i1;
133
   assign pd2[PD] = i2;
134
   assign pd3[PD] = i3;
135
   assign pd4[PD] = i4;
136
   assign o0 = pd0[0];
137
   assign o1 = pd1[0];
138
   assign o2 = pd2[0];
139
   assign o3 = pd3[0];
140
   assign o4 = pd4[0];
141
 
142
   //---------------------------- route decoder related -------------------------- //
143
   // fetch the x and y target
144
   and Px_0 (pipe_xd[0], rten, pd0[1][0]);
145
   and Px_1 (pipe_xd[1], rten, pd1[1][0]);
146
   and Px_2 (pipe_xd[2], rten, pd2[1][0]);
147
   and Px_3 (pipe_xd[3], rten, pd3[1][0]);
148
   and Px_4 (pipe_xd[4], rten, pd0[1][1]);
149
   and Px_5 (pipe_xd[5], rten, pd1[1][1]);
150
   and Px_6 (pipe_xd[6], rten, pd2[1][1]);
151
   and Px_7 (pipe_xd[7], rten, pd3[1][1]);
152
   and Py_0 (pipe_yd[0], rten, pd0[1][2]);
153
   and Py_1 (pipe_yd[1], rten, pd1[1][2]);
154
   and Py_2 (pipe_yd[2], rten, pd2[1][2]);
155
   and Py_3 (pipe_yd[3], rten, pd3[1][2]);
156
   and Py_4 (pipe_yd[4], rten, pd0[1][3]);
157
   and Py_5 (pipe_yd[5], rten, pd1[1][3]);
158
   and Py_6 (pipe_yd[6], rten, pd2[1][3]);
159
   and Py_7 (pipe_yd[7], rten, pd3[1][3]);
160
 
161
 
162
   routing_decision      // the comparator
163
   RTD(
164
       .addrx      ( addrx   )
165
       ,.addry     ( addry   )
166
       ,.pipe_xd   ( pipe_xd )
167
       ,.pipe_yd   ( pipe_yd )
168
       ,.decision  ( raw_dec )
169
       );
170
 
171
   // keep the routing decision until the tail flit is received by all sub-channels
172 28 wsong0210
   c2p C_RTD0  ( .b(raw_dec[0]),      .a((~frame_end)&rst_n),    .q(dec_reg[0]));
173
   c2p C_RTD1  ( .b(raw_dec[1]),      .a((~frame_end)&rst_n),    .q(dec_reg[1]));
174
   c2p C_RT_XEQ (.b(raw_dec[2]),      .a((~frame_end)&rst_n),    .q(x_equal) );
175
   c2p C_RTD2  ( .b(raw_dec[3]),      .a(x_equal),               .q(dec_reg[2]));
176
   c2p C_RTD3  ( .b(raw_dec[4]),      .a(x_equal),               .q(dec_reg[3]));
177
   c2p C_RTD4  ( .b(raw_dec[5]),      .a(x_equal),               .q(dec_reg[4]));
178 16 wsong0210
 
179
   // generate the arbiter request signals
180
   assign arb_r =
181
                  DIR == 0 ? {dec_reg[4],dec_reg[2],dec_reg[1],dec_reg[3]} :   // south port
182
                  DIR == 1 ? {dec_reg[4],dec_reg[2]}                       :   // west port
183
                  DIR == 2 ? {dec_reg[4],dec_reg[2],dec_reg[3],dec_reg[0]} :   // north port
184
                  DIR == 3 ? {dec_reg[4],dec_reg[3]}                       :   // east port
185
                             {dec_reg[2],dec_reg[1],dec_reg[3],dec_reg[0]} ;   // local port
186
 
187
 
188
   assign rt_err =
189
                  DIR == 0 ? |{dec_reg[0]}                        :   // south port
190
                  DIR == 1 ? |{dec_reg[0],dec_reg[1],dec_reg[3]}  :   // west port
191
                  DIR == 2 ? |{dec_reg[1]}                        :   // north port
192
                  DIR == 3 ? |{dec_reg[0],dec_reg[1],dec_reg[2]}  :   // east port
193
                             |{dec_reg[4]}                        ;   // local port
194
 
195
   or IP_RTACK (rt_ack, rt_err, arb_ra);
196
 
197
   // ------------------------ pipeline control ------------------------------ //
198
 
199
`ifdef ENABLE_CHANNEL_SLICING
200
   for(j=0; j<SCN; j++) begin: SC
201
      // the sub-channel controller
202
      subc_ctl SCH_C (
203
                      .nack     ( pdan[0][j]  ),
204
                      .rt_rst   ( rtrst[j]    ),
205
                      .ai2cb    ( oa[j]       ),
206
                      .ack      ( pda[1][j]   ),
207
                      .eof      ( pd4[0][j]   ),
208
                      .rt_ra    ( rt_ack      ),
209
                      .rt_err   ( rt_err      ),
210
                      .rst_n    ( rst_n       )
211
                      );
212
   end // block: SC
213
`else // !`ifdef ENABLE_CHANNEL_SLICING
214
   subc_ctl SCH_C (
215
                   .nack     ( pdan[0]  ),
216
                   .rt_rst   ( rtrst    ),
217
                   .ai2cb    ( oa       ),
218
                   .ack      ( pda[1]   ),
219
                   .eof      ( pd4[0]   ),
220
                   .rt_ra    ( rt_ack   ),
221
                   .rt_err   ( rt_err   ),
222
                   .rst_n    ( rst_n    )
223
                   );
224
`endif // !`ifdef ENABLE_CHANNEL_SLICING
225
 
226
   // the router controller part
227
   assign rten = ~rt_ack;
228
   assign frame_end = &rtrst;
229
 
230
endmodule // inp_buf
231
 
232
 
233
// the routing decision making procedure, comparitors
234
module routing_decision (
235
                         addrx
236
                         ,addry
237
                         ,pipe_xd
238
                         ,pipe_yd
239
                         ,decision
240
                         );
241
 
242
   // compare with (2,3)
243
   input [7:0] addrx;
244
   input [7:0] addry;
245
 
246
   input   [7:0]   pipe_xd;
247
   input [7:0]      pipe_yd;
248
   output [5:0]    decision;
249
 
250
   wire [2:0]       x_cmp [1:0];
251
   wire [2:0]       y_cmp [1:0];
252
 
253
   chain_comparator X0 ( .a(pipe_xd[3:0]), .b(addrx[3:0]), .q(x_cmp[0]));
254
   chain_comparator X1 ( .a(pipe_xd[7:4]), .b(addrx[7:4]), .q(x_cmp[1]));
255
   chain_comparator Y0 ( .a(pipe_yd[3:0]), .b(addry[3:0]), .q(y_cmp[0]));
256
   chain_comparator Y1 ( .a(pipe_yd[7:4]), .b(addry[7:4]), .q(y_cmp[1]));
257
 
258
   assign decision[0] = x_cmp[1][0] | (x_cmp[1][2]&x_cmp[0][0]);       // frame x > addr x
259
   assign decision[1] = x_cmp[1][1] | (x_cmp[1][2]&x_cmp[0][1]);       // frame x < addr x
260
   assign decision[2] = x_cmp[1][2] & x_cmp[0][2];                     // frame x = addr x
261
   assign decision[3] = y_cmp[1][0] | (y_cmp[1][2]&y_cmp[0][0]);       // frame y > addr y
262
   assign decision[4] = y_cmp[1][1] | (y_cmp[1][2]&y_cmp[0][1]);       // frame y < addr y
263
   assign decision[5] = y_cmp[1][2] & y_cmp[0][2];                     // frame y = addr y
264
 
265
endmodule // routing_decision
266
 
267
 
268
// the 1-of-4 comparator
269
module chain_comparator (
270
     a
271
    ,b
272
    ,q
273
    );
274
 
275
   input   [3:0]   a;
276
   input [3:0]      b;
277
   output [2:0]    q;
278
 
279
   // a > b
280
   assign q[0] = (a[3]&(|b[2:0])) | (a[2]&(|b[1:0])) | (a[1]&(|b[0:0]));
281
 
282
   // a < b
283
   assign q[1] = (a[2]&(|b[3:3])) | (a[1]&(|b[3:2])) | (a[0]&(|b[3:1]));
284
 
285
   // a = b
286
   assign q[2] = (a[3]&b[3]) | (a[2]&b[2]) | (a[1]&b[1]) | (a[0]&b[0]);
287
 
288
endmodule // chain_comparator

powered by: WebSVN 2.1.0

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