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

Subversion Repositories uart_fpga_slow_control_migrated

[/] [uart_fpga_slow_control/] [trunk/] [code/] [ab_uart_lbus_slave.vhd] - Blame information for rev 15

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 aborga
-------------------------------------------------------------------------------
2
--                                                                           --
3
--                                                                           --
4
--                                                                           --
5
--                                                                           --
6
-------------------------------------------------------------------------------
7
--
8
-- unit name: uart_lbus (UART Control)
9
--
10
-- author:      Andrea Borga (andrea.borga@nikhef.nl)
11 15 aborga
--              Mauro Predonzani (predmauro@libero.it)
12 3 aborga
--
13
-- date: $26/01/2009    $: created
14
--
15
-- version: $Rev 0      $:
16
--
17
-- description: <file content, behaviour, purpose, special usage notes...>
18
-- <further description>
19
--
20
-- dependencies:        Lantronix_wrapper
21
--                                                              gh_uart_16550
22
--                                                              register_rx_handler
23
--                                                              register_tx_handler
24
--
25
-- references: <reference one>
26
-- <reference two> ...
27
--
28
-- modified by: $Author:: $:
29
--     18/08/2011   Andrea Borga
30
--        modified UART_WRITE to improve stability
31
--
32
-------------------------------------------------------------------------------
33
-- last changes: <date> <initials> <log>
34
-- <extended description>
35
-------------------------------------------------------------------------------
36
-- TODO:
37
--      check the address range (range violation prevention)
38
-- 
39
--
40
-------------------------------------------------------------------------------
41
 
42
--=============================================================================
43
-- Libraries
44
--=============================================================================
45
 
46
library ieee;
47
use ieee.std_logic_1164.all;
48
use ieee.numeric_std.all;
49
use ieee.std_logic_arith.all;
50
use ieee.std_logic_unsigned.all;
51
 
52
--=============================================================================
53
-- Entity declaration for ada_uart_lbus
54
--=============================================================================
55
 
56
entity uart_lbus is
57
  generic (
58
    c_bus_width   : natural := 8
59
    );
60
  port (
61
    lbus_clk            : in    std_logic;  -- local bus clock
62
    lbus_rst            : in    std_logic;  -- local bus reset
63
    lbus_rst_buffer     : out   std_logic;  -- soft reset for UART fifos
64
    lbus_txrdy_n        : in    std_logic;  -- Tx data ready
65
    lbus_rxrdy_n        : in    std_logic;  -- Rx data ready
66
    lbus_cs             : out   std_logic;  -- Chip Select
67
    lbus_wr             : out   std_logic;  -- Write/Read (1/0)
68
    lbus_init           : out   std_logic;  -- Initialization process flag
69
    lbus_add            : out   std_logic_vector(2 downto 0);  -- local bus address
70
    lbus_data           : out   std_logic_vector(c_bus_width-1 downto 0);  -- local bus data
71
    s_tx_proc_rqst_i    : in            std_logic;      -- tx process request from RAM
72
    v_lbus_state        : out           std_logic_vector(2 downto 0);    -- flag indicator of lbus_state
73
    s_cs_rd_c           : out           std_logic;      -- CS signal from caused by read cycle
74
    s_wr_rd_c           : out           std_logic;      -- WR signal from caused by read cycle
75
    s_new_byte_rdy      : in            std_logic;      -- new byte(8bit) is ready and stable to be transmitted
76
    s_data_tx           : in            std_logic;      -- trasmitting byte of RAM address/data
77
    reghnd_rd_rdy       : in            std_logic;      -- 6 byte ready RX but not yet written in RAM (1/0=>data ready/not ready)
78
    echo_en_i           : in            std_logic               -- echo enable command enable/disable = 1/0
79
 
80
                );
81
  end uart_lbus;
82
 
83
 
84
--=============================================================================
85
-- architecture declaration
86
--=============================================================================
87
 
88
architecture slave of uart_lbus is
89
 
90
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
91
  -- Components declaration 
92
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93
 
94
--  component gh_edge_det is
95
--    port(     
96
--      clk : in std_logic;
97
--      rst : in std_logic;
98
--      d   : in std_logic;
99
--      re  : out std_logic; -- rising edge (need sync source at d)
100
--      fe  : out std_logic; -- falling edge (need sync source at d)
101
--      sre : out std_logic; -- sync'd rising edge
102
--      sfe : out std_logic  -- sync'd falling edge
103
--      );
104
--  end component;
105
 
106
  --
107
  -- Internal signal declaration 
108
  --
109
 
110
  signal v_data_gen     : std_logic_vector(7 downto 0);  -- test data generator
111
  signal s_data_toggle  : std_logic;    -- toggles between two data patterns AA and 55
112
  signal v_data_num     : std_logic_vector(19 downto 0);    -- number of data to send  
