1 /*****************************************************************************
2
3 Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4 more contributor license agreements. See the NOTICE file distributed
5 with this work for additional information regarding copyright ownership.
6 Accellera licenses this file to you under the Apache License, Version 2.0
7 (the "License"); you may not use this file except in compliance with the
8 License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 implied. See the License for the specific language governing
16 permissions and limitations under the License.
17
18 *****************************************************************************/
19
20 /*****************************************************************************
21
22 switch.cpp - This is the implementation file for the asynchronous process
23 "switch".
24
25 Original Author: Rashmi Goswami, Synopsys, Inc.
26
27 *****************************************************************************/
28
29 /*****************************************************************************
30
31 MODIFICATION LOG - modifiers, enter your name, affiliation, date and
32 changes you are making here.
33
34 Name, Affiliation, Date:
35 Description of Modification:
36
37 *****************************************************************************/
38
39 #include "systemc.h"
40 #include "pkt.h"
41 #include "switch.h"
42 #include "fifo.h"
43 #include "switch_reg.h"
44 #define SIM_NUM 500
45
entry()46 void mcast_pkt_switch :: entry()
47 {
48 wait();
49
50 // declarations
51 switch_reg R0;
52 switch_reg R1;
53 switch_reg R2;
54 switch_reg R3;
55 switch_reg temp;
56
57 int sim_count;
58 int pkt_count;
59 int drop_count;
60
61 fifo q0_in;
62 fifo q1_in;
63 fifo q2_in;
64 fifo q3_in;
65
66 fifo q0_out;
67 fifo q1_out;
68 fifo q2_out;
69 fifo q3_out;
70
71 // FILE *result;
72
73 // initialization
74 pkt_count = 0;
75 drop_count = 0;
76 sim_count = 0;
77
78 q0_in.pntr = 0;
79 q1_in.pntr = 0;
80 q2_in.pntr = 0;
81 q3_in.pntr = 0;
82
83 q0_out.pntr = 0;
84 q1_out.pntr = 0;
85 q2_out.pntr = 0;
86 q3_out.pntr = 0;
87
88 q0_in.full = false;
89 q1_in.full = false;
90 q2_in.full = false;
91 q3_in.full = false;
92
93 q0_in.empty = true;
94 q1_in.empty = true;
95 q2_in.empty = true;
96 q3_in.empty = true;
97
98 q0_out.full = false;
99 q1_out.full = false;
100 q2_out.full = false;
101 q3_out.full = false;
102
103 q0_out.empty = true;
104 q1_out.empty = true;
105 q2_out.empty = true;
106 q3_out.empty = true;
107
108 R0.free = true;
109 R1.free = true;
110 R2.free = true;
111 R3.free = true;
112
113 // result = fopen("result","w");
114
115 cout << endl;
116 cout << "-------------------------------------------------------------------------------" << endl;
117 cout << endl << " 4x4 Multicast Helix Packet Switch Simulation" << endl;
118 cout << "-------------------------------------------------------------------------------" << endl;
119 cout << " This is the simulation of a 4x4 non-blocking multicast helix packet switch. " << endl;
120 cout << " The switch uses a self-routing ring of shift registers to transfer cells " << endl;
121 cout << " from one port to another in a pipelined fashion, resolving output contention " << endl;
122 cout << " and handling multicast switch efficiently." << endl << endl;
123
124 wait();
125 // functionality
126 while( sim_count++ < SIM_NUM )
127 {
128 wait();
129
130 /////read input packets//////////////////////////////////
131 if (in0.event())
132 {
133 pkt_count++;
134 if (q0_in.full == true) drop_count++;
135 else q0_in.pkt_in(in0.read());
136 };
137
138 if (in1.event())
139 {
140 pkt_count++;
141 if (q1_in.full == true) drop_count++;
142 else q1_in.pkt_in(in1.read());
143 };
144
145 if (in2.event())
146 {
147 pkt_count++;
148 if (q2_in.full == true) drop_count++;
149 else q2_in.pkt_in(in2.read());
150 };
151
152 if (in3.event())
153 {
154 pkt_count++;
155 if (q3_in.full == true) drop_count++;
156 else q3_in.pkt_in(in3.read());
157 };
158
159 /////move the packets from fifo to shift register ring/////
160
161 if((!q0_in.empty) && R0.free)
162 {
163 R0.val = q0_in.pkt_out();
164 R0.free = false;
165 }
166
167 if((!q1_in.empty) && R1.free)
168 {
169 R1.val = q1_in.pkt_out();
170 R1.free = false;
171 }
172 if((!q2_in.empty) && R2.free)
173 {
174 R2.val = q2_in.pkt_out();
175 R2.free = false;
176 }
177 if((!q3_in.empty) && R3.free)
178 {
179 R3.val = q3_in.pkt_out();
180 R3.free = false;
181 }
182
183 if((bool)switch_cntrl && switch_cntrl.event())
184 {
185 /////shift the channel registers /////////////////////////
186 temp = R0;
187 R0 = R1;
188 R1 = R2;
189 R2 = R3;
190 R3 = temp;
191
192 /////write the register values to output fifos////////////
193 if ((!R0.free) && (R0.val.dest0) && (!q0_out.full))
194 {
195 q0_out.pkt_in(R0.val);
196 R0.val.dest0 = false;
197 if (!(R0.val.dest0|R0.val.dest1|R0.val.dest2|R0.val.dest3)) R0.free = true;
198 }
199
200 if ((!R1.free) && (R1.val.dest1) && (!q1_out.full))
201 {
202 q1_out.pkt_in(R1.val);
203 R1.val.dest1 = false;
204 if (!(R1.val.dest1|R1.val.dest1|R1.val.dest2|R1.val.dest3)) R1.free = true;
205 }
206 if ((!R2.free) && (R2.val.dest2) && (!q2_out.full))
207 {
208 q2_out.pkt_in(R2.val);
209 R2.val.dest2 = false;
210 if (!(R2.val.dest2|R2.val.dest1|R2.val.dest2|R2.val.dest3)) R2.free = true;
211 }
212 if ((!R3.free) && (R3.val.dest3) && (!q3_out.full))
213 {
214 q3_out.pkt_in(R3.val);
215 R3.val.dest3 = false;
216 if (!(R3.val.dest3|R3.val.dest1|R3.val.dest2|R3.val.dest3)) R3.free = true;
217 }
218
219 /////write the packets out//////////////////////////////////
220 if (!q0_out.empty) out0.write(q0_out.pkt_out());
221 if (!q1_out.empty) out1.write(q1_out.pkt_out());
222 if (!q2_out.empty) out2.write(q2_out.pkt_out());
223 if (!q3_out.empty) out3.write(q3_out.pkt_out());
224 }
225 }
226
227 sc_stop();
228
229 cout << endl << endl << "-------------------------------------------------------------------------------" << endl;
230 cout << "End of switch operation..." << endl;
231 cout << "Total number of packets received: " << pkt_count << endl;
232 cout << "Total number of packets dropped: " << drop_count << endl;
233 cout << "Percentage packets dropped: " << drop_count*100/pkt_count << endl;
234 cout << "-------------------------------------------------------------------------------" << endl;
235
236 }
237