VICON: Sistema de Visión configurable V1.0
Trabajo Fin de Master Carlos Manuel Gomez Jimenez
Loading...
Searching...
No Matches
TOP.vhd
Go to the documentation of this file.
1
3
4library IEEE;
5use IEEE.STD_LOGIC_1164.ALL;
6use IEEE.NUMERIC_STD.ALL;
7
8entity TOP is
9 generic (
10 CLK_FREQ_HZ : integer := 50_000_000;
11 I2C_FREQ_HZ : integer := 400_000;
12 FIFO_DEPTH : integer := 16;
13 SENSOR_ADDR : std_logic_vector(6 downto 0) := "1011100" -- 0x5C
14 );
15 port (
16 clk : in std_logic;
17 reset : in std_logic;
18 sclk : out std_logic;
19 sdata : inout std_logic;
20 done : out std_logic
21 );
22end entity TOP;
23
24architecture Behavioral of TOP is
25
26 ---------------------------------------------------------------------------
27 -- Señales hacia/desde i2c_master
28 ---------------------------------------------------------------------------
29 -- Control
30 signal i2c_rw : std_logic := '0';
31 signal i2c_start : std_logic := '0';
32 signal i2c_num_regs : integer range 1 to FIFO_DEPTH := 1;
33 signal i2c_addr_reg : std_logic_vector(7 downto 0) := (others => '0');
34
35 -- WR FIFO
36 signal i2c_wr_push : std_logic := '0';
37 signal i2c_wr_data : std_logic_vector(15 downto 0) := (others => '0');
38 signal i2c_wr_full : std_logic;
39 signal i2c_wr_empty : std_logic;
40
41 -- RD FIFO
42 signal i2c_rd_pop : std_logic := '0';
43 signal i2c_rd_data : std_logic_vector(15 downto 0);
44 signal i2c_rd_full : std_logic;
45 signal i2c_rd_empty : std_logic;
46
47 -- Estado
48 signal i2c_busy : std_logic;
49 signal i2c_done : std_logic;
50 signal i2c_error : std_logic;
51
52 ---------------------------------------------------------------------------
53 -- FSM del TOP
54 --
55 -- Secuencia de ejemplo:
56 -- 1. Escribir 2 registros consecutivos a partir de addr_reg=0x04
57 -- (aprovechando auto-increment del MT9V111)
58 -- 2. Leer 2 registros consecutivos a partir de addr_reg=0x04
59 -- 3. Vaciar RD_FIFO y señalizar done
60 ---------------------------------------------------------------------------
61 type main_state_t is (
62 ST_IDLE,
63 -- Escritura
64 ST_WR_FILL_FIFO, -- Cargar datos en WR FIFO
65 ST_WR_START, -- Lanzar transacción write
66 ST_WR_WAIT, -- Esperar done/error
67 -- Lectura
68 ST_RD_START, -- Lanzar transacción read
69 ST_RD_WAIT, -- Esperar done/error
70 ST_RD_DRAIN, -- Vaciar RD FIFO (procesar datos leídos)
71 -- Fin
72 ST_FINISH,
73 ST_ERROR
74 );
75 signal state : main_state_t := ST_IDLE;
76
77 -- Contador para cargar múltiples entradas en la WR FIFO
78 signal fill_cnt : integer range 0 to FIFO_DEPTH := 0;
79
80 signal mclk : std_logic;
81 signal locked : std_logic;
82 signal rst_final : std_logic;
83
84 -- Número de registros a escribir/leer en este ejemplo
85 constant NUM_REGS_WR : integer := 2;
86 constant NUM_REGS_RD : integer := 2;
87
88 -- Datos de ejemplo a escribir (se pueden sustituir por señales externas)
89 type reg_data_array_t is array (0 to NUM_REGS_WR - 1) of std_logic_vector(15 downto 0);
90 constant WR_DATA : reg_data_array_t := (
91 0 => x"823A", -- Reg 0x04
92 1 => x"0010" -- Reg 0x05 (auto-increment)
93 );
94
95 -- Buffer para almacenar los registros leídos
96 type rd_buf_t is array (0 to NUM_REGS_RD - 1) of std_logic_vector(15 downto 0);
97 signal rd_buf : rd_buf_t := (others => (others => '0'));
98 signal rd_cnt : integer range 0 to NUM_REGS_RD := 0;
99
100begin
101 -- MMCM
102 mi_MMCM : entity work.clk_wiz_0
103 port map (
104 clk_in1 => clk,
105 reset => reset,
106 clk_out1 => mclk,
107 locked => locked
108 );
109
110
111 -- Logica de Reset: El sistema solo sale de reset cuando el reloj es estable
112 rst_final <= not locked;
113
114 ---------------------------------------------------------------------------
115 -- Instancia del controlador I2C
116 ---------------------------------------------------------------------------
117 u_i2c : entity work.i2c_master
118 generic map (
122 )
123 port map (
124 clk => mclk,
125 reset => rst_final,
126 rw => i2c_rw,
139 busy => i2c_busy,
140 done => i2c_done,
141 error => i2c_error,
142 sclk => sclk,
143 sdata => sdata
144 );
145
146 ---------------------------------------------------------------------------
147 -- FSM principal
148 ---------------------------------------------------------------------------
149 process(mclk)
150 begin
151 if rising_edge(mclk) then
152 if rst_final = '1' then
153 state <= ST_IDLE;
154 i2c_rw <= '0';
155 i2c_start <= '0';
156 i2c_wr_push <= '0';
157 i2c_rd_pop <= '0';
158 i2c_num_regs <= 1;
159 i2c_addr_reg <= (others => '0');
160 i2c_wr_data <= (others => '0');
161 fill_cnt <= 0;
162 rd_cnt <= 0;
163 done <= '0';
164 else
165 -- Pulsos de un ciclo por defecto
166 i2c_start <= '0';
167 i2c_wr_push <= '0';
168 i2c_rd_pop <= '0';
169
170 case state is
171
172 -----------------------------------------------------------
173 when ST_IDLE =>
174 done <= '0';
175 fill_cnt <= 0;
176 rd_cnt <= 0;
177 state <= ST_WR_FILL_FIFO;
178
179 -----------------------------------------------------------
180 -- Cargar datos en WR FIFO antes de lanzar la escritura.
181 -- Se comprueban dos condiciones: FIFO no llena y aún
182 -- quedan datos por meter.
183 -----------------------------------------------------------
184 when ST_WR_FILL_FIFO =>
185 if fill_cnt = NUM_REGS_WR then
186 -- FIFO cargada → lanzar escritura
187 fill_cnt <= 0;
188 state <= ST_WR_START;
189 elsif i2c_wr_full = '0' then
191 i2c_wr_push <= '1';
192 fill_cnt <= fill_cnt + 1;
193 end if;
194 -- Si FIFO llena y aún quedan datos: esperar (raro con
195 -- FIFO_DEPTH >= NUM_REGS_WR, pero seguro)
196
197 -----------------------------------------------------------
198 when ST_WR_START =>
199 if i2c_busy = '0' then
200 i2c_rw <= '0'; -- Write
201 i2c_addr_reg <= x"04"; -- Registro inicial
203 i2c_start <= '1';
204 state <= ST_WR_WAIT;
205 end if;
206
207 -----------------------------------------------------------
208 when ST_WR_WAIT =>
209 if i2c_error = '1' then
210 state <= ST_ERROR;
211 elsif i2c_done = '1' then
212 state <= ST_RD_START;
213 end if;
214
215 -----------------------------------------------------------
216 when ST_RD_START =>
217 -- El controlador bloquea si RD FIFO no está vacía,
218 -- pero aquí sabemos que lo está (acabamos de arrancar)
219 if i2c_busy = '0' and i2c_rd_empty = '1' then
220 i2c_rw <= '1'; -- Read
221 i2c_addr_reg <= x"04";
223 i2c_start <= '1';
224 state <= ST_RD_WAIT;
225 end if;
226
227 -----------------------------------------------------------
228 when ST_RD_WAIT =>
229 if i2c_error = '1' then
230 state <= ST_ERROR;
231 elsif i2c_done = '1' then
232 rd_cnt <= 0;
233 state <= ST_RD_DRAIN;
234 end if;
235
236 -----------------------------------------------------------
237 -- Vaciar RD FIFO y guardar en buffer interno.
238 -- Cada ciclo en que rd_fifo_empty='0' se hace pop.
239 -----------------------------------------------------------
240 when ST_RD_DRAIN =>
241 if i2c_rd_empty = '0' and rd_cnt < NUM_REGS_RD then
242 i2c_rd_pop <= '1';
244 rd_cnt <= rd_cnt + 1;
245 elsif rd_cnt = NUM_REGS_RD then
246 state <= ST_FINISH;
247 end if;
248
249 -----------------------------------------------------------
250 when ST_FINISH =>
251 done <= '1';
252 state <= ST_FINISH; -- Mantener done='1'
253 -- Aquí rd_buf(0) y rd_buf(1) tienen los valores leídos
254
255 -----------------------------------------------------------
256 when ST_ERROR =>
257 done <= '0';
258 state <= ST_ERROR;
259 -- Señal de error visible en i2c_error del controlador.
260 -- Añadir lógica de recuperación si es necesario.
261
262 when others =>
263 state <= ST_IDLE;
264
265 end case;
266 end if;
267 end if;
268 end process;
269
270end architecture Behavioral;
main_state_t := ST_IDLE state
Definition TOP.vhd:75
std_logic_vector( 15 downto 0) :=( others => '0') i2c_wr_data
Definition TOP.vhd:37
std_logic locked
Definition TOP.vhd:81
std_logic_vector( 7 downto 0) :=( others => '0') i2c_addr_reg
Definition TOP.vhd:33
integer := 2 NUM_REGS_RD
Definition TOP.vhd:86
std_logic rst_final
Definition TOP.vhd:82
(ST_IDLE,ST_WR_FILL_FIFO,ST_WR_START,ST_WR_WAIT,ST_RD_START,ST_RD_WAIT,ST_RD_DRAIN,ST_FINISH,ST_ERROR) main_state_t
Definition TOP.vhd:61
std_logic := '0' i2c_rd_pop
Definition TOP.vhd:42
std_logic := '0' i2c_rw
Definition TOP.vhd:30
std_logic := '0' i2c_start
Definition TOP.vhd:31
std_logic := '0' i2c_wr_push
Definition TOP.vhd:36
integer range 1 to FIFO_DEPTH:= 1 i2c_num_regs
Definition TOP.vhd:32
std_logic i2c_done
Definition TOP.vhd:49
std_logic_vector( 15 downto 0) i2c_rd_data
Definition TOP.vhd:43
rd_buf_t :=( others =>( others => '0')) rd_buf
Definition TOP.vhd:97
std_logic i2c_busy
Definition TOP.vhd:48
std_logic mclk
Definition TOP.vhd:80
reg_data_array_t :=( 0=> x"823A", 1=> x"0010") WR_DATA
Definition TOP.vhd:90
std_logic i2c_rd_empty
Definition TOP.vhd:45
integer range 0 to NUM_REGS_RD:= 0 rd_cnt
Definition TOP.vhd:98
std_logic i2c_error
Definition TOP.vhd:50
std_logic i2c_wr_full
Definition TOP.vhd:38
( 0 to NUM_REGS_WR- 1) std_logic_vector( 15 downto 0) reg_data_array_t
Definition TOP.vhd:89
( 0 to NUM_REGS_RD- 1) std_logic_vector( 15 downto 0) rd_buf_t
Definition TOP.vhd:96
std_logic i2c_rd_full
Definition TOP.vhd:44
std_logic i2c_wr_empty
Definition TOP.vhd:39
integer := 2 NUM_REGS_WR
Definition TOP.vhd:85
integer range 0 to FIFO_DEPTH:= 0 fill_cnt
Definition TOP.vhd:78
Definition TOP.vhd:8
inout sdata std_logic
Definition TOP.vhd:19
in reset std_logic
Definition TOP.vhd:17
CLK_FREQ_HZ integer := 50_000_000
Definition TOP.vhd:10
SENSOR_ADDR std_logic_vector( 6 downto 0) := "1011100"
Definition TOP.vhd:14
in clk std_logic
Definition TOP.vhd:16
I2C_FREQ_HZ integer := 400_000
Definition TOP.vhd:11
out done std_logic
Definition TOP.vhd:21
FIFO_DEPTH integer := 16
Definition TOP.vhd:12
out sclk std_logic
Definition TOP.vhd:18
out rd_fifo_empty std_logic
inout sdata std_logic
in addr_reg std_logic_vector( 7 downto 0)
in reset std_logic
CLK_FREQ_HZ integer := 50_000_000
in clk std_logic
I2C_FREQ_HZ integer := 400_000
out wr_fifo_empty std_logic
in rd_fifo_pop std_logic
out done std_logic
in wr_fifo_data std_logic_vector( 15 downto 0)
in rw std_logic
in addr_dev std_logic_vector( 6 downto 0)
in wr_fifo_push std_logic
FIFO_DEPTH integer := 16
out rd_fifo_full std_logic
out sclk std_logic
out busy std_logic
out wr_fifo_full std_logic
out error std_logic
in start_i2c std_logic
out rd_fifo_data std_logic_vector( 15 downto 0)
in num_regs integer range 1 to FIFO_DEPTH