113
 
114
  signal s_wr_rd        : std_logic;    -- wr for READ state process
115
  signal v_add_rd       : std_logic_vector(2 downto 0);
116
 
117
  signal s_tx_term      : std_logic;    -- transmission teminating strobe
118
  signal s_tx_send_data : std_logic;    -- data to send strobe
119
  signal s_cs_wr        : std_logic;    -- cs for WRITE state process
120
  signal s_wr_wr        : std_logic;    -- wr for WRITE state process
121
  signal v_add_wr       : std_logic_vector(2 downto 0);
122
 
123
  signal v_add          : std_logic_vector(2 downto 0);
124
  signal v_data         : std_logic_vector(c_bus_width-1 downto 0);
125
 
126
  signal s_init_done    : std_logic;    -- initialization done flag
127
  signal s_write_msb    : std_logic;
128
  signal s_tick_delay   : std_logic;    -- delays termination by 1 cycle (needed for lbus init)
129
  signal v_tick_delay_1 : std_logic_vector(1 downto 0);    -- delays termination by 1 cycle (needed for RW_lbus) 
130
  signal s_cs_init      : std_logic;    -- cs for INIT state process
131
  signal s_wr_init      : std_logic;    -- wr for INIT state process
132
  signal v_add_init     : std_logic_vector(2 downto 0);
133
  signal v_data_init    : std_logic_vector(c_bus_width-1 downto 0);
134
  signal v_fcr_init     : std_logic_vector(7 downto 0);  -- local FIFO Control Register O"2"
135
  signal v_lcr_init     : std_logic_vector(7 downto 0);  -- local Line Control Register O"3"
136
  signal v_lsr_init     : std_logic_vector(7 downto 0);  -- local Line Status Register  O"5"
137
        signal s_cs_rd        : std_logic;
138
  --
139
  -- State Machine states 
140
  --
141
 
142
  type t_uart_state is (IDLE, INIT, UART_READ, UART_WRITE);
143
  signal s_slave_state         : t_uart_state;
144
 
145
  type t_uart_init is (IDLE, WRITE_FCR, WRITE_LCR, WRITE_DIVLTC, ENB_FIFO, ENB_UART);
146
  signal s_slave_init         : t_uart_init;
147
 
148
--=============================================================================
149
-- architecture begin
150
--=============================================================================
151
 
152
 
153
        signal lbus_clk_n       : std_logic;
154
 
155
 
156
begin
157
 
158
  --
159
  -- Internal signals
160
  -- 
161
 
162
  lbus_clk_n            <=  not lbus_clk;
163
  s_cs_rd_c                                             <= s_cs_rd;
164
  s_wr_rd_c                                             <= s_wr_rd;
165
  lbus_add              <= v_add_init or v_add_wr or v_add_rd;
166
  lbus_data             <= v_data_init;                         -- or v_data_wr;
167
  lbus_init             <= not s_init_done;                     -- init signal
168
 
169
  lbus_cs               <= s_cs_init or s_cs_wr or s_cs_rd;     --      CS uart signal
170
  lbus_wr               <= s_wr_init or s_wr_wr or s_wr_rd;     --      R/W control UART signal
171
 
172
 
173
 
174
 
175
  --**************************************************************************
176
  -- UART local bus slave
177
  -- (state transitions)
178
  --**************************************************************************
179
  -- read: lbus_clk
180
  -- write:
181
  -- r/w: s_slave_state
182
 
183
  p_uart_state: process (lbus_clk_n)
184
  begin
185
    if Rising_edge(lbus_clk_n) then
186
      if lbus_rst = '1' then                    -- Sync RESET 
187
        s_slave_state   <= IDLE;
188
        s_cs_wr         <= '0';
189
        s_wr_wr         <= '0';
190
        s_cs_rd         <= '0';
191
        s_wr_rd         <= '0';
192
        v_add_wr        <= (others => '0');
193
        v_add_rd        <= (others => '0');
194
        v_tick_delay_1  <= "00";
195
        v_lbus_state            <= "000";
196
        lbus_rst_buffer <= '1';         -- rest UART FIFO 
197
      else
198
        case s_slave_state is
199
          when IDLE  =>                         -- uart IDLE
200
            s_cs_rd                             <= '0';
201
            s_wr_rd                             <= '0';
202
            s_cs_wr           <= '0';
203
            s_wr_wr           <= '0';
204
            v_tick_delay_1  <= "00";
205
            if s_init_done = '0' then
206
              s_slave_state <= INIT;
207
              v_lbus_state              <= "001";
208
            else
209
              lbus_rst_buffer <= '0';   -- release UART FIFO after init
210
              if s_tx_proc_rqst_i = '1' and lbus_txrdy_n = '0' then -- and reghnd_rd_rdy = '0' then
