1 | ---------------------------------------------------------------------------------- |
---|
2 | -- Company: |
---|
3 | -- Engineer: GAMOM |
---|
4 | -- |
---|
5 | -- Create Date: 14:44:36 03/07/2012 |
---|
6 | -- Design Name: |
---|
7 | -- Module Name: EX4_FSM - Behavioral |
---|
8 | -- Project Name: MPI_CORE_COMPONENTS |
---|
9 | -- Target Devices: SPARTAN 3E xc3s1200e |
---|
10 | -- Tool versions: |
---|
11 | -- Description: Ce module renferme les fonctions permettant d'initialiser la |
---|
12 | -- bibliothèque matériel MPI |
---|
13 | -- Dependencies: |
---|
14 | -- |
---|
15 | -- Revision: 25/juin/2012 au 24/Octobre/2012 |
---|
16 | -- Revision 0.03 - File updated |
---|
17 | -- Additional Comments: |
---|
18 | -- |
---|
19 | ---------------------------------------------------------------------------------- |
---|
20 | library IEEE; |
---|
21 | |
---|
22 | use IEEE.STD_LOGIC_1164.ALL; |
---|
23 | |
---|
24 | -- Uncomment the following library declaration if using |
---|
25 | -- arithmetic functions with Signed or Unsigned values |
---|
26 | use IEEE.NUMERIC_STD.ALL; |
---|
27 | Library NocLib; |
---|
28 | use NoCLib.CoreTypes.all; |
---|
29 | use work.packet_type.all; |
---|
30 | |
---|
31 | -- Uncomment the following library declaration if instantiating |
---|
32 | -- any Xilinx primitives in this code. |
---|
33 | --library UNISIM; |
---|
34 | --use UNISIM.VComponents.all; |
---|
35 | |
---|
36 | entity EX4_FSM is |
---|
37 | Port ( Instruction : in STD_LOGIC_VECTOR (Word-1 downto 0); |
---|
38 | Instruction_En : in STD_LOGIC; |
---|
39 | clk : in STD_LOGIC; |
---|
40 | reset : in STD_LOGIC; |
---|
41 | ResultOut : out STD_LOGIC_VECTOR (Word-1 downto 0):=(others=>'0'); |
---|
42 | Result_En : out STD_LOGIC:='0'; |
---|
43 | Ready : out STD_LOGIC; --indique que le module est disponible |
---|
44 | NocSize : out STD_LOGIC_VECTOR(3 downto 0); |
---|
45 | PortId : out STD_LOGIC_VECTOR(3 downto 0):=(others=>'0'); |
---|
46 | AppRank : out STD_LOGIC_VECTOR(3 downto 0):=(others=>'0'); |
---|
47 | AppSize : out STD_LOGIC_VECTOR(3 downto 0):=(others=>'0'); |
---|
48 | IsMain : out STD_LOGIC; |
---|
49 | I_fifo_full :in STD_LOGIC; --instruction fifo |
---|
50 | I_fifo_wr_en: out STD_LOGIC;--instruction fifo Write enable |
---|
51 | I_fifo_data_in :out STD_LOGIC_vector; --instruction fifo data |
---|
52 | Initialized : out STD_LOGIC; |
---|
53 | Snd_Ack : IN std_logic; |
---|
54 | Rec_Rdy : IN std_logic; |
---|
55 | Rec_Data : IN Typ_PortIO(0 to 3); |
---|
56 | Snd_data : OUT Typ_PortIO(0 to 3); |
---|
57 | Snd_Start : buffer std_logic; |
---|
58 | Rec_Ack : OUT std_logic; |
---|
59 | dma_wr_grant : in STD_LOGIC; |
---|
60 | dma_wr_request : out STD_LOGIC; |
---|
61 | dma_rd_grant : in STD_LOGIC; |
---|
62 | dma_rd_request : out STD_LOGIC; |
---|
63 | ram_rd : out std_logic; |
---|
64 | ram_wr : out std_logic; |
---|
65 | ram_address : out std_logic_vector(ADRLEN-1 downto 0);--accès au stockage |
---|
66 | Ram_data_in : out STD_LOGIC_VECTOR (Word-1 downto 0); |
---|
67 | Ram_data_out : in STD_LOGIC_VECTOR (Word-1 downto 0); |
---|
68 | |
---|
69 | AppAck : in STD_LOGIC; |
---|
70 | AppReq : in STD_LOGIC; |
---|
71 | port_in_cmd_en : out STD_LOGIC:='0'; |
---|
72 | port_in_wr_en : out STD_LOGIC:='0'; |
---|
73 | port_in_empty : in STD_LOGIC; |
---|
74 | port_in_full : in STD_LOGIC; |
---|
75 | port_in_data : out STD_LOGIC_VECTOR (Word-1 downto 0):=(others=>'-'); |
---|
76 | port_out_data : in STD_LOGIC_VECTOR (Word-1 downto 0); |
---|
77 | port_out_rd_en : out STD_LOGIC:='0'; |
---|
78 | port_out_data_available : in STD_LOGIC); |
---|
79 | end EX4_FSM; |
---|
80 | |
---|
81 | architecture Behavioral of EX4_FSM is |
---|
82 | |
---|
83 | COMPONENT SetBit |
---|
84 | PORT( |
---|
85 | clk : IN std_logic; |
---|
86 | reset : IN std_logic; |
---|
87 | BitNum : IN std_logic_vector(0 to 2); |
---|
88 | BitVal : IN std_logic; |
---|
89 | dma_wr_grant : IN std_logic; |
---|
90 | dma_rd_grant : IN std_logic; |
---|
91 | Ram_data_in : IN std_logic_vector(7 downto 0); |
---|
92 | |
---|
93 | dma_wr_request : OUT std_logic; |
---|
94 | dma_rd_request : OUT std_logic; |
---|
95 | ram_rd : OUT std_logic; |
---|
96 | ram_wr : OUT std_logic; |
---|
97 | ram_address : OUT std_logic_vector(15 downto 0); |
---|
98 | Ram_data_out : OUT std_logic_vector(7 downto 0) |
---|
99 | ); |
---|
100 | END COMPONENT; |
---|
101 | Type Ar_MPIPort_In is array (positive range <>) of Typ_MPIPort_in; |
---|
102 | Type Ar_MPIPort_out is array (positive range <>) of Typ_MPIPort_out; |
---|
103 | |
---|
104 | --MAE pour emission de init |
---|
105 | --type init1_type is (init,NocSize,InitToNoc,NextPort,EndBCast); |
---|
106 | -- MAE pour affectation des rangs aux différentes librairies MPI |
---|
107 | type init2_type is (init,GetPortNum,DecodeData,IsPortZero,SeekMain1,SeekMain2,StoreMain,SetMainFlag,ReadNoc,GetMainReq,StoreRank,NewRank,SendRank,RegRank,SendPeerStat,AskPeerStat,GetPeerStat,SendApp,SpawnApp,SpawnLoad,ErrSpawn,EndInit); |
---|
108 | -- MAE pour réception de init depuis le réseau; |
---|
109 | type init3_type is (init,GetNocSize,ReadInitHead,StorePort,EndInit); |
---|
110 | type typ_send is (s_init,s_head,s_len,s_len2,s_data,s_end); |
---|
111 | type typ_receiv is (r_wait,r_dlen,r_drop,r_glen,r_data,r_pulse,r_end); |
---|
112 | type typ_cmd is (cmdstart,cmdpost,cmdpostidle,cmdread,cmdlen,cmdglen,cmddata,cmdend,cmdtimeout); |
---|
113 | type typ_mem16 is array(natural range <>) of std_logic_vector(15 downto 0);-- |
---|
114 | signal etsnd : typ_send; |
---|
115 | signal etrec:typ_receiv; --pour la machine à état de réception |
---|
116 | signal etcmd :typ_cmd; --pour la machine à état de commande |
---|
117 | signal IS_state,next_Is_state : natural range 0 to 3:=0; |
---|
118 | |
---|
119 | -- signal stInit1, next_stInit1 : init1_type; |
---|
120 | signal stInit2, next_stInit2 : init2_type; |
---|
121 | --signal stInit3, next_stInit3 : init3_type; |
---|
122 | --signaux pour l'interface avec les ports |
---|
123 | signal cport_in_wr_en,sport_in_wr_en:std_logic; |
---|
124 | signal cport_out_rd_en,rport_out_rd_en:std_logic; |
---|
125 | signal rdy:std_logic:='0'; --signal busy/ready |
---|
126 | signal tosend,tosend4 :std_logic_vector(Word-1 downto 0); |
---|
127 | signal PeerStat : std_logic_vector(15 downto 0):=(others=>'0'); --état des autres Lib initialisées |
---|
128 | signal SpawnReq,SpawnReq_Q : std_logic_vector(15 downto 0):=(others=>'0'); --état des autres HT qui ont appelés le Spawn |
---|
129 | signal Spawn_grp,Spawn_grp_Q :typ_mem16(0 to 3):=((others=>'0'),(others=>'0'),(others=>'0'),(others=>'0')); --un max de quatre groupes de fils est prévu |
---|
130 | signal Grp_id,grp_id_i :natural range 0 to 3:=0; --id du groupe des HT fils |
---|
131 | signal selector : std_logic_vector (2 downto 0); -- pour le MUX des signaux vers le port |
---|
132 | --signaux pour les états des MAE |
---|
133 | signal NocSizeOk,PortCountFlag : std_logic; |
---|
134 | signal PortNumFlag,EquFlag,MainResp,StatAsked,RankAsked,RankSent:std_logic; |
---|
135 | |
---|
136 | signal RTS_cmd,RTS_dat,RTS_I,CTR,BCast,Send_Ack,DS_Ack,CM_Ack:std_logic:='0'; |
---|
137 | signal I_Send_Ack,I_Send_Rdy:std_logic:='0'; |
---|
138 | signal Rcv_On,Snd_On,Cmd_On : std_logic:='0'; --status des MAE d'envoie et de réception |
---|
139 | signal SpawnOn,SpawnInit :std_logic:='0'; --indique que le Spawn est activé |
---|
140 | signal SpawnNbReq,SpawnNbAck,SpawnNBAck_i : natural range 0 to 15 :=0; --compte le nombre de requêtes et le nombre d'acquitement |
---|
141 | signal SpawnNbReq_Q : natural range 0 to 15 :=0; --compte le nombre de requêtes et le nombre d'acquitement |
---|
142 | signal SpawnCmd0,SpawnCmd1, SpawnCmd2 :std_logic_vector(Word-1 downto 0):=(others=>'0'); |
---|
143 | signal SpawnCmd0_Q,SpawnCmd1_Q, SpawnCmd2_Q :std_logic_vector(Word-1 downto 0):=(others=>'0'); |
---|
144 | signal SpawnDest :std_logic_vector(3 downto 0); |
---|
145 | Signal Ht_Start,Ht_Start_i : natural range 0 to 15:=0; |
---|
146 | Signal vPeerStat,vPeerStat_i : std_logic_vector(15 downto 0):=(others=>'0'); |
---|
147 | signal IsMain_i,Initialized_i,HCL_init: std_logic:='0'; |
---|
148 | signal DS_RDY ,BCast_Rdy,Send_RDY,CM_RDY:std_logic:='0'; |
---|
149 | signal ExecTime_out:std_logic; |
---|
150 | --signaux de gestion de la RAM |
---|
151 | signal Ram_NextAdress : std_logic_vector(ADRLEN-1 downto 0):=std_logic_vector(to_unsigned(Core_BASE_ADR+CORE_Rank2port_BASE,16)); |
---|
152 | signal Ram_NExtAdress_i :std_logic_vector(ADRLEN-1 downto 0):=std_logic_vector(to_unsigned(Core_BASE_ADR+CORE_Rank2port_BASE,16)); |
---|
153 | signal n,n_i:natural range 0 to 15 :=0; |
---|
154 | signal n0,n0_i:natural range 0 to 7:=0; |
---|
155 | signal DataToRam : std_logic_vector(Word-1 downto 0) ; |
---|
156 | signal dma_rd,dma_wr,rd_ok ,wr_ok:std_logic:='0'; |
---|
157 | --Signaux des résultats et de l'état |
---|
158 | signal PortNum_i,MyPort : std_logic_vector(3 downto 0); -- |
---|
159 | signal NocMax : std_logic_vector(3 downto 0):=(others=>'0'); -- Nombre de ports du réseau -1 ? |
---|
160 | signal MyRank : std_logic_vector(3 downto 0) ; --rang du PE |
---|
161 | signal AppSize_i:std_logic_vector(3 downto 0) ;--taille de l'application |
---|
162 | signal Spawn_done:std_logic:='0'; --indique que le Spawn a été effectué |
---|
163 | signal MainPort : std_logic_vector(3 downto 0) ; --Port de la lib main |
---|
164 | signal NextRank,NextRank_i : std_logic_vector(3 downto 0):=(others=>'0'); --utiliser pour gérer les affectations de rangs MPI |
---|
165 | signal DataToSend : Typ_PortIo(0 to 3):=((others=>'0'),(others=>'0'),(others=>'0'),(others=>'0')); -- permet d'empiler les données à envoyer |
---|
166 | signal RankToPort :Typ_PortIo(0 to 15);--permet d'associer un port réseau à chaque rang |
---|
167 | signal CmdReceived : Typ_PortIO(0 to 3):=((others=>'0'),(others=>'0'),(others=>'0'),(others=>'0')); |
---|
168 | signal DataReceived : Typ_PortIO(0 to 3):=((others=>'0'),(others=>'0'),(others=>'0'),(others=>'0')); |
---|
169 | signal Datalen : natural range 0 to 7:=0; --indique la longueur des données |
---|
170 | --other outputs |
---|
171 | signal StatAsked_i,RankAsked_i,EquFlag_i,MainResp_i,RankSent_i,Result_i:std_logic:='0'; |
---|
172 | signal snd_start_i:std_logic:='0';--version interne des signaux de sortie |
---|
173 | --signal BCast_Rdy_i : std_logic; |
---|
174 | signal cdlen,dcount : natural range 0 to 255:=0; --longueur du paquet reçu par le process pcmd |
---|
175 | signal timeout,timeout_i : natural range 0 to 4095:=0; |
---|
176 | signal PortStat : std_logic_vector(3 downto 0):=(others=>'0'); |
---|
177 | signal PeerPort : natural range 0 to 15:=0; -- désigne le port qui emet une requête |
---|
178 | signal PeerRTS,PeerCTR:std_logic:='0'; |
---|
179 | signal cpt,cpt_peer : natural range 0 to 31:=0; --compteur pour le nombre de HT initialisés |
---|
180 | signal clk_cyl,clk_cyl_i : natural range 0 to 15:=0; |
---|
181 | begin |
---|
182 | --======================================================================================= |
---|
183 | --fonctions du module |
---|
184 | --======================================================================================= |
---|
185 | --======================================================================================= |
---|
186 | |
---|
187 | -- Inst_SetBit: SetBit PORT MAP( |
---|
188 | -- clk => clk, |
---|
189 | -- reset => reset , |
---|
190 | -- ce => cmd, |
---|
191 | -- BitNum => , |
---|
192 | -- BitVal => '1', |
---|
193 | -- dma_wr_grant => dma_wr_grant , |
---|
194 | -- dma_wr_request => dma_wr_request, |
---|
195 | -- dma_rd_grant => dma_rd_grant, |
---|
196 | -- dma_rd_request => dma_rd_request, |
---|
197 | -- ram_rd => ram_rd, |
---|
198 | -- ram_wr => ram_wr, |
---|
199 | -- ram_address => , |
---|
200 | -- Ram_data_in => Ram_data_in, |
---|
201 | -- Ram_data_out => Ram_data_out |
---|
202 | -- ); |
---|
203 | |
---|
204 | |
---|
205 | -- Gestion de l'initialisation du Core MPI |
---|
206 | sync_Init2 : process (clk,reset) |
---|
207 | begin |
---|
208 | if reset='1' then |
---|
209 | stinit2<=init; |
---|
210 | StatAsked<='0'; |
---|
211 | NextRank<=(others =>'0'); |
---|
212 | elsif rising_edge(clk) then |
---|
213 | stinit2<=next_stinit2; |
---|
214 | IS_State<=Next_IS_State; |
---|
215 | n0<=n0_i; |
---|
216 | --ajout des autres affectations ici |
---|
217 | Ram_NextAdress<=Ram_NextAdress_i ; |
---|
218 | |
---|
219 | RankAsked<=RankAsked_i; |
---|
220 | RankSent<=RankSent_i; |
---|
221 | AppRank<=MyRank; |
---|
222 | timeout<=timeout_i; |
---|
223 | cpt<=cpt_peer; |
---|
224 | clk_cyl<=clk_cyl_i; |
---|
225 | NextRank<=NextRank_i; |
---|
226 | StatAsked<=StatAsked_i; |
---|
227 | n<=n_i; |
---|
228 | Ht_Start<=Ht_Start_i; |
---|
229 | Grp_Id<=Grp_Id_i; |
---|
230 | vPeerStat<=vPeerStat_i; |
---|
231 | SpawnNbAck<=SpawnNbAck_i; |
---|
232 | AppSize<=AppSize_i; |
---|
233 | Ready<=Rdy; |
---|
234 | snd_start<=snd_start_i; |
---|
235 | SpawnNbReq_q<=SpawnNbReq; |
---|
236 | SpawnReq_Q<=SpawnReq; |
---|
237 | SpawnCmd0_Q<=SpawnCmd0; |
---|
238 | SpawnCmd1_Q<=SpawnCmd1; |
---|
239 | SpawnCmd2_Q<=SpawnCmd2; |
---|
240 | Spawn_grp_q<=Spawn_grp; |
---|
241 | end if; |
---|
242 | end process; |
---|
243 | |
---|
244 | Init2_DECODE: process (stinit2,n, CmdReceived, EquFlag, MyPort, DS_RDY, MainResp, DataReceived, |
---|
245 | SpawnOn,Ram_NextAdress,PeerRTS,PortSTAT,dma_rd,dma_wr,Send_rdy,I_Send_rdy,rd_ok,wr_ok,Instruction, |
---|
246 | MainPort,PeerStat,SpawnCmd0,SpawnCmd1,SpawnCmd2,SpawnInit,BCast_rdy) |
---|
247 | variable nextr,nextadr : natural :=0;--to_integer(unsigned(Ram_NextAdress)); |
---|
248 | variable nport : natural range 0 to 15:=0; |
---|
249 | begin |
---|
250 | |
---|
251 | Case stInit2 is |
---|
252 | When Init => |
---|
253 | RTS_cmd<='0'; |
---|
254 | --RTS_dat<='0'; |
---|
255 | RTS_I<='0'; |
---|
256 | BCast<='0'; |
---|
257 | Result_En<='0'; |
---|
258 | Initialized_i<='0'; |
---|
259 | CM_Ack <='0'; |
---|
260 | CTR<='0' ; |
---|
261 | DS_ACK<='0'; |
---|
262 | Send_Ack<='0'; |
---|
263 | ram_wr<='0'; |
---|
264 | rdy<='1';--le module est disponible |
---|
265 | ResultOut<=(others=>'0'); |
---|
266 | if PortNumFlag='1' and IsMain_i='1' then |
---|
267 | PortNum_i<=Instruction(3 downto 0); |
---|
268 | else |
---|
269 | PortNum_i<=(others=>'-'); |
---|
270 | end if; |
---|
271 | EquFlag<='0'; |
---|
272 | RankAsked_i<='0'; |
---|
273 | dma_wr_request<='0'; |
---|
274 | dma_rd_request<='0'; |
---|
275 | When GetPortNum => |
---|
276 | RTS_cmd<='1'; |
---|
277 | RTS_I<='0'; |
---|
278 | |
---|
279 | Result_En<='0'; |
---|
280 | Initialized_i<='0'; |
---|
281 | BCast<='0'; --réalise un envoie non collectif |
---|
282 | CM_Ack<='0'; -- les données sont maintenant attendues |
---|
283 | CTR<='0' ; |
---|
284 | DataToSend(0)<=X"0" & GETPORTID; |
---|
285 | DS_ACK<='0'; |
---|
286 | Send_Ack<='0'; |
---|
287 | ram_wr<='0'; |
---|
288 | rdy<='0'; |
---|
289 | ResultOut<=(others=>'0'); |
---|
290 | PortNum_i<=(others=>'-'); |
---|
291 | RankAsked_i<='0'; |
---|
292 | dma_wr_request<='0'; |
---|
293 | When DecodeData => |
---|
294 | EquFlag<=(All_zeros(Cmdreceived(2)(3 downto 0))); |
---|
295 | RTS_cmd<='0'; |
---|
296 | RTS_I<='0'; |
---|
297 | BCast<='0'; |
---|
298 | |
---|
299 | Result_En<='0'; |
---|
300 | |
---|
301 | CM_Ack <='1'; --les données ont été reçues |
---|
302 | MyPort<=Cmdreceived(2)(3 downto 0); |
---|
303 | PortNum_i<=Cmdreceived(2)(3 downto 0); --récupère les valeurs de port |
---|
304 | PeerPort<=To_integer(unsigned(Cmdreceived(2)(3 downto 0))); |
---|
305 | NocMax<=Cmdreceived(2)(7 downto 4); -- et la taille du réseau |
---|
306 | PortNumFlag<='1'; -- le numéro du port est maintenant connu |
---|
307 | CTR<='0' ; |
---|
308 | DS_ACK<='0'; |
---|
309 | Send_Ack<='0'; |
---|
310 | ram_wr<='0'; |
---|
311 | rdy<='0'; |
---|
312 | RankAsked_i<='0'; |
---|
313 | ResultOut<=(others=>'0'); |
---|
314 | dma_wr_request<='0'; |
---|
315 | When IsPortZero => --Ce port est-il le n° 0 du NoC ? |
---|
316 | BCast<='0'; |
---|
317 | Result_En<='0'; |
---|
318 | RTS_cmd<='0'; |
---|
319 | RTS_I<='0'; |
---|
320 | NextRank_i<="0001"; -- le prochain rang à affecter sera le n° 1 |
---|
321 | nextr:=1; |
---|
322 | IsMain_i<=EquFlag; |
---|
323 | MyRank<="0000"; |
---|
324 | MainPort<="0000"; |
---|
325 | --MainAdr<="0000"; -- le port 0 est le main Lib par défaut; |
---|
326 | CTR<='0' ; |
---|
327 | DS_ACK<='0'; |
---|
328 | ram_wr<='0'; |
---|
329 | rdy<='0'; |
---|
330 | RankAsked_i<='0'; |
---|
331 | ResultOut<=(others=>'0'); |
---|
332 | dma_wr_request<='0'; |
---|
333 | When SeekMain1 => -- recherche de la lib main |
---|
334 | RTS_cmd<='0'; |
---|
335 | --RTS_DAT<='1'; |
---|
336 | RTS_I<='1'; |
---|
337 | CTR<='1' ; -- prêt à recevoir les données Clear To Receive |
---|
338 | DS_ACK<='0'; --les données sont attendus |
---|
339 | Send_Ack<=BCast_rdy; |
---|
340 | I_Send_Ack<=BCAst_rdy; |
---|
341 | DataToSend(0)<=MPI_INIT & MyPort ; |
---|
342 | DataToSend(1)<="00000100"; -- la longueur du packet =4 |
---|
343 | DataToSend(2)<="0000" & MyPort; --propose sa propre adresse |
---|
344 | DataToSend(3)<=INIT_SEEKMAIN & MyPort ; |
---|
345 | DataLen<=4; |
---|
346 | BCast<='1'; |
---|
347 | |
---|
348 | Result_En<='0'; |
---|
349 | Initialized_i<='0'; |
---|
350 | ram_wr<='0'; |
---|
351 | rdy<='0'; |
---|
352 | ResultOut<=(others=>'0'); |
---|
353 | RankAsked_i<='0'; |
---|
354 | dma_wr_request<='0'; |
---|
355 | When SeekMain2 => -- recherche de la lib main |
---|
356 | RTS_cmd<='0'; |
---|
357 | RTS_I<='0'; |
---|
358 | CTR<='1' ; -- prêt à recevoir les données Clear To Receive |
---|
359 | DS_ACK<= DS_RDY; --les données sont acquittées aussitôt reçues |
---|
360 | Send_Ack<=BCast_rdy; |
---|
361 | -- DataToSend(0)<=INIT_SEEKMAIN & MyPort ; |
---|
362 | -- DataToSend(1)<="00000011"; -- la longueur du packet =3 |
---|
363 | -- DataToSend(2)<="0000" & MyPort; --propose sa propre adresse |
---|
364 | -- DataLen<=3; |
---|
365 | BCast<='0'; |
---|
366 | Result_En<='0'; |
---|
367 | Initialized_i<='0'; |
---|
368 | ram_wr<='0'; |
---|
369 | rdy<='0'; |
---|
370 | ResultOut<=(others=>'0'); |
---|
371 | EquFlag<='0'; |
---|
372 | RankAsked_i<='0'; |
---|
373 | dma_wr_request<='0'; |
---|
374 | When StoreMain => -- la Main Lib est une autre |
---|
375 | BCAST<='0'; |
---|
376 | Result_En<='0'; |
---|
377 | IsMain_i<='0'; |
---|
378 | Initialized_i<='0'; |
---|
379 | DS_ACK<=DS_RDY; |
---|
380 | Send_Ack<='0'; |
---|
381 | RTS_cmd<='0'; |
---|
382 | RTS_I<='0'; |
---|
383 | CTR<=not(MainResp); -- essayer de recevoir tant que le main n'a pas répondu |
---|
384 | ram_wr<='1'; |
---|
385 | rdy<='0'; |
---|
386 | ResultOut<=(others=>'0'); |
---|
387 | RankAsked_i<='0'; |
---|
388 | EquFlag<='0'; |
---|
389 | MainPort<=DataReceived(0)(3 downto 0); |
---|
390 | ram_address<= STD_logic_vector(to_unsigned(Core_init_adr+1,16)); |
---|
391 | ram_data_in<=DataReceived(0)(3 downto 0)& DataReceived(2)(3 downto 0); --MainPort & MyRank |
---|
392 | dma_wr_request<= '0'; ---pas très sûr |
---|
393 | |
---|
394 | When AskPeerStat => -- Interroge les données d'initialisation |
---|
395 | RTS_cmd<='0'; |
---|
396 | if n=0 then |
---|
397 | --RTS_DAT<='0'; --on peut envoyer les données |
---|
398 | RTS_I<='1'; |
---|
399 | else |
---|
400 | --RTS_DAT<='0'; --on désactive l'envoie des données |
---|
401 | RTS_I<='0'; |
---|
402 | end if; |
---|
403 | CTR<='0' ; -- prêt à recevoir les données Clear To Receive |
---|
404 | DS_ACK<='0'; --les données sont attendus |
---|
405 | I_Send_Ack<=I_Send_rdy; |
---|
406 | Send_Ack<=Send_rdy; |
---|
407 | DataToSend(0)<=MPI_INIT & MainPort ; |
---|
408 | DataToSend(1)<="00000100"; -- la longueur du packet =4 |
---|
409 | DataToSend(2)<="0000" & MyPort; --indique sa propre adresse |
---|
410 | DataToSend(3)<=INIT_STAT & MyPort ; |
---|
411 | DataLen<=4; |
---|
412 | BCast<='0'; |
---|
413 | Result_En<='0'; |
---|
414 | ram_wr<='0'; |
---|
415 | rdy<='0'; |
---|
416 | ResultOut<=(others=>'0'); |
---|
417 | EquFlag<='0'; |
---|
418 | RankAsked_i<='0'; |
---|
419 | dma_wr_request<='0'; |
---|
420 | When SetMainFlag => -- Cette Lib est la Main Lib |
---|
421 | if (Datareceived(3)(7 downto 4) = INIT_SEEKMAIN) then |
---|
422 | RankAsked_i<='1'; |
---|
423 | else |
---|
424 | RankAsked_i<='0'; |
---|
425 | end if; |
---|
426 | RTS_cmd<='0'; |
---|
427 | Initialized_i<='0'; |
---|
428 | RTS_I<='0'; |
---|
429 | BCast<='0'; |
---|
430 | IsMain_i<='1'; |
---|
431 | Result_En<='0'; |
---|
432 | MyRank<="0000"; |
---|
433 | MainPort<="0000"; |
---|
434 | PeerStat(0)<='1'; --la main lib est initialisée |
---|
435 | CTR<='1'; |
---|
436 | DS_ACK<='0'; |
---|
437 | ram_wr<='1'; |
---|
438 | rdy<='0'; |
---|
439 | ResultOut<=(others=>'0'); |
---|
440 | EquFlag<='0'; |
---|
441 | ram_address<= STD_logic_vector(to_unsigned(Core_init_adr+1,16)); |
---|
442 | ram_data_in<=(others =>'0'); -- le port vaut 0 et la mainlib est aussi à 0 |
---|
443 | dma_wr_request<='1'; |
---|
444 | When ReadNoc => |
---|
445 | if (Datareceived(3)(7 downto 4) = INIT_SEEKMAIN) then |
---|
446 | RankAsked_i<='1' ; |
---|
447 | else |
---|
448 | RankAsked_i<='0'; |
---|
449 | end if; |
---|
450 | ram_wr<='0'; -- pas d'écriture en RAM |
---|
451 | rdy<='0'; |
---|
452 | BCast<='0'; |
---|
453 | DS_ACK<='0'; |
---|
454 | --IsMain<='0'; |
---|
455 | Result_En<='0'; |
---|
456 | RTS_cmd<='0'; |
---|
457 | RTS_I<='0'; |
---|
458 | CTR<='1'; |
---|
459 | ResultOut<=(others=>'0'); |
---|
460 | PortNum_i<=DataReceived(2)(3 downto 0); -- le port qui demande un rang; |
---|
461 | PeerPort<= To_integer(unsigned(DataReceived(2)(3 downto 0))); |
---|
462 | --EquFlag<='1'; |
---|
463 | dma_wr_request<='0'; |
---|
464 | When GetMainReq => |
---|
465 | --RankAsked_i<='1'; |
---|
466 | ram_wr<='0'; -- pas |
---|
467 | BCast<='0'; |
---|
468 | DS_ACK<='1'; |
---|
469 | Result_En<='0'; |
---|
470 | RTS_cmd<='0'; |
---|
471 | RTS_I<='0'; |
---|
472 | CTR<='1'; |
---|
473 | ResultOut<=(others=>'0'); |
---|
474 | PortNum_i<=DataReceived(0)(3 downto 0); -- le port qui demande un rang; |
---|
475 | EquFlag<='1'; |
---|
476 | dma_wr_request<='0'; |
---|
477 | When GetPeerStat => |
---|
478 | --RankAsked_i<='1'; |
---|
479 | ram_wr<='0'; -- pas |
---|
480 | BCast<='0'; |
---|
481 | DS_ACK<=DS_RDY; |
---|
482 | Result_En<='0'; |
---|
483 | RTS_cmd<='0'; |
---|
484 | RTS_I<='0'; |
---|
485 | CTR<=not MainResp; |
---|
486 | ResultOut<=(others=>'0'); |
---|
487 | PortNum_i<=DataReceived(0)(3 downto 0); --adresse du Main Port |
---|
488 | PeerStat(7 downto 0)<=DataReceived(2); -- état des initialisations |
---|
489 | EquFlag<='0'; |
---|
490 | dma_wr_request<=dma_wr; |
---|
491 | ram_wr<=wr_ok; |
---|
492 | rdy<='0'; |
---|
493 | ram_rd<=rd_ok; |
---|
494 | Ram_NextAdress_i<= STD_logic_vector(to_unsigned(CORE_Init_Adr+2,ADRLEN)); --incr_vec(Ram_NextAdress,'1'); |
---|
495 | ram_address<=Ram_NextAdress; -- |
---|
496 | ram_data_in<=DataReceived(2); --enregistrer les ports actifs |
---|
497 | |
---|
498 | When NewRank => |
---|
499 | nport:=to_integer(Unsigned(PortNum_i)); --port ayant sollicité le rang |
---|
500 | nextr:=to_integer(unsigned(nextrank)); |
---|
501 | if PeerStat(nport)='0' then -- si le rang n'a pas encore été affecté à ce port |
---|
502 | nextrank_i<=incr_vec(nextrank,'1'); |
---|
503 | RankToPort(nextR)<="0000" & PortNum_i; |
---|
504 | NextAdr:=NextAdr+1; |
---|
505 | end if; |
---|
506 | DataToSend(0)<=MPI_INIT & PortNum_i ; |
---|
507 | DataToSend(1)<="00000100"; |
---|
508 | DataToSend(2)<="0000" & NextRank; --ici c'est la valeur avant incrémentation ! |
---|
509 | DataToSend(3)<=INIT_SETRANK & PortNum_i ; |
---|
510 | PeerStat(nport)<='1'; -- mise à jour du status |
---|
511 | DataLen<=4; |
---|
512 | BCast<='0'; |
---|
513 | DS_ACK<='0'; |
---|
514 | Result_En<='0'; |
---|
515 | EquFlag<='1'; |
---|
516 | RTS_cmd<='0'; |
---|
517 | RTS_I<='1'; |
---|
518 | CTR<='0' ; |
---|
519 | ram_wr<='0'; |
---|
520 | rdy<='0'; |
---|
521 | RankAsked_i<='1'; |
---|
522 | ResultOut<=(others=>'0'); |
---|
523 | dma_wr_request<='0'; |
---|
524 | |
---|
525 | When SendRank => |
---|
526 | BCast<='0'; |
---|
527 | Result_En<='0'; |
---|
528 | EquFlag<='1'; |
---|
529 | |
---|
530 | RTS_I<='1'; |
---|
531 | RTS_cmd<='0'; |
---|
532 | DS_ACK<='0'; |
---|
533 | Send_Ack<='0'; |
---|
534 | CTR<='0' ; |
---|
535 | ram_wr<='0'; |
---|
536 | Ram_NextAdress_i<= STD_logic_vector(to_unsigned(CORE_RANK_ADR+Nextr-1,16)); |
---|
537 | ResultOut<=(others=>'0'); |
---|
538 | RankAsked_i<='1'; |
---|
539 | dma_wr_request<='0'; |
---|
540 | When RegRank => |
---|
541 | RankAsked_i<='0'; |
---|
542 | |
---|
543 | CTR<='1' ; -- continuer à recevoir les données du NoC |
---|
544 | Result_En<='0'; |
---|
545 | RTS_cmd<='0'; |
---|
546 | DS_ACK<='0'; |
---|
547 | Send_Ack<=Send_RDY; |
---|
548 | I_Send_ack<=i_send_rdy; |
---|
549 | Rts_I<='0'; |
---|
550 | BCast<='0'; |
---|
551 | EquFlag<='1'; |
---|
552 | ram_wr<='1'; |
---|
553 | |
---|
554 | Ram_NextAdress_i<= STD_logic_vector(to_unsigned(CORE_RANK_ADR+Nextr-1,16)); --incr_vec(Ram_NextAdress,'1'); |
---|
555 | ram_address<=Ram_NextAdress; -- le rang qui a été envoyé; |
---|
556 | -- "le motif 0001 indique juste que le port est bien activé |
---|
557 | ram_data_in<="0001" & PortNum_i; --enregistrer le port qui a fait la demande en RAM |
---|
558 | ResultOut<=(others=>'0'); |
---|
559 | dma_wr_request<='1'; |
---|
560 | When SendPeerStat => |
---|
561 | BCast<='0'; |
---|
562 | Result_En<='0'; |
---|
563 | EquFlag<='0'; |
---|
564 | RTS_I<=PeerRTS; |
---|
565 | RTS_cmd<='0'; |
---|
566 | DS_ACK<='0'; |
---|
567 | DataToSend(0)<=MPI_INIT & PortStat ; |
---|
568 | DataToSend(1)<="00000100"; |
---|
569 | DataToSend(2)<=PeerStat(7 downto 0); |
---|
570 | DataToSend(3)<=INIT_REGISTER & MyPort ; |
---|
571 | Send_Ack<=Send_Rdy; |
---|
572 | I_Send_Ack<=I_Send_Rdy; |
---|
573 | CTR<='0' ; |
---|
574 | ram_wr<='0'; |
---|
575 | rdy<='0'; |
---|
576 | ResultOut<=(others=>'0'); |
---|
577 | RankAsked_i<='1'; |
---|
578 | dma_wr_request<='0'; |
---|
579 | Initialized_i<='1'; |
---|
580 | When StoreRank => --le processus qui écoute le Port et qui |
---|
581 | --stoke les adresses des autres bib va gérer le stockage du rang |
---|
582 | BCAST<='0'; |
---|
583 | DS_ACK<='1'; |
---|
584 | Send_Ack<='0'; |
---|
585 | RTS_cmd<='0'; |
---|
586 | EquFlag<='0'; |
---|
587 | RTS_I<='0'; |
---|
588 | CTR<='0'; |
---|
589 | Result_En<='0'; |
---|
590 | |
---|
591 | if ExecTime_out='1' then |
---|
592 | MainPort<="0000"; |
---|
593 | MyRank<=MyPort; |
---|
594 | initialized_i<='0'; |
---|
595 | else |
---|
596 | MainPort<=DataReceived(0)(3 downto 0); |
---|
597 | MyRank<=DataReceived(2)(3 downto 0); |
---|
598 | Initialized_i<='1'; |
---|
599 | end if; |
---|
600 | ram_wr<='1'; |
---|
601 | --ram_address<=DataReceived(2); -- le rang qui a été envoyé; |
---|
602 | ram_address<= STD_logic_vector(to_unsigned(Core_init_adr+1,16)); |
---|
603 | ram_data_in<=DataReceived(0)(3 downto 0)& DataReceived(2)(3 downto 0); --MainPort & MyRank |
---|
604 | ResultOut<=(others=>'0'); |
---|
605 | RankAsked_i<='0'; |
---|
606 | dma_wr_request<='1'; |
---|
607 | When SendApp => --ajouter du code pour recevoir l'adr du reg status |
---|
608 | Initialized_i<='1'; |
---|
609 | ResultOut<="00000001"; -- Init Ok |
---|
610 | Result_En<='1'; |
---|
611 | PortId<=MyPort; |
---|
612 | BCAST<='0'; |
---|
613 | DS_ACK<='1'; |
---|
614 | Send_Ack<='0'; |
---|
615 | RTS_cmd<='0'; |
---|
616 | RTS_I<='0'; |
---|
617 | CTR<='0'; |
---|
618 | ram_wr<='0'; |
---|
619 | rdy<='0'; |
---|
620 | RankAsked_i<='0'; |
---|
621 | dma_wr_request<='0'; |
---|
622 | When SpawnApp => |
---|
623 | RTS_cmd<='0'; |
---|
624 | RTS_I<='0'; |
---|
625 | Result_En<='0'; |
---|
626 | DS_ACK<=DS_RDY; |
---|
627 | BCAST<='0'; |
---|
628 | CTR<='0'; --cette mise à 1 permet de ctrler la fin de réception |
---|
629 | rdy<='0'; |
---|
630 | ram_wr<=wr_ok; |
---|
631 | ram_rd<=rd_ok; |
---|
632 | Ram_NextAdress_i<= STD_logic_vector(to_unsigned(CORE_BASE_ADR,ADRLEN)); --incr_vec(Ram_NextAdress,'1'); |
---|
633 | ram_address<=Ram_NextAdress; -- le rang qui a été envoyé; |
---|
634 | -- "le motif 0001 indique juste que le port est bien activé |
---|
635 | ram_data_in<=DataToRam; --enregistrer le port qui a fait la demande en RAM |
---|
636 | dma_rd_request <= dma_rd; |
---|
637 | dma_wr_request <=dma_wr; |
---|
638 | RankAsked_i<='0'; |
---|
639 | if n>=3 then |
---|
640 | ResultOut<=("00000010");--spawn completed |
---|
641 | else |
---|
642 | ResultOut<=("00000000");--spawn message received |
---|
643 | end if; |
---|
644 | |
---|
645 | When SpawnLoad => |
---|
646 | RTS_cmd<='0'; |
---|
647 | --RTS_DAT<='1'; --à tester |
---|
648 | RTS_I<=PeerRTS; -- pour le timing |
---|
649 | Result_En<='0'; |
---|
650 | DS_ACK<='0'; |
---|
651 | BCAST<='0'; |
---|
652 | CTR<='0'; |
---|
653 | rdy<='0'; |
---|
654 | ram_wr<=wr_ok; |
---|
655 | ram_rd<=rd_ok; |
---|
656 | DataToSend(0)<=SpawnCmd0; |
---|
657 | DataToSend(1)<="00000100"; |
---|
658 | DataToSend(2)<=SpawnCmd1; |
---|
659 | DataToSend(3)<=SpawnCmd2; -- SPAWN_LOAD & MyPort ; |
---|
660 | Send_Ack<=Send_Rdy; |
---|
661 | I_Send_Ack<=I_Send_rdy; |
---|
662 | RankAsked_i<='0'; |
---|
663 | if SpawnInit='1' then |
---|
664 | ResultOut<=("10000000"); --spawn completed |
---|
665 | else |
---|
666 | ResultOut<=("01000000");--spawn in progress |
---|
667 | end if; |
---|
668 | When ErrSpawn => |
---|
669 | RTS_cmd<='0'; |
---|
670 | RTS_I<='0'; |
---|
671 | Result_En<='1'; |
---|
672 | DS_ACK<='0'; |
---|
673 | Send_Ack<='0'; |
---|
674 | BCAST<='0'; |
---|
675 | CTR<='0'; |
---|
676 | ram_wr<='0'; |
---|
677 | rdy<='0'; |
---|
678 | RankAsked_i<='0'; |
---|
679 | |
---|
680 | ResultOut<=(others=>'0'); |
---|
681 | dma_wr_request<='0'; |
---|
682 | dma_rd_request<='0'; |
---|
683 | When EndInit => |
---|
684 | RTS_cmd<='0'; |
---|
685 | RTS_I<='0'; |
---|
686 | Result_En<='0'; |
---|
687 | DS_ACK<='0'; |
---|
688 | Send_Ack<='0'; |
---|
689 | BCAST<='0'; |
---|
690 | CTR<='0'; |
---|
691 | ram_wr<='0'; |
---|
692 | rdy<='0'; |
---|
693 | RankAsked_i<='0'; |
---|
694 | ResultOut<=(others=>'0'); |
---|
695 | dma_wr_request<='0'; |
---|
696 | dma_rd_request<='0'; |
---|
697 | end case; |
---|
698 | end process; |
---|
699 | |
---|
700 | result_proc:process (ISMain_i,Initialized_i,stInit2,reset) |
---|
701 | begin |
---|
702 | if reset='1' then |
---|
703 | IsMain<='0'; |
---|
704 | Initialized<='0'; |
---|
705 | Else |
---|
706 | if ismain_i='1' then |
---|
707 | IsMain<='1'; |
---|
708 | end if; |
---|
709 | |
---|
710 | if Initialized_i='1' and stInit2=EndInit then |
---|
711 | Initialized<='1'; |
---|
712 | HCL_Init<='1'; |
---|
713 | elsif stInit2=SendApp then |
---|
714 | HCL_Init<='1'; |
---|
715 | end if; |
---|
716 | end if; |
---|
717 | end process result_proc; |
---|
718 | --================ |
---|
719 | --Traitement du Spawn |
---|
720 | --=================== |
---|
721 | |
---|
722 | --================== |
---|
723 | NEXT_STInit2_DECODE: process (stInit2,AppReq,Instruction_en, AppAck,PortNumFlag,EquFlag,MainResp,StatAsked,RankAsked,RankSent,CM_RDY, CmdReceived, |
---|
724 | BCast_Rdy, DS_RDY, DataReceived,Ht_Start,vPeerStat, Send_RDY, I_Send_RDY,TimeOut,Dma_rd_grant,Dma_wr_grant,cpt,n,clk_cyl,IsMain_i,SpawnOn, |
---|
725 | Instruction,Hcl_Init,Spawn_done,mainport,PeerStat,PeerRTS,Rec_Data,SpawnInit,grp_id,SpawnNbReq,Ram_data_out,Spawn_grp,MyPort) |
---|
726 | variable InitTimeOut :natural:=0; |
---|
727 | variable LastPort,Ht_hole : std_logic:='0'; |
---|
728 | variable i,nbSpawn,htloc,Ht_Id : natural range 0 to 15:=0; |
---|
729 | --variable vPeerStat : std_logic_vector(15 downto 0); |
---|
730 | variable vPortStat,nulvect : std_logic_vector(3 downto 0):="0000"; |
---|
731 | variable tempval : std_logic_vector(Word-1 downto 0); |
---|
732 | begin |
---|
733 | --declare default state for next_state to avoid latches |
---|
734 | next_stInit2 <= stInit2; --default is to stay in current state |
---|
735 | --insert statements to decode next_state |
---|
736 | --below is a simple example |
---|
737 | vPeerStat_i<=vPeerStat; |
---|
738 | SpawnNbReq<=SpawnNbReq_q; |
---|
739 | SpawnReq<=SpawnReq_q; |
---|
740 | Ht_Start_i<=Ht_Start; |
---|
741 | SpawnCmd0<=SpawnCmd0_Q; |
---|
742 | SpawnCmd1<=SpawnCmd1_Q; |
---|
743 | SpawnCmd2<=SpawnCmd2_Q; |
---|
744 | for i in 0 to 3 loop |
---|
745 | Spawn_grp(i)<=Spawn_grp_q(i); |
---|
746 | end loop; |
---|
747 | case (stInit2) is |
---|
748 | |
---|
749 | |
---|
750 | When Init =>If Instruction_en='1' and AppReq='1' then |
---|
751 | If PortNumFlag='1' and IsMain_i='1' then |
---|
752 | if instruction(7 downto 4)=INIT_SEEKMAIN and (instruction(3 downto 0)/=MyRank) then |
---|
753 | Next_stInit2 <=NewRank;--affecter un rang au demandeur. |
---|
754 | elsif instruction(7 downto 4)=INIT_STAT then |
---|
755 | StatASked_i<='1'; |
---|
756 | Next_stInit2 <=SendPeerStat; --envoyer des stat au demandeur |
---|
757 | elsif instruction(7 downto 4)=SPAWN_LOAD then |
---|
758 | SpawnInit<='0'; -- indique le debut du Spawn |
---|
759 | Next_stInit2 <=SpawnLoad; |
---|
760 | elsif instruction(7 downto 4)=INIT_SPAWN then |
---|
761 | SpawnInit<='1'; -- indique la fin du |
---|
762 | Next_stInit2 <=SpawnLoad; --dans ce cas il s'agit de terminer le spawn |
---|
763 | else --ignorer ce message |
---|
764 | Next_stInit2 <=SendApp; |
---|
765 | end if; |
---|
766 | elsif HCL_Init='1' and IsMain_i='0' then |
---|
767 | Next_stInit2 <=SendApp; --ignorer ce message simplement |
---|
768 | else |
---|
769 | Next_stInit2 <=GetPortNum; -- initialiser la bibliothèque normalement |
---|
770 | end if; |
---|
771 | TimeOut_i<=0;PeerRTS<='0'; |
---|
772 | |
---|
773 | elsif SpawnOn='1' and Spawn_done='0' then |
---|
774 | Next_stInit2 <=SpawnApp; |
---|
775 | TimeOut_i<=0; |
---|
776 | end if; |
---|
777 | cpt_peer<=0;LastPort:='0';n_i<=0; |
---|
778 | When GetPortNum => -- récupérer le numéro du port |
---|
779 | |
---|
780 | if CM_RDY='1' then |
---|
781 | Next_stInit2 <=DecodeData; |
---|
782 | end if; |
---|
783 | |
---|
784 | When DecodeData => -- cet état permet de lire les données reçues du port |
---|
785 | --if CM_RDY='1' then |
---|
786 | if ((Cmdreceived(2)(3 downto 0) or nulvect)=nulvect) then -- teste si le n° du port est zero |
---|
787 | --EquFlag<='1'; |
---|
788 | else |
---|
789 | --EquFlag<='0'; |
---|
790 | end if; |
---|
791 | |
---|
792 | Next_stInit2 <=IsPortZero; |
---|
793 | --end if; |
---|
794 | When IsPortZero => |
---|
795 | if PortNumFlag='1' then |
---|
796 | |
---|
797 | End if; |
---|
798 | if EquFlag='0' then --tester le numéro de port obtenu |
---|
799 | Next_stInit2 <=SeekMain1; -- chercher le numéro de port sur le réseau |
---|
800 | else |
---|
801 | Next_stInit2<=SetMainFlag; -- enregistrer le numéro de port |
---|
802 | End If; |
---|
803 | TimeOut_i<=0; |
---|
804 | |
---|
805 | When SeekMain1 =>If BCast_RDY='1' then -- si tous les envois ont été postés |
---|
806 | Next_stInit2<=SeekMain2; |
---|
807 | End if; |
---|
808 | When SeekMain2 => |
---|
809 | If DS_RDY='1' then -- Si un jeu de données a été reçu |
---|
810 | if (Datareceived(3)(7 downto 4) = INIT_SETRANK) then |
---|
811 | MainResp<='1'; |
---|
812 | Next_stInit2 <=StoreMain; -- de la librairie pricipale |
---|
813 | else |
---|
814 | MainResp<='0'; |
---|
815 | Timeout_i<=0; |
---|
816 | end if; |
---|
817 | |
---|
818 | elsif (ExecTime_Out='1') then |
---|
819 | |
---|
820 | -- le Noc ne répond pas |
---|
821 | -- affecter un numéro en raport avec le port |
---|
822 | Next_stInit2 <=SeekMain2; |
---|
823 | elsif TimeOut=800 then |
---|
824 | --essayer de redemander l'initialisation |
---|
825 | Timeout_i<=0; |
---|
826 | Next_stInit2 <=SeekMain1; |
---|
827 | else |
---|
828 | Timeout_i<=TimeOut+1; |
---|
829 | End if; |
---|
830 | |
---|
831 | |
---|
832 | |
---|
833 | When StoreMain => |
---|
834 | if DataReceived(3)(7 downto 4)= INIT_SETRANK then |
---|
835 | -- enregistrer le Main Adresse et les adresses des autres processus |
---|
836 | -- dans la variable prévue à cet effet |
---|
837 | Next_stInit2 <=StoreRank; |
---|
838 | |
---|
839 | elsif Datareceived(3)(7 downto 4) = INIT_SEEKMAIN then |
---|
840 | -- ignorer ce message |
---|
841 | Next_stInit2 <=StoreMain; --essayer de recevoir le rang |
---|
842 | |
---|
843 | |
---|
844 | end if; |
---|
845 | |
---|
846 | When StoreRank => |
---|
847 | --il faut prévoir du code pour s'assurer que la RAM a bien enregistrer |
---|
848 | -- la donnée ... |
---|
849 | if dma_wr_grant = '1' then |
---|
850 | if clk_cyl=2 then --prévoir deux cycle d'horloge pour lire en RAM |
---|
851 | Next_stInit2 <=AskPeerStat; |
---|
852 | TimeOut_i<=0; |
---|
853 | clk_cyl_i<=0; |
---|
854 | else |
---|
855 | clk_cyl_i<=clk_cyl+1; |
---|
856 | end if; |
---|
857 | else |
---|
858 | Next_stInit2 <=StoreRank; |
---|
859 | TimeOut_i<=0; |
---|
860 | clk_cyl_i<=0; |
---|
861 | end if; |
---|
862 | When AskPeerStat =>if n=0 then |
---|
863 | If I_SEND_RDY='1' then -- si tous les envois ont été postés |
---|
864 | n_i<=1; |
---|
865 | StatAsked_i<='0'; |
---|
866 | End if; |
---|
867 | elsif n=1 then |
---|
868 | If I_SEND_RDY='0' then -- si tous les envois ont été postés |
---|
869 | Next_stInit2<=GetPeerStat; |
---|
870 | StatAsked_i<='1'; |
---|
871 | MainResp<='0'; |
---|
872 | n_i<=0; |
---|
873 | End if; |
---|
874 | end if; |
---|
875 | When GetPeerStat => |
---|
876 | if n=0 then |
---|
877 | If DS_RDY='1' then -- Si un jeu de données a été reçu |
---|
878 | if (Datareceived(3) = INIT_REGISTER & MainPort ) then |
---|
879 | MainResp<='1'; |
---|
880 | n_i<=n+1; |
---|
881 | |
---|
882 | else |
---|
883 | MainResp<='0'; |
---|
884 | Timeout_i<=0; |
---|
885 | n_i<=n; |
---|
886 | end if; |
---|
887 | |
---|
888 | elsif TimeOut=1800 then |
---|
889 | --essayer de redemander les statistiques |
---|
890 | Timeout_i<=0; |
---|
891 | If StatAsked='1' then |
---|
892 | Next_stInit2 <=AskPeerStat; -- ceci n'est pas sûr |
---|
893 | else |
---|
894 | Next_stInit2 <=GetPeerStat; |
---|
895 | end if; |
---|
896 | else |
---|
897 | Timeout_i<=TimeOut+1; |
---|
898 | End if; |
---|
899 | elsif n=1 then --écrire le résultat de l'initialisation |
---|
900 | dma_wr<='1'; |
---|
901 | if dma_wr_grant='1' then |
---|
902 | n_i<=n+1; |
---|
903 | wr_ok<='1'; |
---|
904 | end if; |
---|
905 | elsif n=2 then |
---|
906 | n_i<=n+1; --écriture dans la RAM |
---|
907 | elsif n=3 then |
---|
908 | n_i<=0; |
---|
909 | dma_wr<='0'; |
---|
910 | Next_stInit2 <=SendApp; -- de la librairie pricipale |
---|
911 | end if; |
---|
912 | When SetMainFlag => |
---|
913 | if dma_wr_grant='1' then |
---|
914 | TimeOut_i<=0; |
---|
915 | Next_stInit2 <=ReadNoc; |
---|
916 | elsif Timeout=800 then |
---|
917 | Next_stInit2 <=SendApp; |
---|
918 | else |
---|
919 | TimeOut_i<=TimeOut+1; |
---|
920 | -- end if; -- il est envisagée de terminer le programme à ce point |
---|
921 | end if; |
---|
922 | when ReadNoc => if DS_RDY='1' then |
---|
923 | if (Datareceived(3)(7 downto 4) = INIT_STAT) then |
---|
924 | StatAsked_i<='1' ; |
---|
925 | Next_stInit2 <=SendPeerStat; |
---|
926 | LastPort:='0'; |
---|
927 | else |
---|
928 | StatAsked_i<='0'; |
---|
929 | Next_stInit2 <=GetMainReq; |
---|
930 | end if; |
---|
931 | |
---|
932 | Timeout_i<=0; |
---|
933 | elsif Timeout=200 then |
---|
934 | Timeout_i<=0; |
---|
935 | --if StatAsked = '1' then |
---|
936 | --Next_stInit2 <=ErrSpawn; --il y a eu une erreur |
---|
937 | Next_stInit2 <=SendApp; |
---|
938 | -- else |
---|
939 | -- Next_stInit2 <=SendPeerStat; |
---|
940 | -- end if; |
---|
941 | else |
---|
942 | TimeOut_i<=TimeOut+1; |
---|
943 | end if; |
---|
944 | |
---|
945 | When GetMainReq => if RankAsked='1' and PeerStat(PeerPort)='0' then |
---|
946 | Next_stInit2 <=NewRank; -- un nouveau rang est demandé |
---|
947 | else |
---|
948 | Next_stInit2 <=ReadNoC; -- sinon essayer encore de lire un jeu de données. |
---|
949 | end if; |
---|
950 | When NewRank => |
---|
951 | Next_stInit2 <=SendRank; |
---|
952 | When SendRank => |
---|
953 | if I_Send_RDY='1' then --RankSent |
---|
954 | Next_stInit2 <=RegRank; |
---|
955 | RankSent_i<='1'; -- le rang a été envoyé |
---|
956 | TimeOut_i<=0; -- prépare le traitement de la prochaine requête |
---|
957 | -- d'attente des ports |
---|
958 | elsif Timeout=800 then |
---|
959 | assert true report "Impossible d'envoyer le rang" |
---|
960 | severity failure; |
---|
961 | timeout_i<=0; |
---|
962 | else |
---|
963 | TimeOut_i<=TimeOut+1; |
---|
964 | end if; |
---|
965 | When RegRank => |
---|
966 | --il faut prévoir du code pour s'assurer que la RAM a bien enregistrer |
---|
967 | -- la donnée ... |
---|
968 | if dma_wr_grant = '1' then |
---|
969 | -- if DS_RDY='1' then |
---|
970 | RankSent_i<='0'; |
---|
971 | if DS_RDY='0' then |
---|
972 | |
---|
973 | Next_stInit2 <=ReadNoc; |
---|
974 | end if; |
---|
975 | elsif Timeout=800 then |
---|
976 | Next_stInit2 <=SendApp; |
---|
977 | else |
---|
978 | TimeOut_i<=TimeOut+1; |
---|
979 | -- end if; -- il est envisagée |
---|
980 | end if; |
---|
981 | --calcul de la taille de l'appli |
---|
982 | HtLoc:=0; |
---|
983 | for i in 0 to 7 loop |
---|
984 | if peerStat(i)='1' then --trouve le prochai rang libre |
---|
985 | HtLoc:=HtLoc+1; |
---|
986 | end if; |
---|
987 | end loop; |
---|
988 | AppSize_i<=std_logic_vector(to_unsigned(HtLoc,4)); |
---|
989 | |
---|
990 | When SendPeerStat => |
---|
991 | |
---|
992 | if cpt<=unsigned(NoCMax)and LastPort='0' then |
---|
993 | if peerRts='0' then -- pas encore envoyer les données alors les préparer |
---|
994 | if StatAsked='1' then |
---|
995 | |
---|
996 | PortStat<=PortNum_i; |
---|
997 | vPortStat:=std_logic_vector(to_unsigned(PeerPort,4)); |
---|
998 | else |
---|
999 | PortStat<=std_logic_vector(to_unsigned(cpt,4));--Port à contacter |
---|
1000 | vPortStat:=std_logic_vector(to_unsigned(cpt,4)); |
---|
1001 | end if; |
---|
1002 | |
---|
1003 | if StatAsked='1' then |
---|
1004 | LastPort:='1'; -- on traite u seul port celui qui en a fait la demande |
---|
1005 | if PeerStat(PeerPort)='1' then |
---|
1006 | PeerRts<='1'; |
---|
1007 | end if; |
---|
1008 | else |
---|
1009 | if (PeerStat(cpt)='1') and not(vPortStat=MyPort) then |
---|
1010 | PeerRts<='1'; |
---|
1011 | end if; |
---|
1012 | if cpt<unsigned(NoCMax) then |
---|
1013 | cpt_peer<=cpt+1; |
---|
1014 | LastPort:='0'; |
---|
1015 | else |
---|
1016 | if LastPort='0' then |
---|
1017 | LastPort:='1'; |
---|
1018 | cpt_peer<=cpt+1;--ceci permet de déclencher l'évaluation du process |
---|
1019 | end if; |
---|
1020 | end if; |
---|
1021 | end if; |
---|
1022 | TimeOut_i<=0; |
---|
1023 | else |
---|
1024 | if I_Send_RDY='1' then |
---|
1025 | |
---|
1026 | RankSent_i<='1'; -- les stat ont été envoyé |
---|
1027 | TimeOut_i<=0; -- prépare le traitement de la prochaine requête |
---|
1028 | PeerRts<='0'; -- d'attente des ports |
---|
1029 | elsif TimeOut_i=800 then |
---|
1030 | Next_stInit2 <=EndInit ;-- impossible d'envoyer sur le NoC |
---|
1031 | else |
---|
1032 | TimeOut_i<=TimeOut_i+1; |
---|
1033 | end if; |
---|
1034 | end if; |
---|
1035 | elsif PeerRTS='1' then -- le dernier port est il activé ? |
---|
1036 | if I_Send_RDY='1' then |
---|
1037 | RankSent_i<='1'; -- les stat ont été envoyé |
---|
1038 | TimeOut_i<=0; -- prépare le traitement de la prochaine requête |
---|
1039 | PeerRts<='0'; |
---|
1040 | if statAsked='1' then |
---|
1041 | -- Next_stInit2<=ReadNoc; |
---|
1042 | |
---|
1043 | Next_stInit2<=SendApp; --terminer l'application |
---|
1044 | end if; |
---|
1045 | |
---|
1046 | elsif TimeOut=100 then |
---|
1047 | Next_stInit2 <=EndInit; |
---|
1048 | else |
---|
1049 | TimeOut_i<=TimeOut+1; |
---|
1050 | end if; |
---|
1051 | else |
---|
1052 | Next_stInit2<=SendApp; |
---|
1053 | end if; |
---|
1054 | When SendApp => -- envoyer au programme un signal |
---|
1055 | -- et attendre un acquittement et l'adresse de base |
---|
1056 | If AppAck='1' then |
---|
1057 | Next_stInit2 <=EndInit; |
---|
1058 | end if; |
---|
1059 | |
---|
1060 | When SpawnLoad => |
---|
1061 | |
---|
1062 | if n=0 then |
---|
1063 | ht_id:=to_integer(unsigned(rec_data(0)(3 downto 0))); |
---|
1064 | vPeerStat_i<=PeerStat; --récupérer la situation actuelle des tâches créées |
---|
1065 | if IsMain_i='1' and SpawnInit='0' then |
---|
1066 | SpawnNbReq<=to_integer(unsigned(Instruction(3 downto 0))); -- sauver le nombre de HT à créer |
---|
1067 | |
---|
1068 | n_i<=1; |
---|
1069 | SpawnReq(ht_id)<='1'; --Note l'id de HT qui a appelé le Spawn |
---|
1070 | elsif IsMain_i='1' and SpawnInit='1' then -- il faut envoyer les acquittements |
---|
1071 | ht_id:=to_integer(unsigned(rec_data(0)(3 downto 0))); |
---|
1072 | Spawn_grp(grp_id)(ht_id)<='1'; --noter le port du Fils Spawné dans ce groupe |
---|
1073 | Ht_start_i<=0; --compte le nombre de tâches chargées |
---|
1074 | n_i<=6; |
---|
1075 | |
---|
1076 | else |
---|
1077 | if SpawnOn='1' then --if IsMain_i='0' then -- il faut juste charger puis activer la tâche |
---|
1078 | n_i<=7; |
---|
1079 | end if; |
---|
1080 | assert true |
---|
1081 | Report "SpawnLoad : Cas non prévu !" |
---|
1082 | severity failure; |
---|
1083 | end if; |
---|
1084 | elsif n=1 then |
---|
1085 | if PeerStat=SpawnReq then --tous les Hts ont appelés Spawn ? |
---|
1086 | ht_hole:='0'; |
---|
1087 | L1: for i in 0 to 15 loop |
---|
1088 | if vPeerStat(i)='0' then |
---|
1089 | SpawnDest<=std_logic_vector(to_unsigned(i,4)); -- le port à activer |
---|
1090 | SpawnCmd0<=MPI_SPAWN & std_logic_vector(to_unsigned(i,4)); |
---|
1091 | vPeerStat_i(i)<='1'; |
---|
1092 | Ht_Start_i<=Ht_Start+1; |
---|
1093 | Ht_Hole:='1'; -- une place a été trouvé |
---|
1094 | else |
---|
1095 | Ht_hole:='0'; -- pas de place trouvé |
---|
1096 | end if; |
---|
1097 | exit L1 when ht_hole='1'; |
---|
1098 | end loop L1; |
---|
1099 | if Ht_hole='0' then -- toutes les tâches n'ont pas été créés |
---|
1100 | -- aller à la fin ! en signalant une erreur! |
---|
1101 | SpawnCMd2<=Spawn_Err & "0001"; --erreur pas assez de ports sur le NoC |
---|
1102 | n_i<=9; |
---|
1103 | else |
---|
1104 | n_i<=n+1; |
---|
1105 | SpawnCmd1<=PeerStat(7 downto 0); |
---|
1106 | SpawnCmd2<=SPAWN_START & MyPort; |
---|
1107 | end if; |
---|
1108 | else --Tous les Hts n'ont pas appelé Spawn encore |
---|
1109 | Next_stInit2<=SendApp; --on termine normalement |
---|
1110 | n_i<=0; |
---|
1111 | end if; |
---|
1112 | elsif n=2 then |
---|
1113 | PeerRTS<='1'; -- envoyer les données du Spawn |
---|
1114 | n_i<=n+1; |
---|
1115 | elsif n=3 then |
---|
1116 | if I_Send_RDy='1' then |
---|
1117 | n_i<=n+1; |
---|
1118 | PeerRts<='0'; |
---|
1119 | end if; |
---|
1120 | elsif n=4 then |
---|
1121 | if SpawnInit='0' then |
---|
1122 | if Ht_Start>=SpawnNbReq then |
---|
1123 | n_i<=n+1; |
---|
1124 | else |
---|
1125 | n_i<=1; -- passer à la création du HT suivant |
---|
1126 | end if; |
---|
1127 | else |
---|
1128 | n_i<=7; -- passer au contact du HT suivant |
---|
1129 | end if; |
---|
1130 | elsif n=5 then |
---|
1131 | -- Aller à la fin le résultat du Spawn |
---|
1132 | |
---|
1133 | n_i<=10; |
---|
1134 | elsif n=6 then |
---|
1135 | nbSpawn:=0; |
---|
1136 | for i in 0 to 15 loop |
---|
1137 | if Spawn_grp(grp_id)(i)='1' then |
---|
1138 | nbSpawn:=nbSpawn+1; |
---|
1139 | end if; |
---|
1140 | end loop; |
---|
1141 | if nbSpawn=SpawnNbReq then |
---|
1142 | n_i<=n+1; --aller renvoyer les réponses |
---|
1143 | else |
---|
1144 | n_i<=10; --fin du Spawn |
---|
1145 | |
---|
1146 | end if; |
---|
1147 | elsif n=7 then |
---|
1148 | Ht_hole:='0'; |
---|
1149 | L2: for i in 0 to 7 loop --for i in Ht_start to 7 loop |
---|
1150 | if i>=Ht_start then |
---|
1151 | if vPeerStat(i)='1' and Spawn_grp(grp_id)(i)='0' then --on avertit les membres du groupe parent |
---|
1152 | --mais pas ceux du groupe Fils ! |
---|
1153 | SpawnDest<=std_logic_vector(to_unsigned(i,4)); -- le port à avertir |
---|
1154 | SpawnCmd0<=MPI_ACK & std_logic_vector(to_unsigned(i,4)); |
---|
1155 | vPeerStat_i(i)<='0'; |
---|
1156 | Ht_Start_i<=i+1; -- le prochain Ht à prévenir |
---|
1157 | Ht_Hole:='1'; -- Une tâche doit être avertie |
---|
1158 | else |
---|
1159 | Ht_hole:='0'; -- |
---|
1160 | end if; |
---|
1161 | end if; |
---|
1162 | exit L2 when ht_hole='1'; |
---|
1163 | end loop L2; |
---|
1164 | n_i<=n+1; |
---|
1165 | elsif n=8 then |
---|
1166 | if Ht_hole='1' then -- |
---|
1167 | -- un HT existant à prévenir ! |
---|
1168 | SpawnCmd1<=Spawn_grp(grp_id)(7 downto 0); |
---|
1169 | SpawnCMd2<=MPI_SPAWN & MyRank; -- fin du Spawn |
---|
1170 | n_i<=2; --envoyer la donnée sur le réseau |
---|
1171 | elsif vpeerstat /=spawn_grp(grp_id) then --il ne reste plus de membres à prévenir ? |
---|
1172 | n_i<=7; --on est sorti mais ce n'est pas la fin |
---|
1173 | |
---|
1174 | else -- fin du Spawn car tous ont été averti |
---|
1175 | n_i<=10; |
---|
1176 | SpawnNbReq<=0; |
---|
1177 | SpawnReq<=(others=>'0'); |
---|
1178 | vPeerStat_i<=(others=>'0'); |
---|
1179 | grp_id_i<=grp_id+1; --incrementer le compteur de groupes************ |
---|
1180 | end if; |
---|
1181 | elsif n=9 then |
---|
1182 | assert true report "error in Spawn command" |
---|
1183 | severity failure; |
---|
1184 | elsif n=10 then |
---|
1185 | n_i<=0; |
---|
1186 | Next_stInit2<=SendApp; |
---|
1187 | end if; |
---|
1188 | |
---|
1189 | When SpawnApp=> |
---|
1190 | --Mise à jour du bit 6 du registre status du COre. |
---|
1191 | if n>=0 and n <4 then |
---|
1192 | |
---|
1193 | dma_wr<='1'; --demander un accès exclusif au bus |
---|
1194 | dma_rd<='1'; -- pour éviter une mauvaise mise à jour des données |
---|
1195 | else |
---|
1196 | dma_wr<='0'; |
---|
1197 | dma_rd<='0'; |
---|
1198 | end if; |
---|
1199 | |
---|
1200 | if n=0 then |
---|
1201 | if DS_RDY='1' then --- |
---|
1202 | if Datareceived(3)(7 downto 4)=SPAWN_START then |
---|
1203 | n_i<=n+1; |
---|
1204 | else |
---|
1205 | Next_stInit2<=ErrSpawn; |
---|
1206 | n_i<=0; --erreur instruction incorrecte |
---|
1207 | end if; |
---|
1208 | |
---|
1209 | rd_ok<='1'; |
---|
1210 | wr_ok<='0'; |
---|
1211 | end if; |
---|
1212 | elsif n=1 or n=2 then |
---|
1213 | if dma_rd_grant='1' then |
---|
1214 | n_i<=n+1; |
---|
1215 | tempval:=Ram_data_out; |
---|
1216 | end if; |
---|
1217 | rd_ok<='1'; |
---|
1218 | wr_ok<='0'; |
---|
1219 | |
---|
1220 | elsif n=3 then |
---|
1221 | if dma_rd_grant='1' and dma_wr_grant='1' then |
---|
1222 | n_i<=n+1; |
---|
1223 | tempval:=Ram_data_out; |
---|
1224 | tempval(6):='1'; |
---|
1225 | |
---|
1226 | dataToram<=tempval; |
---|
1227 | rd_ok<='0'; |
---|
1228 | wr_ok<='1'; |
---|
1229 | else |
---|
1230 | rd_ok<='1'; |
---|
1231 | wr_ok<='0'; |
---|
1232 | end if; |
---|
1233 | elsif n=4 then |
---|
1234 | if spawninit='0' then |
---|
1235 | Spawn_done<='1'; |
---|
1236 | end if; |
---|
1237 | rd_ok<='0'; |
---|
1238 | wr_ok<='0'; |
---|
1239 | n_i<=0; |
---|
1240 | Next_stInit2<=EndInit; |
---|
1241 | end if; |
---|
1242 | |
---|
1243 | When ErrSpawn => |
---|
1244 | assert true |
---|
1245 | report "Ex4/stInit2/SpawnApp:Erreur lors de Spawn" |
---|
1246 | severity failure; |
---|
1247 | Next_stInit2<=Init; |
---|
1248 | When EndInit=> |
---|
1249 | |
---|
1250 | StatAsked_i<='0'; --reset de ces variables |
---|
1251 | Next_stInit2<=Init; |
---|
1252 | end case; |
---|
1253 | end process; |
---|
1254 | |
---|
1255 | --================================================ |
---|
1256 | --sauvegarde du rang et du main port à l'adresse de retour de la fonction Init |
---|
1257 | --================================================== |
---|
1258 | |
---|
1259 | --==================================================== |
---|
1260 | --envoie des données sur le port |
---|
1261 | --=================================================== |
---|
1262 | selector<=(Rcv_on,Cmd_on,Snd_on); |
---|
1263 | |
---|
1264 | process (selector,Rport_out_rd_en,cport_out_rd_en,sPort_in_wr_en ,cPort_in_wr_en, |
---|
1265 | tosend ,tosend4) |
---|
1266 | begin |
---|
1267 | case selector is |
---|
1268 | |
---|
1269 | when "000" => port_in_data<=(others=>'-'); |
---|
1270 | Port_in_wr_en<='0'; |
---|
1271 | Port_out_rd_en<='0'; |
---|
1272 | |
---|
1273 | when "001" => port_in_data<=tosend; --envoie de données |
---|
1274 | Port_in_wr_en<=sPort_in_wr_en ; |
---|
1275 | Port_out_rd_en<='0'; |
---|
1276 | when "101" => port_in_data<=tosend; --envoie de données |
---|
1277 | Port_in_wr_en<=sPort_in_wr_en ; |
---|
1278 | Port_out_rd_en<=Rport_out_rd_en ; |
---|
1279 | when "010" | "110" | "011" | "111" => |
---|
1280 | port_in_data<=tosend4; --envoie de commande GetPort |
---|
1281 | Port_in_wr_en<=cPort_in_wr_en; |
---|
1282 | Port_out_rd_en<=cport_out_rd_en; |
---|
1283 | |
---|
1284 | when "100" => port_in_data<=(others=>'-'); -- réception de données |
---|
1285 | Port_in_wr_en<='0'; |
---|
1286 | Port_out_rd_en<=Rport_out_rd_en ; |
---|
1287 | |
---|
1288 | when others => port_in_data<=(others=>'-'); |
---|
1289 | Port_in_wr_en<='0'; |
---|
1290 | Port_out_rd_en<='0'; |
---|
1291 | end case; |
---|
1292 | end process; |
---|
1293 | |
---|
1294 | --================================================== |
---|
1295 | |
---|
1296 | --=============================================================== |
---|
1297 | --processus d'accès au réseau |
---|
1298 | --=============================================================== |
---|
1299 | |
---|
1300 | |
---|
1301 | |
---|
1302 | |
---|
1303 | |
---|
1304 | preceiv:process(clk,reset) |
---|
1305 | |
---|
1306 | variable origport,destport : natural range 0 to 15; |
---|
1307 | variable dcount,dlen ,rtimeout:natural range 0 to 1023; |
---|
1308 | variable ptype : std_logic_vector(3 downto 0); |
---|
1309 | variable bad_paquet :std_logic:='0'; |
---|
1310 | begin |
---|
1311 | -- |
---|
1312 | |
---|
1313 | if reset='1' then |
---|
1314 | etrec<=r_wait; |
---|
1315 | destport:=1; |
---|
1316 | rtimeout:=0; |
---|
1317 | bad_paquet:='0'; |
---|
1318 | else |
---|
1319 | if rising_edge(clk) then |
---|
1320 | case etrec is |
---|
1321 | when r_wait => |
---|
1322 | |
---|
1323 | rtimeout:=0; |
---|
1324 | bad_paquet:='0'; |
---|
1325 | --modifier le 01-08-pour gérer le Spawn |
---|
1326 | if Port_out_data_available='1' and Cmd_on='0' then |
---|
1327 | ptype:=port_out_data(7 downto 4); |
---|
1328 | origport:=to_integer(unsigned(port_out_data(3 downto 0))); |
---|
1329 | |
---|
1330 | if ptype=MPI_SPAWN and not(portnumflag='1') then |
---|
1331 | etrec<=r_dlen; --identification de la signature d'en tête valide |
---|
1332 | Datareceived(0)<=Port_out_data; --stocker l'entête |
---|
1333 | bad_paquet:='0'; |
---|
1334 | SpawnOn<='1'; --le spawn est actif |
---|
1335 | elsif Instruction_en='0' and CTR='0' and Hcl_init= '0' then |
---|
1336 | --il faut éliminer ce paquet qui est inoportun ! |
---|
1337 | Bad_paquet:='1'; |
---|
1338 | etrec<=r_dlen; --il faut ignorer cette donnée et quitter |
---|
1339 | dcount:=1; |
---|
1340 | elsif CTR='1' then |
---|
1341 | if ptype=MPI_INIT or ptype=INIT_SETRANK or ptype=INIT_SEEKMAIN or ptype=INIT_REGISTER then |
---|
1342 | etrec<=r_dlen; --identification de la signature d'en tête valide |
---|
1343 | Datareceived(0)<=Port_out_data; --stocker l'entête |
---|
1344 | bad_paquet:='0'; |
---|
1345 | else |
---|
1346 | --une donnée non attendue est présente sur le port |
---|
1347 | etrec<=r_dlen; --il faut ignorer cette donnée et quitter |
---|
1348 | dcount:=1; |
---|
1349 | bad_paquet:='1'; |
---|
1350 | Datareceived(0)<=(others=>'0'); |
---|
1351 | end if; |
---|
1352 | end if; |
---|
1353 | --elsif Port_out_data_available='1' and CTR='0' then |
---|
1354 | -- etrec<=r_drop; |
---|
1355 | else |
---|
1356 | |
---|
1357 | etrec<=r_wait; |
---|
1358 | end if; |
---|
1359 | DS_RDY<='0'; |
---|
1360 | When r_drop => -- ignorer les messages qui arrivent à ce noeud tant que |
---|
1361 | --l'application n'a pas été initialisée |
---|
1362 | if port_out_data_available='0' then |
---|
1363 | etrec<=r_end; |
---|
1364 | dcount:=0; |
---|
1365 | |
---|
1366 | end if; |
---|
1367 | |
---|
1368 | |
---|
1369 | |
---|
1370 | --Rport_out_rd_en<='1'; --lire les données qui sont dans le tampon de sortie |
---|
1371 | DS_RDY<='0'; |
---|
1372 | when r_Dlen => --positionnement du mot de longueur des données |
---|
1373 | if Port_out_data_available ='1' then |
---|
1374 | |
---|
1375 | --Rport_out_rd_en<='1'; |
---|
1376 | etrec<=r_glen; |
---|
1377 | rtimeout:=0; |
---|
1378 | else |
---|
1379 | rtimeout:=rtimeout+1; |
---|
1380 | if rtimeout>=30 then |
---|
1381 | Exectime_out<='0'; --read Noc time out |
---|
1382 | etrec<=r_end; -- données pas prêtes |
---|
1383 | end if; |
---|
1384 | |
---|
1385 | |
---|
1386 | end if; |
---|
1387 | DS_RDY<='0'; |
---|
1388 | -- |
---|
1389 | when r_glen => --lecture effective de la longueur des données |
---|
1390 | if port_out_data_available='1' then |
---|
1391 | dlen:=to_integer(unsigned(port_out_data(Word-1 downto 0))); |
---|
1392 | Datareceived(1)<=Port_out_data; |
---|
1393 | --RPort_out_rd_en<='0'; |
---|
1394 | etrec<=r_data; |
---|
1395 | dcount:=2; -- initialisation du compteur de reception (il y a |
---|
1396 | -- déjà deux mots reçues |
---|
1397 | else |
---|
1398 | rtimeout:=rtimeout+1; |
---|
1399 | if rtimeout>=30 then |
---|
1400 | ExecTime_out<='0'; |
---|
1401 | etrec<=r_end; -- données pas prêtes |
---|
1402 | end if; |
---|
1403 | |
---|
1404 | end if; |
---|
1405 | DS_RDY<='0'; |
---|
1406 | when r_data => -- lecture des données |
---|
1407 | if port_out_data_available='1' then |
---|
1408 | |
---|
1409 | --Rport_out_rd_en<='1'; --autoriser la lecture |
---|
1410 | if bad_paquet='0' then |
---|
1411 | DataReceived(dcount)<=Port_out_data; --récupération des données |
---|
1412 | else |
---|
1413 | DataReceived(2)<=(others=>'0'); |
---|
1414 | --ignorer ces données |
---|
1415 | end if; |
---|
1416 | --assert true report "Donnée lue :"; --& string(unsigned(port4_out(Word-1 downto 0))) |
---|
1417 | DS_RDY<='0'; |
---|
1418 | dcount:=dcount+1; |
---|
1419 | --severity note; |
---|
1420 | if dlen <=dcount then -- ce doit être égale ici et non <= ??? |
---|
1421 | etrec<=r_end; |
---|
1422 | DS_RDY<= not bad_paquet; -- jeu de données disponibles |
---|
1423 | elsif dcount=255 then --dépassement de la capacité |
---|
1424 | DS_RDY<='0'; |
---|
1425 | etrec<=r_end; |
---|
1426 | end if; |
---|
1427 | else |
---|
1428 | rtimeout:=rtimeout+1; |
---|
1429 | if rtimeout>=30 then |
---|
1430 | ExecTime_out<='0'; |
---|
1431 | etrec<=r_end; -- données pas prêtes |
---|
1432 | end if; |
---|
1433 | DS_RDY<='0'; |
---|
1434 | |
---|
1435 | end if; |
---|
1436 | when r_pulse => |
---|
1437 | etrec<=r_end; |
---|
1438 | DS_RDY<=not bad_paquet; |
---|
1439 | when r_end => |
---|
1440 | |
---|
1441 | --rPort_out_rd_en <='0'; |
---|
1442 | |
---|
1443 | if DS_ACK='1' or rtimeout> 30 or (CTR='0' and SpawnOn='0') or bad_paquet='1' then |
---|
1444 | DS_RDY<='0'; |
---|
1445 | SpawnOn<='0'; |
---|
1446 | etrec<=r_wait; |
---|
1447 | else |
---|
1448 | DS_RDY<=DS_RDY; |
---|
1449 | end if; |
---|
1450 | end case; |
---|
1451 | end if;--reset='1' |
---|
1452 | end if; |
---|
1453 | end process preceiv; |
---|
1454 | |
---|
1455 | val_preceiv: process (etrec) |
---|
1456 | begin |
---|
1457 | case etrec is |
---|
1458 | when r_wait => |
---|
1459 | -- DS_RDY<='0'; |
---|
1460 | |
---|
1461 | Rport_out_rd_en <='0'; |
---|
1462 | when r_dlen => |
---|
1463 | -- DS_RDY<='0'; |
---|
1464 | Rport_out_rd_en <='1'; |
---|
1465 | rcv_On<='1'; |
---|
1466 | when r_drop => |
---|
1467 | -- DS_RDY<='0'; |
---|
1468 | Rport_out_rd_en <='1'; |
---|
1469 | rcv_On<='1'; |
---|
1470 | when r_glen => |
---|
1471 | Rport_out_rd_en <='1'; |
---|
1472 | -- DS_RDY<='0'; |
---|
1473 | rcv_On<='1'; |
---|
1474 | when r_data => |
---|
1475 | Rport_out_rd_en <='1'; |
---|
1476 | -- DS_RDY<='0'; |
---|
1477 | rcv_On<='1'; |
---|
1478 | when r_pulse => |
---|
1479 | Rport_out_rd_en <='0'; |
---|
1480 | rcv_On<='1'; |
---|
1481 | -- DS_RDY<='1'; |
---|
1482 | when r_end => |
---|
1483 | Rport_out_rd_en <='0'; |
---|
1484 | -- DS_RDY<='0'; |
---|
1485 | rcv_On<='0'; |
---|
1486 | when others => |
---|
1487 | Rport_out_rd_en <='0'; |
---|
1488 | -- DS_RDY<='0'; |
---|
1489 | rcv_On<='0'; |
---|
1490 | end case; |
---|
1491 | end process; |
---|
1492 | |
---|
1493 | psend:process(clk,reset) |
---|
1494 | --génération des paquets à partir du port courant |
---|
1495 | variable pactype :natural range 0 to 15; |
---|
1496 | variable destport : natural range 0 to 15:=0; |
---|
1497 | variable realdlen, i,i_pair : natural range 0 to 255; |
---|
1498 | variable MaxPort : natural :=4; -- en fait ne doit pas être 0 |
---|
1499 | |
---|
1500 | |
---|
1501 | begin |
---|
1502 | if rising_edge(clk) then |
---|
1503 | if reset='1' then |
---|
1504 | etsnd<=s_init; |
---|
1505 | |
---|
1506 | |
---|
1507 | |
---|
1508 | else -- le process s'exécute sur chaque front |
---|
1509 | -- montant de l'horloge |
---|
1510 | case etsnd is |
---|
1511 | when s_init => tosend<=(others=>'-'); |
---|
1512 | MaxPort :=to_integer(unsigned(NOCMAX)); |
---|
1513 | sPort_in_wr_en<='0'; |
---|
1514 | if port_in_full='0' and Rts_dat='1' then --on peut aussi tester si le port est vide |
---|
1515 | BCast_RDY<='0'; -- pas la fin de du Broadcasting |
---|
1516 | Send_RDY<='0'; |
---|
1517 | Snd_on<='1'; |
---|
1518 | if Bcast='1' then -- envoyer à tous les ports le même message ? |
---|
1519 | DestPort :=0; |
---|
1520 | else |
---|
1521 | DestPort:=to_integer(unsigned(DataToSend(0)(3 downto 0))); |
---|
1522 | end if; |
---|
1523 | etsnd<=s_head; |
---|
1524 | end if; |
---|
1525 | when s_head => -- construction et envoie de l'en-tête |
---|
1526 | Send_RDY<='0'; --l'envoi commence |
---|
1527 | BCast_RDY<='0'; |
---|
1528 | Snd_on<='1'; |
---|
1529 | --pactype:=to_integer(MPI_INIT);-- |
---|
1530 | pactype:=to_integer(unsigned(DataToSend(0)(7 downto 4))); |
---|
1531 | --realdlen:=to_integer(unsigned(Datalen)); |
---|
1532 | --? destport:=MAXPORT; -- le port de destination |
---|
1533 | |
---|
1534 | tosend <=STD_LOGIC_VECTOR(to_unsigned(pactype,4)) & STD_LOGIC_VECTOR(to_unsigned(destport,4)); |
---|
1535 | sPort_in_wr_en<='1'; -- |
---|
1536 | |
---|
1537 | i:=1; |
---|
1538 | etsnd<=s_len2; -- passer à l'état suivant |
---|
1539 | |
---|
1540 | when s_len => |
---|
1541 | BCast_RDY<='0'; |
---|
1542 | Send_RDY<='0'; |
---|
1543 | Snd_on<='1'; |
---|
1544 | --tosend<=(STD_LOGIC_VECTOR(to_unsigned(Realdlen,8))); |
---|
1545 | tosend<=DataToSend(1); |
---|
1546 | sPort_in_wr_en <='1'; |
---|
1547 | |
---|
1548 | |
---|
1549 | --port1_in<=tosend1; --copie directe sur le port |
---|
1550 | etsnd<=s_len2; |
---|
1551 | when s_len2 => |
---|
1552 | --tosend<=(STD_LOGIC_VECTOR(to_unsigned(realdlen,8))); |
---|
1553 | sPort_in_wr_en<='1'; |
---|
1554 | tosend<=DataToSend(1); |
---|
1555 | |
---|
1556 | --port1_in<=tosend1; --copie directe sur le port |
---|
1557 | etsnd<=s_data; |
---|
1558 | BCast_RDY<='0'; |
---|
1559 | Send_RDY<='0'; |
---|
1560 | Snd_on<='1'; |
---|
1561 | i:=i+1; |
---|
1562 | when s_data => |
---|
1563 | Snd_on<='1'; |
---|
1564 | if Port_in_full='0' and RTS_dat='1' then |
---|
1565 | sPort_in_wr_en<='1'; |
---|
1566 | |
---|
1567 | --envoie des données sur le port |
---|
1568 | tosend<=DataToSend(i); |
---|
1569 | |
---|
1570 | |
---|
1571 | if i+1>=datalen then |
---|
1572 | etsnd<=s_end; |
---|
1573 | Send_RDY<='1'; --l'envoi est terminé |
---|
1574 | if BCast='1' and destport=MAXPort then |
---|
1575 | BCAST_RDY<='1'; --l'envoi collectif aussi |
---|
1576 | else |
---|
1577 | BCast_RDY<='0'; |
---|
1578 | |
---|
1579 | end if; |
---|
1580 | else |
---|
1581 | BCast_RDY<='0'; |
---|
1582 | Send_RDY<='0'; |
---|
1583 | i:=i+1; |
---|
1584 | end if; |
---|
1585 | elsif port_in_full='1' then |
---|
1586 | sPort_in_wr_en<='0'; |
---|
1587 | else |
---|
1588 | sPort_in_wr_en<='0'; |
---|
1589 | BCast_RDY<='0'; |
---|
1590 | Send_RDY<='0'; |
---|
1591 | end if; |
---|
1592 | when s_end => |
---|
1593 | tosend<=(others=>'-'); |
---|
1594 | |
---|
1595 | sPort_in_wr_en<='0'; |
---|
1596 | if Bcast='1' then |
---|
1597 | if destPort<Maxport then |
---|
1598 | DestPort:=Destport+1; |
---|
1599 | etsnd<=s_head; |
---|
1600 | |
---|
1601 | else |
---|
1602 | BCast_RDY<='1' ; -- BroadCast End=Ok |
---|
1603 | if Send_ack='1' then |
---|
1604 | etsnd<=s_init; |
---|
1605 | Send_RDY<='0'; |
---|
1606 | Snd_on<='0'; |
---|
1607 | end if; |
---|
1608 | end if; |
---|
1609 | else |
---|
1610 | BCast_RDY<='0'; |
---|
1611 | if Send_ack='1' then |
---|
1612 | etsnd<=s_init; |
---|
1613 | Send_RDY<='0'; |
---|
1614 | Snd_on<='0'; |
---|
1615 | end if; |
---|
1616 | |
---|
1617 | end if; |
---|
1618 | end case; |
---|
1619 | |
---|
1620 | |
---|
1621 | end if; --reset ='1' |
---|
1622 | end if; --rising_edge... |
---|
1623 | end process psend; |
---|
1624 | |
---|
1625 | -- envoi des commandes |
---|
1626 | pcmd:process(clk,reset) |
---|
1627 | |
---|
1628 | variable origport,destport,pid,mport : natural range 0 to 15; |
---|
1629 | variable ctimeout:natural range 0 to 255; |
---|
1630 | begin |
---|
1631 | |
---|
1632 | |
---|
1633 | if reset='1' then |
---|
1634 | etcmd<=cmdstart; |
---|
1635 | |
---|
1636 | -- sorigport<=origport; |
---|
1637 | else |
---|
1638 | if rising_edge(clk) then |
---|
1639 | case etcmd is |
---|
1640 | when cmdstart => |
---|
1641 | if Port_in_empty='1' and RTS_Cmd='1' then |
---|
1642 | etcmd<=cmdpost; |
---|
1643 | |
---|
1644 | end if; |
---|
1645 | destport:=0; |
---|
1646 | ctimeout:=0; |
---|
1647 | origport:=1; |
---|
1648 | when cmdpost => |
---|
1649 | if Port_in_empty='1' then |
---|
1650 | etcmd<=cmdread; |
---|
1651 | end if; |
---|
1652 | |
---|
1653 | when cmdpostidle => --permet juste la prise en compte de la commande |
---|
1654 | etcmd<=cmdread; |
---|
1655 | dcount<=0;-- initialisation du compteur de reception |
---|
1656 | when cmdread => |
---|
1657 | |
---|
1658 | |
---|
1659 | ctimeout:=0; |
---|
1660 | |
---|
1661 | if Port_out_data_available='1' then |
---|
1662 | mport:=to_integer(unsigned(port_out_data(7 downto 4))); |
---|
1663 | pid:=to_integer(unsigned(port_out_data(3 downto 0)))+1; |
---|
1664 | CmdReceived(dcount)<=port_out_data; |
---|
1665 | --cdata_out_en(origport)<='1'; |
---|
1666 | -- if pid=origport then --le port a été bien identifié |
---|
1667 | etcmd<=cmdglen; -- |
---|
1668 | dcount<=dcount+1; |
---|
1669 | -- else |
---|
1670 | -- etcmd<=cmdtimeout; |
---|
1671 | -- end if; |
---|
1672 | else |
---|
1673 | |
---|
1674 | etcmd<=cmdread; |
---|
1675 | end if; |
---|
1676 | |
---|
1677 | |
---|
1678 | when cmdlen => --positionnement du mot de longueur des données |
---|
1679 | if Port_out_data_available='1' then |
---|
1680 | |
---|
1681 | etcmd<=cmdglen; |
---|
1682 | ctimeout:=0; |
---|
1683 | else |
---|
1684 | ctimeout:=ctimeout+1; |
---|
1685 | if ctimeout>=30 then |
---|
1686 | etcmd<=cmdtimeout; -- données pas prêtes |
---|
1687 | end if; |
---|
1688 | |
---|
1689 | |
---|
1690 | end if; |
---|
1691 | when cmdglen => --lecture effective de la longueur des données |
---|
1692 | if Port_out_data_available='1' then |
---|
1693 | cdlen<=to_integer(unsigned(port_out_data(Word-1 downto 0))); |
---|
1694 | CmdReceived(dcount)<=port_out_data; |
---|
1695 | etcmd<=cmddata; |
---|
1696 | dcount<=dcount+1; |
---|
1697 | else |
---|
1698 | ctimeout:=ctimeout+1; |
---|
1699 | if ctimeout>=30 then |
---|
1700 | --time_out(destport)<='1'; |
---|
1701 | etcmd<=cmdtimeout; -- données pas prêtes |
---|
1702 | end if; |
---|
1703 | |
---|
1704 | end if; |
---|
1705 | |
---|
1706 | when cmddata => |
---|
1707 | if (port_out_data_available='1' and ctimeout<30) then |
---|
1708 | |
---|
1709 | --cdata_out_en(origport)<='1'; |
---|
1710 | mport:=to_integer(unsigned(port_out_data(7 downto 4))); |
---|
1711 | --attention les ports sont numérotés à partir de 0 |
---|
1712 | pid:=to_integer(unsigned(port_out_data(3 downto 0)))+1; |
---|
1713 | CmdReceived(dcount)<=port_out_data; |
---|
1714 | if (dcount>=cdlen-1 ) then--attention le compteur de données commence à 0 |
---|
1715 | etcmd<=cmdend; |
---|
1716 | --CM_RDY<='1'; |
---|
1717 | else |
---|
1718 | dcount<=dcount+1; |
---|
1719 | end if; |
---|
1720 | Else |
---|
1721 | |
---|
1722 | if ctimeout>=30 then |
---|
1723 | --time_out(destport)<='1'; |
---|
1724 | etcmd<=cmdtimeout; -- données pas prêtes |
---|
1725 | else |
---|
1726 | ctimeout:=ctimeout+1; |
---|
1727 | etcmd<=cmdend; |
---|
1728 | end if; |
---|
1729 | end if; |
---|
1730 | when cmdend => |
---|
1731 | |
---|
1732 | etcmd<=cmdstart; |
---|
1733 | |
---|
1734 | when cmdtimeout => |
---|
1735 | |
---|
1736 | etcmd<=cmdstart; |
---|
1737 | end case; |
---|
1738 | --sorigport<=origport; |
---|
1739 | end if; --reset='1' |
---|
1740 | end if; |
---|
1741 | end process pcmd; |
---|
1742 | |
---|
1743 | majetcmd: process (etcmd,DataToSend, port_out_data_available, dcount,port_out_data) |
---|
1744 | variable origport : natural; |
---|
1745 | variable i:natural:=0; |
---|
1746 | begin |
---|
1747 | case etcmd is |
---|
1748 | when cmdstart => |
---|
1749 | i:=0; |
---|
1750 | Port_in_cmd_en<='0'; |
---|
1751 | tosend4<=(others=>'-'); |
---|
1752 | cport_out_rd_en<='0'; |
---|
1753 | cport_in_wr_en<='0'; |
---|
1754 | CM_RDY<='0'; |
---|
1755 | Cmd_on<='0'; |
---|
1756 | when cmdpost | cmdpostidle => |
---|
1757 | cport_in_wr_en<='1'; |
---|
1758 | tosend4<=DataToSend(0); ---code pour getportid |
---|
1759 | Port_in_cmd_en<='1'; |
---|
1760 | cport_out_rd_en<='0'; |
---|
1761 | CM_RDY<='0'; |
---|
1762 | Cmd_on<='1'; |
---|
1763 | when cmdread => |
---|
1764 | tosend4<=(others=>'-'); |
---|
1765 | cPort_in_wr_en<='0'; |
---|
1766 | cport_out_rd_en<=port_out_data_available; |
---|
1767 | --CmdReceived(dcount)<=port_out_data; --mettre les données dans le tampon |
---|
1768 | Port_in_cmd_en<='1'; |
---|
1769 | CM_RDY<='0'; |
---|
1770 | Cmd_on<='1'; |
---|
1771 | when cmdlen |cmdglen => --positionnement du mot de longueur des données |
---|
1772 | tosend4<=(others=>'-'); |
---|
1773 | cport_in_wr_en<='0'; |
---|
1774 | cport_out_rd_en<=port_out_data_available; |
---|
1775 | Port_in_cmd_en<='1'; |
---|
1776 | --CmdReceived(dcount)<= port_out_data; |
---|
1777 | CM_RDY<='0'; |
---|
1778 | Cmd_on<='1'; |
---|
1779 | when cmddata => |
---|
1780 | tosend4<=(others=>'-'); |
---|
1781 | cport_in_wr_en<='0'; |
---|
1782 | cport_out_rd_en<=Port_out_data_available; |
---|
1783 | Port_in_cmd_en<='1'; |
---|
1784 | --CmdReceived(dcount)<=port_out_data; --mettre les données dans le tampon |
---|
1785 | i:=i+1; |
---|
1786 | CM_RDY<='0'; |
---|
1787 | Cmd_on<='1'; |
---|
1788 | when cmdend => |
---|
1789 | tosend4<=(others=>'-'); |
---|
1790 | cport_in_wr_en<='0'; |
---|
1791 | cport_out_rd_en<='0'; |
---|
1792 | --CmdReceived(dcount)<=port_out_data; |
---|
1793 | Port_in_cmd_en<='0'; |
---|
1794 | CM_RDY<='1'; |
---|
1795 | Cmd_on<='0'; |
---|
1796 | when cmdtimeout => |
---|
1797 | tosend4<=(others=>'-'); |
---|
1798 | cport_in_wr_en<='0'; |
---|
1799 | cport_out_rd_en<='0'; |
---|
1800 | Port_in_cmd_en<='0'; |
---|
1801 | Cmd_on<='1'; |
---|
1802 | end case; |
---|
1803 | |
---|
1804 | end process majetcmd ; |
---|
1805 | |
---|
1806 | i_send_val:process(HCL_Init,Send_RDY,RTS_I,Snd_Ack,I_send_ack,DataToSend,Bcast_rdy,Bcast) |
---|
1807 | begin |
---|
1808 | snd_start_i<=snd_start; |
---|
1809 | if HCL_Init='1' then |
---|
1810 | if RTS_I='1' and snd_ack='0' then |
---|
1811 | snd_start_i<='1'; |
---|
1812 | elsif i_send_ack='1' then |
---|
1813 | |
---|
1814 | snd_start_i<='0'; |
---|
1815 | end if; |
---|
1816 | i_send_rdy<=snd_ack; |
---|
1817 | |
---|
1818 | Snd_data<=DataToSend; |
---|
1819 | else |
---|
1820 | if RTS_I='1' and i_send_ack='0' then |
---|
1821 | RTS_DAT<='1'; |
---|
1822 | elsif i_send_ack='1' then |
---|
1823 | |
---|
1824 | RTS_DAT<='0'; |
---|
1825 | end if; |
---|
1826 | i_send_rdy<=send_rdy; |
---|
1827 | for i in 0 to 3 loop |
---|
1828 | Snd_data(i)<=(others=>'0'); |
---|
1829 | end loop; |
---|
1830 | end if; |
---|
1831 | end process; |
---|
1832 | end Behavioral; |
---|
1833 | |
---|