1 |
2 |
DavidRAMBA |
--=============================================================================
|
2 |
|
|
-- TITRE : STORE_FRAMETXDMA
|
3 |
|
|
-- DESCRIPTION :
|
4 |
|
|
-- Stocke une trame émise par le PIC dans un buffer tournant
|
5 |
|
|
-- On écrit le nombre d 'octets au début de la zone
|
6 |
|
|
-- FICHIER : store_frametxdma.vhd
|
7 |
|
|
--=============================================================================
|
8 |
|
|
-- CREATION
|
9 |
|
|
-- DATE AUTEUR PROJET REVISION
|
10 |
|
|
-- 10/04/2014 DRA SATURN V1.0
|
11 |
|
|
--=============================================================================
|
12 |
|
|
-- HISTORIQUE DES MODIFICATIONS :
|
13 |
|
|
-- DATE AUTEUR PROJET REVISION
|
14 |
|
|
--=============================================================================
|
15 |
|
|
|
16 |
|
|
LIBRARY IEEE;
|
17 |
|
|
USE IEEE.STD_LOGIC_1164.ALL;
|
18 |
|
|
USE IEEE.STD_LOGIC_ARITH.ALL;
|
19 |
|
|
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
|
20 |
|
|
|
21 |
|
|
LIBRARY work;
|
22 |
|
|
USE work.package_saturn.ALL;
|
23 |
|
|
|
24 |
|
|
ENTITY store_frametxdma IS
|
25 |
|
|
PORT (
|
26 |
|
|
clk_sys : IN STD_LOGIC; -- Horloge système
|
27 |
|
|
rst_n : IN STD_LOGIC; -- Reset général système
|
28 |
|
|
store_enable : IN STD_LOGIC; -- Autorise le stockage des trames incidentes
|
29 |
|
|
-- Interface de réception des trames Rx
|
30 |
|
|
data_store : IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- Données à stocker.
|
31 |
|
|
val_store : IN STD_LOGIC; -- Validant du bus data_store(signal write)
|
32 |
|
|
sof_store : IN STD_LOGIC; -- Indique und début de trame (nouvelle trame). Synchrone du 1er octet envoyé
|
33 |
|
|
eof_store : IN STD_LOGIC; -- Indique que la trame est finie (plus de données à envoyer)
|
34 |
|
|
|
35 |
|
|
-- Interface de restitution des trames enregistrées
|
36 |
|
|
frame_dispo : OUT STD_LOGIC; -- Indique qu'il y'a au moins une trame dispo à émettre
|
37 |
|
|
frame_data : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);-- Données à émettre (lue comme une FIFO en FWFT)
|
38 |
|
|
frame_rd : IN STD_LOGIC; -- Signal de lecture d'une donnée
|
39 |
|
|
overflow : OUT STD_LOGIC; -- Indique que le pointeur d'écriture a rattraper celui de lecture
|
40 |
|
|
timestamp : IN STD_LOGIC_VECTOR(7 DOWNTO 0) -- Pour timestamper la récetion des trames
|
41 |
|
|
);
|
42 |
|
|
END store_frametxdma;
|
43 |
|
|
|
44 |
|
|
ARCHITECTURE rtl of store_frametxdma is
|
45 |
|
|
CONSTANT nbbit_add8 : integer := 12; -- Nombre de bit du bus d'adresse du buffer
|
46 |
|
|
CONSTANT vecnull : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000";
|
47 |
|
|
|
48 |
|
|
SIGNAL cpt_adwr : STD_LOGIC_VECTOR(nbbit_add8-1 DOWNTO 0); -- Compteur et pointeur d'écriture
|
49 |
|
|
SIGNAL cpt_adrd : STD_LOGIC_VECTOR(nbbit_add8-2-1 DOWNTO 0);-- Compteur de lecture
|
50 |
|
|
SIGNAL old_adwr : STD_LOGIC_VECTOR(nbbit_add8-2-1 DOWNTO 0);-- 1er empalcement libre dans la mémoire
|
51 |
|
|
SIGNAL adread : STD_LOGIC_VECTOR(nbbit_add8-2-1 DOWNTO 0);-- Pointeur de lecture
|
52 |
|
|
SIGNAL cpt_byte : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Compteur d'octet dans une trame
|
53 |
|
|
SIGNAL data_wr : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Donnée à écrire dans la DPRAM
|
54 |
|
|
SIGNAL wr_dpram : STD_LOGIC; -- Signal d'écriture dans la DPRAM
|
55 |
|
|
SIGNAL wea : STD_LOGIC_VECTOR(0 DOWNTO 0);
|
56 |
|
|
|
57 |
|
|
TYPE fsm_write_type IS (idlewr_st, write_payload_st, store_cpt_st, clr_msbsize_st, gest_over_st); -- Machine d'état d'écriture d'une trame
|
58 |
|
|
SIGNAL fsm_write : fsm_write_type;
|
59 |
|
|
|
60 |
|
|
-- DPRAM de stockage
|
61 |
|
|
COMPONENT dpram_storerx
|
62 |
|
|
PORT (
|
63 |
|
|
clka : IN STD_LOGIC;
|
64 |
|
|
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
|
65 |
|
|
addra : IN STD_LOGIC_VECTOR(nbbit_add8-1 DOWNTO 0);
|
66 |
|
|
dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
67 |
|
|
douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
|
68 |
|
|
clkb : IN STD_LOGIC;
|
69 |
|
|
web : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
|
70 |
|
|
addrb : IN STD_LOGIC_VECTOR(nbbit_add8-2-1 DOWNTO 0);
|
71 |
|
|
dinb : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
|
72 |
|
|
doutb : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
|
73 |
|
|
);
|
74 |
|
|
END COMPONENT;
|
75 |
|
|
|
76 |
|
|
BEGIN
|
77 |
|
|
|
78 |
|
|
--------------------------------------------
|
79 |
|
|
-- Gestion du compteur d'adresse de la DPRAM en lecture
|
80 |
|
|
--------------------------------------------
|
81 |
|
|
cptr : PROCESS(clk_sys, rst_n)
|
82 |
|
|
BEGIN
|
83 |
|
|
IF (rst_n = '0') THEN
|
84 |
|
|
cpt_adrd <= (others => '0');
|
85 |
|
|
frame_dispo <= '0';
|
86 |
|
|
ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
|
87 |
|
|
IF (frame_rd = '1') THEN
|
88 |
|
|
-- A chaque donéne lue
|
89 |
|
|
cpt_adrd <= cpt_adrd + 1;
|
90 |
|
|
END IF;
|
91 |
|
|
IF (cpt_adrd /= old_adwr) THEN
|
92 |
|
|
-- Si le pointeur en lecture est différent du pointeur en écriture, on indique qu'il
|
93 |
|
|
-- y'a des données à traiter
|
94 |
|
|
frame_dispo <= '1';
|
95 |
|
|
ELSE
|
96 |
|
|
frame_dispo <= '0';
|
97 |
|
|
END IF;
|
98 |
|
|
END IF;
|
99 |
|
|
END PROCESS;
|
100 |
|
|
-- Permet d'avoir un fonctionnement style FWFT avec un seul cycle entre le rd et la donnée
|
101 |
|
|
adread <= cpt_adrd WHEN (frame_rd = '0') ELSE cpt_adrd+1;
|
102 |
|
|
|
103 |
|
|
--------------------------------------------
|
104 |
|
|
-- Machine d'état d'écriture du flux
|
105 |
|
|
--------------------------------------------
|
106 |
|
|
wr_fsm : PROCESS(clk_sys, rst_n)
|
107 |
|
|
VARIABLE temp : STD_LOGIC_VECTOR(nbbit_add8-1 DOWNTO 0);
|
108 |
|
|
BEGIN
|
109 |
|
|
IF (rst_n = '0') THEN
|
110 |
|
|
fsm_write <= idlewr_st;
|
111 |
|
|
cpt_adwr <= (others => '0');
|
112 |
|
|
old_adwr <= (others => '0');
|
113 |
|
|
cpt_byte <= (others => '0');
|
114 |
|
|
overflow <= '0';
|
115 |
|
|
wr_dpram <= '0';
|
116 |
|
|
ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
|
117 |
|
|
CASE fsm_write IS
|
118 |
|
|
WHEN idlewr_st =>
|
119 |
|
|
-- Etat d'attente d'un SOF
|
120 |
|
|
overflow <= '0';
|
121 |
|
|
IF (val_store = '1' AND sof_store = '1' AND store_enable = '1') THEN
|
122 |
|
|
-- Sur SOF et que le store est autorisé
|
123 |
|
|
cpt_adwr <= (old_adwr + 1) & "00"; -- On réserve un espace pour stocker la longueur
|
124 |
|
|
data_wr <= data_store; -- On va écrire la première donnée
|
125 |
|
|
wr_dpram <= '1'; -- On va écrire
|
126 |
|
|
cpt_byte <= x"01"; -- On a 1 octet utile
|
127 |
|
|
fsm_write <= write_payload_st;
|
128 |
|
|
ELSE
|
129 |
|
|
wr_dpram <= '0';
|
130 |
|
|
END IF;
|
131 |
|
|
|
132 |
|
|
WHEN write_payload_st =>
|
133 |
|
|
-- Etat d'attente du EOF
|
134 |
|
|
IF (wr_dpram = '1') AND ((cpt_adwr(nbbit_add8-1 DOWNTO 2) = cpt_adrd-4) OR
|
135 |
|
|
(cpt_adwr(nbbit_add8-1 DOWNTO 2) = cpt_adrd-3)) THEN
|
136 |
|
|
-- On a un overflow si on écrit et que le pointeur wr a rattrapé le pointeur rd
|
137 |
|
|
-- On teste par rapprot à 2 valeurs du pointeurs de lecture car sinon, le fonctionnement
|
138 |
|
|
-- en FWFT peut faire qu'on loupe une valeur
|
139 |
|
|
overflow <= '1';
|
140 |
|
|
wr_dpram <= '0';
|
141 |
|
|
IF (eof_store = '1') THEN
|
142 |
|
|
-- Si c'est également le dernier mot de la trame
|
143 |
|
|
fsm_write <= idlewr_st;
|
144 |
|
|
ELSE
|
145 |
|
|
-- Si c'est pas le derneir, on va attendre la fin de la trame
|
146 |
|
|
fsm_write <= gest_over_st;
|
147 |
|
|
END IF;
|
148 |
|
|
ELSE
|
149 |
|
|
IF (val_store = '1') THEN
|
150 |
|
|
-- A cqhaue nouvelle donnée
|
151 |
|
|
cpt_adwr <= cpt_adwr + 1; -- On va l'écrire à l'adresse suivante
|
152 |
|
|
cpt_byte <= cpt_byte + 1; -- On la compte
|
153 |
|
|
data_wr <= data_store; -- On l'écrit telle quelle
|
154 |
|
|
wr_dpram <= '1';
|
155 |
|
|
IF (eof_store = '1') THEN
|
156 |
|
|
-- Si c'était la dernière de la trame
|
157 |
|
|
fsm_write <= store_cpt_st;
|
158 |
|
|
END IF;
|
159 |
|
|
ELSE
|
160 |
|
|
wr_dpram <= '0';
|
161 |
|
|
END IF;
|
162 |
|
|
END IF;
|
163 |
|
|
|
164 |
|
|
WHEN store_cpt_st =>
|
165 |
|
|
-- Etat de stockage du nombre d'octets dans le LSB 1er mot de 32 bits
|
166 |
|
|
cpt_adwr <= old_adwr & "00"; -- On va stocker le nombre d'octets utiles dans les LSB du au début
|
167 |
|
|
data_wr <= cpt_byte; -- On garde toutes les données écrites
|
168 |
|
|
temp := cpt_adwr; -- On arrondit le nouveau pointeur d'écriture au multiple de 4 supérieur
|
169 |
|
|
old_adwr <= temp(nbbit_add8-1 DOWNTO 2) + 1;
|
170 |
|
|
wr_dpram <= '1';
|
171 |
|
|
fsm_write<= clr_msbsize_st;
|
172 |
|
|
|
173 |
|
|
WHEN clr_msbsize_st =>
|
174 |
|
|
-- Etat de fabrication des MSB du 1er mot de 32 bits
|
175 |
|
|
-- La première zone mémoire du bloc contient:
|
176 |
|
|
-- LSB : Taille du bloc
|
177 |
|
|
-- LSB+1 : 0
|
178 |
|
|
-- LSB+2 : 0
|
179 |
|
|
-- MSB : Timestamp
|
180 |
|
|
cpt_adwr(1 DOWNTO 0) <= cpt_adwr(1 DOWNTO 0) + 1;
|
181 |
|
|
IF (cpt_adwr(1 DOWNTO 0) = "10") THEN
|
182 |
|
|
-- On va écrire le time stamp dans les 8 MSB de la 1ère zone
|
183 |
|
|
data_wr <= timestamp;
|
184 |
|
|
fsm_write <= idlewr_st;
|
185 |
|
|
ELSE
|
186 |
|
|
-- On cleare les LSB+1 et LSB+2
|
187 |
|
|
data_wr <= x"00";
|
188 |
|
|
END IF;
|
189 |
|
|
|
190 |
|
|
WHEN gest_over_st =>
|
191 |
|
|
overflow <= '0';
|
192 |
|
|
wr_dpram <= '0';
|
193 |
|
|
IF (eof_store = '1') THEN
|
194 |
|
|
-- On attend le signal de fin trame pour recommencer à traiter
|
195 |
|
|
fsm_write <= idlewr_st;
|
196 |
|
|
END IF;
|
197 |
|
|
|
198 |
|
|
WHEN OTHERS =>
|
199 |
|
|
fsm_write <= idlewr_st;
|
200 |
|
|
END CASE;
|
201 |
|
|
END IF;
|
202 |
|
|
END PROCESS;
|
203 |
|
|
|
204 |
|
|
wea(0) <= wr_dpram;
|
205 |
|
|
store : dpram_storerx
|
206 |
|
|
PORT MAP (
|
207 |
|
|
clka => clk_sys,
|
208 |
|
|
wea => wea,
|
209 |
|
|
addra => cpt_adwr,
|
210 |
|
|
dina => data_wr,
|
211 |
|
|
douta => OPEN,
|
212 |
|
|
clkb => clk_sys,
|
213 |
|
|
web => vecnull(0 DOWNTO 0),
|
214 |
|
|
addrb => adread,
|
215 |
|
|
dinb => vecnull,
|
216 |
|
|
doutb => frame_data
|
217 |
|
|
);
|
218 |
|
|
END rtl;
|
219 |
|
|
|