211
                v_lbus_state            <= "100";
212
                s_slave_state <= UART_WRITE;
213
              elsif s_tx_proc_rqst_i = '0' and lbus_rxrdy_n = '0' and lbus_txrdy_n = '0' and reghnd_rd_rdy = '0' then
214
                s_slave_state <= UART_READ;
215
                v_lbus_state            <= "010";
216
              else
217
                s_slave_state <= IDLE;
218
                v_lbus_state <= "000";
219
              end if;
220
            end if;
221
          when INIT =>                          -- uart INIT
222
            v_lbus_state                <= "001";
223
            if s_init_done = '0' then
224
              s_slave_state <= INIT;
225
            else
226
              s_slave_state <= IDLE;
227
            end if;
228
          when UART_READ =>                     -- uart READ
229
            v_lbus_state                <= "010";
230
            s_cs_wr         <= '0';
231
            s_wr_wr         <= '0';
232
            if lbus_rxrdy_n = '0'  then
233
              if v_tick_delay_1 = "00" then
234
                if echo_en_i = '1' then                                                 -- ECHO is enable
235
                  v_tick_delay_1    <= "01";
236
                elsif echo_en_i = '0' then                                       -- ECHO is disable
237
                  v_tick_delay_1    <= "11";
238
                end if;
239
                s_cs_rd           <= '1';
240
                s_wr_rd           <= '0';
241
                s_slave_state <= UART_READ;
242
              elsif v_tick_delay_1 = "01" then                  -- will be executed in a READ cycle only if ECHO is enable
243
                v_tick_delay_1    <= "10";
244
                v_add_rd          <= O"0";
245
                s_cs_rd           <= '0';
246
                s_wr_rd           <= '1';
247
                s_slave_state <= UART_READ;
248
              elsif v_tick_delay_1 = "10" then                  -- will be executed in a READ cycle only if ECHO is enable
249
                v_tick_delay_1    <= "11";
250
                v_add_rd          <= O"0";
251
                s_cs_rd           <= '1';
252
                s_wr_rd           <= '1';
253
                s_slave_state <= UART_READ;
254
              elsif v_tick_delay_1 = "11" then                  -- will be executed in every READ cycle
255
                v_tick_delay_1    <= "00";
256
                v_add_rd          <= O"0";
257
                s_cs_rd           <= '0';
258
                s_wr_rd           <= '0';
259
                s_slave_state <= IDLE;
260
              end if;
261
            else
262
              s_cs_rd           <= '0';
263
              s_wr_rd           <= '0';
264
              s_slave_state <= IDLE;
265
            end if;
266
          when UART_WRITE =>                     -- uart WRITE
267
            v_lbus_state                <= "100";
268
            if v_tick_delay_1 = "00" then
269
              if s_new_byte_rdy = '1' then
270
                v_tick_delay_1    <= "01";
271
                s_cs_wr           <= '0';
272
                s_wr_wr           <= '1';
273
              else
274
                v_tick_delay_1    <= "00";
275
                if s_tx_proc_rqst_i = '0' and s_data_tx = '0' then
276
                  s_slave_state <= IDLE;
277
                else
278
                  s_slave_state <= UART_WRITE;
279
                end if;
280
              end if;
281
            elsif v_tick_delay_1 ="01" then
282
              v_tick_delay_1     <= "11";
283
              s_cs_wr           <= '1';
284
              s_wr_wr           <= '1';
285
              v_add_wr          <= O"0";
286
              s_slave_state <= UART_WRITE;
287
            elsif v_tick_delay_1 ="11" then
288
              if s_new_byte_rdy = '1' then
289
                v_tick_delay_1    <= "11";
290
                s_cs_wr           <= '0';
291
                s_wr_wr           <= '1';
292
                v_add_wr          <= O"0";
293
                s_slave_state <= UART_WRITE;
294
              else
295
                v_tick_delay_1    <= "00";
296
                s_cs_wr           <= '0';
297
                s_wr_wr           <= '1';
298
                v_add_wr          <= O"0";
299
                s_slave_state <= UART_WRITE;
300
              end if;
301
            else
302
              s_cs_rd           <= '0';
303
              s_wr_rd           <= '0';
304
              s_slave_state     <= IDLE;
305
            end if;
306
          when others =>                        -- uart OTHERS 
307
            s_slave_state <= IDLE;
308
        end case;
309
      end if;
310
    end if;
311
  end process p_uart_state;
312
 
313
  --**************************************************************************
314
  -- UART local bus slave
315
  -- (initialization)
316
  --**************************************************************************
317
  -- read: 
318
  -- write:
319
  -- r/w:
320
 
321
  p_init_lbus : process (lbus_clk, lbus_rst)  -- uart initialization process
322
  begin  -- process
323
    if lbus_rst = '1' then
324
      s_slave_init    <= IDLE;
325
      v_add_init      <= O"7";
326
      v_data_init     <= (others => '0');
327
      v_lcr_init      <= (others => '0');
328
      v_fcr_init      <= (others => '0');
329
      s_tick_delay    <= '0';
330
      s_write_msb     <= '0';
331
      s_cs_init       <= '0';
332
      s_wr_init       <= '0';
333
      s_init_done     <= '0';
334
    elsif Rising_edge(lbus_clk) then
335
      case s_slave_init is
336
        when IDLE =>                    -- init IDLE
337
           if s_init_done = '0' and s_write_msb = '0' then
338
             s_cs_init          <= '1';
339
             s_wr_init          <= '1';
340
             s_slave_init       <= WRITE_FCR;
341
           else
342
             s_slave_init       <= IDLE;
343
           end if;
344
        when WRITE_FCR =>               --  init WRITE_FCR
345
          v_add_init            <= O"2";
346
          v_fcr_init            <= "00000000";  -- DMA mode 0 init FIFO Control Register
347
          v_data_init           <= "00000000";  -- DMA mode 0 write FIFO Control Register
348
--          v_fcr_init            <= "00001000";  -- DMA mode 1 init FIFO Control Register
349
--          v_data_init           <= "00001000";  -- DMA mode 1 write FIFO Control Register
350
          s_slave_init          <= WRITE_LCR;
351
        when WRITE_LCR =>               -- init WRITE_LCR
352
          v_add_init            <= O"3";
353
          v_lcr_init            <= "10000011";  -- init FIFO Control Register
354
          v_data_init           <= "10000011";  -- write FIFO Control Register
355
          s_slave_init          <= WRITE_DIVLTC;
356
        when WRITE_DIVLTC =>            -- init WRITE_DIVLTC
357
          if s_write_msb = '0' then
358
            v_add_init          <= O"0";         -- init Divisor Latch lsb
359 7 aborga
            v_data_init         <= "00000010";   -- DEC 2 Baudrate = 921600 bps @ 29,4912 MHz 
360 3 aborga
            s_write_msb         <= '1';
361
            s_slave_init        <= WRITE_DIVLTC;
362
          else
363
            v_add_init          <= O"1";         -- init Divisor Latch msb
364
            v_data_init         <= "00000000";
365
            s_slave_init        <= ENB_FIFO;
366
          end if;
367
        when ENB_FIFO =>                -- init ENB_FIFO
368
          if s_tick_delay = '0' then
369
            s_tick_delay        <= '1';
370
            v_add_init          <= O"3";
371
            v_lcr_init          <= "00000011";         -- Enable FIFO access
372
            v_data_init         <= "00000011";
373
          else
374
            v_add_init          <= (others => '0');
375
            v_data_init         <= (others => '0');
376
            s_tick_delay        <= '0';
377
            s_slave_init        <= ENB_UART;
378
          end if;
379
        when ENB_UART =>                -- init ENB_UART
380
          if s_tick_delay = '0' then
381
            s_tick_delay        <= '1';
382
            s_init_done         <= '1';         -- terminate init
383
            s_cs_init           <= '0';
384
            s_wr_init           <= '0';
385
            v_data_init         <= "00000000";
386
          else
387
            s_tick_delay        <= '0';
388
            s_init_done         <= '1';
389
            s_slave_init          <= IDLE;
390
          end if;
391
        when others =>
392
          s_slave_init          <= IDLE;
393
      end case;
394
    end if;
395
  end process;
396
 
397
 
398
 
399
 
400
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
401
  -- Components mapping
402
  -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
403
 
404
--  cmp_cs_rd_edge : gh_edge_det 
405
--    port map (
406
--      clk => lbus_clk,
407
--      rst => lbus_rst,
408
--      d   => s_cs_rd,
409
--      sre => s_cs_rd_edge);
410
 
411
--  cmp_wr_rd_edge : gh_edge_det 
412
--    port map (
413
--      clk => lbus_clk,
414
--      rst => lbus_rst,
415
--      d   => s_wr_rd,
416
--      sre => s_wr_rd_edge);
417
 
418
--  cmp_cs_wr_edge : gh_edge_det 
419
--    port map (
420
--      clk => lbus_clk,
421
--      rst => lbus_rst,
422
--      d   => s_cs_wr,
423
--      sre => s_cs_wr_edge);
424
--
425
--  cmp_wr_wr_edge : gh_edge_det 
426
--    port map (
427
--      clk => lbus_clk,
428
--      rst => lbus_rst,
429
--      d   => s_wr_wr,
430
--      sre => s_wr_wr_edge);
431
 
432
end slave;
433
 
434
--=============================================================================
435
-- architecture end
436
--=============================================================================
437
 
438
 

powered by: WebSVN 2.1.0

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