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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.interface/] [eth_lan91c111_ctrl/] [1.0/] [vhd/] [lan91c111_read_module.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : LAN91C111 controller, read module
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : Original: DM9kA_read_module.vhd
6
-- Author     : Jussi Nieminen (Antti Alhonen for LAN91C111)
7
-- Last update: 2011-11-07
8
-------------------------------------------------------------------------------
9
-- Description: Handles reading of rx data from LAN91C111
10
-------------------------------------------------------------------------------
11
-- Revisions  :
12
-- Date        Version  Author  Description
13
-- 2009/09/02  1.0      niemin95        Created
14
-- 2011/07/??  lan91c111 alhonena
15
-------------------------------------------------------------------------------
16
 
17
library ieee;
18
use ieee.std_logic_1164.all;
19
use ieee.numeric_std.all;
20
use work.lan91c111_ctrl_pkg.all;
21
 
22
 
23
entity lan91c111_read_module is
24
 
25
  generic (
26
    mode_16bit_g : integer := 0);
27
 
28
  port (
29
    clk                     : in  std_logic;
30
    rst_n                   : in  std_logic;
31
    -- from interrupt handler
32
    rx_waiting_in           : in  std_logic;
33
    -- from/to comm module
34
    reg_addr_out            : out std_logic_vector( real_addr_width_c-1 downto 0 );
35
    config_data_out         : out std_logic_vector( lan91_data_width_c-1 downto 0 );
36
    nBE_out                 : out std_logic_vector( 3 downto 0 );
37
    read_not_write_out      : out std_logic;
38
    config_valid_out        : out std_logic;
39
    data_from_comm_in       : in  std_logic_vector( lan91_data_width_c-1 downto 0 );
40
    data_from_comm_valid_in : in  std_logic;
41
    comm_busy_in            : in  std_logic;
42
    comm_req_out            : out std_logic;
43
    comm_grant_in           : in  std_logic;
44
    -- from/to upper level
45
    rx_data_out             : out std_logic_vector( lan91_data_width_c-1 downto 0 );
46
    rx_data_valid_out       : out std_logic;
47
    rx_bytes_valid_out      : out std_logic_vector( 3 downto 0);  -- you may want to use this to help reading, or as a debug signal, or to ignore it.
48
    rx_re_in                : in  std_logic;
49
    new_rx_out              : out std_logic;
50
    rx_len_out              : out std_logic_vector( tx_len_w_c-1 downto 0 );  -- Actual number of bytes of payload.
51
    frame_type_out          : out std_logic_vector( 15 downto 0 );
52
    rx_erroneous_out        : out std_logic;
53
    fatal_error_out         : out std_logic  -- worse than some network error
54
    );
55
 
56
end lan91c111_read_module;
57
 
58
 
59
architecture rtl of lan91c111_read_module is
60
 
61
  type read_state_type is (wait_rx,      -- wait until interrupt module rises rx_waiting_in.
62
                           set_pointer_to_status,  -- set the pointer register to read packet status.
63
                           read_status_and_len,    -- read the packet status and length
64
                           frame_type,  -- Ethernet frame type is read.
65
                           frame_type2,
66
                           start_read,
67
                           read_normal,
68
                           read_last_24,
69
                           read_last_16,
70
                           read_last_odd,
71
                           wait_re,
72
                           remove_from_fifo,  -- issue a command to MMU to remove the RX and free memory.
73
                           wait_for_mmu,  -- poll the MMU until it has processed the command.
74
                           check_mmu,
75
                           check_for_more);  -- check if there are more rx's in the FIFO.
76
 
77
  signal state_r : read_state_type;
78
 
79
  signal comm_req_r         : std_logic;
80
 
81
  signal rx_len_r : integer range 0 to 2**tx_len_w_c-1;
82
 
83
  signal config_valid_r : std_logic;
84
 
85
  signal first_r : std_logic;
86
 
87
  signal new_r : std_logic;
88
 
89
  signal new_rx_r : std_logic;
90
  signal rx_data_valid_r : std_logic;
91
 
92
  constant pnt_set_wait_cnt_c : integer := clk_hz_c/2702702;  -- 370 ns wait after pointer is set.
93
  signal pnt_set_wait_cnt_r : integer range 0 to pnt_set_wait_cnt_c;
94
 
95
-------------------------------------------------------------------------------
96
begin  -- rtl
97
-------------------------------------------------------------------------------
98
 
99
  comm_req_out <= comm_req_r;
100
 
101
  config_valid_out <= config_valid_r;
102
 
103
  new_rx_out <= new_rx_r;
104
 
105
  rx_data_valid_out <= rx_data_valid_r;
106
 
107
  main : process (clk, rst_n)
108
 
109
    variable rx_len_v : integer range 0 to 2**tx_len_w_c-1;
110
 
111
  begin  -- process main
112
    if rst_n = '0' then                 -- asynchronous reset (active low)
113
 
114
      state_r            <= wait_rx;
115
      comm_req_r         <= '0';
116
      rx_len_r           <= 0;
117
 
118
      reg_addr_out       <= (others => '0');
119
      config_data_out    <= (others => '0');
120
      config_valid_r   <= '0';
121
      read_not_write_out <= '0';
122
      rx_len_out         <= (others => '0');
123
      rx_erroneous_out   <= '0';
124
      fatal_error_out    <= '0';
125
      frame_type_out     <= (others => '0');
126
      new_r              <= '0';
127
 
128
      new_rx_r           <= '0';
129
      rx_data_valid_r    <= '0';
130
 
131
    elsif clk'event and clk = '1' then  -- rising clock edge
132
 
133
      if new_rx_r = '1' and rx_re_in = '1' then
134
        new_rx_r <= '0';
135
      end if;
136
 
137
      if rx_data_valid_r = '1' and rx_re_in = '1' then
138
        rx_data_valid_r <= '0';
139
      end if;
140
 
141
      -- DEFAULTS:
142
      config_valid_r <= '0';
143
 
144
 
145
      case state_r is
146
 
147
        when wait_rx =>
148
          -- notification from int handler
149
          if rx_waiting_in = '1' or new_r = '1' then
150
            new_r <= '0';
151
            -- ask for a turn
152
            comm_req_r <= '1';
153
          end if;
154
 
155
          if comm_req_r = '1' and comm_grant_in = '1' and comm_busy_in = '0' then
156
            -- our turn
157
            state_r <= set_pointer_to_status;
158
            -- again, we suppose that we are in BANK 2.
159
            config_data_out <= x"0000" & "11100" & "000" & x"00";  -- pointer to 0 (status), with rcv, read, autoincr.
160
            reg_addr_out <= "011"; nBE_out <= "1100"; read_not_write_out <= '0'; config_valid_r <= '1';
161
            pnt_set_wait_cnt_r <= pnt_set_wait_cnt_c;
162
          end if;
163
 
164
        when set_pointer_to_status =>
165
          if comm_busy_in = '0' and config_valid_r = '0' then
166
            if pnt_set_wait_cnt_r = 0 then
167
              -- pointer set, start reading.
168
              reg_addr_out <= "100"; nBE_out <= "0000"; read_not_write_out <= '1'; config_valid_r <= '1';
169
              state_r <= read_status_and_len;
170
            else
171
              pnt_set_wait_cnt_r <= pnt_set_wait_cnt_r - 1;
172
            end if;
173
          end if;
174
 
175
        when read_status_and_len =>
176
          if data_from_comm_valid_in = '1' then  -- this also means "not busy", remember that?
177
            rx_erroneous_out <= data_from_comm_in(10) or  -- too short
178
                                  data_from_comm_in(11) or  -- too long
179
                                  data_from_comm_in(13) or  -- bad crc
180
                                  data_from_comm_in(15);  -- alignment error.
181
            rx_len_v := to_integer(unsigned(data_from_comm_in(16+11-1 downto 17) & data_from_comm_in(12))) - 16;  -- actual data length.
182
            rx_len_r <= rx_len_v;
183
            rx_len_out <= std_logic_vector(to_unsigned(rx_len_v, tx_len_w_c));
184
 
185
            config_data_out <= x"0000" & "11100" & "000" & x"10";  -- set pointer to 16 (frame type), with rcv, read, autoincr.
186
            reg_addr_out <= "011"; nBE_out <= "1100"; read_not_write_out <= '0'; config_valid_r <= '1';
187
            pnt_set_wait_cnt_r <= pnt_set_wait_cnt_c;
188
            state_r <= frame_type;
189
          end if;
190
 
191
        when frame_type =>
192
          if comm_busy_in ='0' and config_valid_r = '0' then
193
            if pnt_set_wait_cnt_r = 0 then
194
              reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1';  -- 16 bit read for frame type.
195
              state_r <= frame_type2;
196
            else
197
              pnt_set_wait_cnt_r <= pnt_set_wait_cnt_r - 1;
198
            end if;
199
          end if;
200
 
201
        when frame_type2 =>
202
          if data_from_comm_valid_in = '1' then
203
            frame_type_out <= data_from_comm_in(7 downto 0) & data_from_comm_in(15 downto 8);
204
            new_rx_r <= '1';
205
            state_r <= start_read;
206
            first_r <= '1';
207
          end if;
208
 
209
        when start_read =>
210
          if rx_re_in = '1' or first_r = '1' then  -- previous word was read by the application; or this is the first word.
211
            first_r <= '0';
212
 
213
            if mode_16bit_g = 1 then
214
              -- 16-bit mode:
215
              if rx_len_r = 1 then
216
                reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1';
217
                state_r <= read_last_odd;   -- zero "data area" left; read control byte and last data byte.
218
              else
219
                reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1';
220
                state_r <= read_normal;         -- normal 16-bit read.
221
              end if;
222
 
223
            else
224
              -- Original 32-bit mode:
225
              if rx_len_r = 1 then
226
                reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1';
227
                state_r <= read_last_odd;   -- zero "data area" left; read control byte and last data byte.
228
              elsif rx_len_r = 2 then
229
                reg_addr_out <= "100"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1';
230
                state_r <= read_last_16;    -- two bytes of "data area" left; read it and ignore ctrl byte and last byte.
231
              elsif rx_len_r = 3 then
232
                reg_addr_out <= "100"; nBE_out <= "0000"; read_not_write_out <= '1'; config_valid_r <= '1';
233
                state_r <= read_last_24;    -- two bytes of "data area" left; do a 32-bit read to data + ctrl + odd byte.
234
              else
235
                reg_addr_out <= "100"; nBE_out <= "0000"; read_not_write_out <= '1'; config_valid_r <= '1';
236
                state_r <= read_normal;         -- normal 32-bit read.
237
              end if;
238
 
239
            end if;
240
 
241
          end if;
242
 
243
        when read_normal =>
244
          if data_from_comm_valid_in = '1' then
245
            rx_data_valid_r <= '1';
246
            rx_data_out <= data_from_comm_in;
247
            if mode_16bit_g = 1 then
248
              rx_bytes_valid_out <= "0011";
249
            else
250
              rx_bytes_valid_out <= "1111";
251
            end if;
252
            state_r <= start_read;
253
            if (mode_16bit_g = 0 and rx_len_r = 4) or
254
               (mode_16bit_g = 1 and rx_len_r = 2) then        -- this was last and it was even.
255
              state_r <= wait_re;
256
            end if;
257
            if mode_16bit_g = 1 then
258
              rx_len_r <= rx_len_r - 2;
259
            else
260
              rx_len_r <= rx_len_r - 4;
261
            end if;
262
          end if;
263
 
264
        when read_last_24 =>
265
          assert mode_16bit_g = 0 report "Shouldn't be here!" severity failure;
266
 
267
          if data_from_comm_valid_in = '1' then
268
            rx_data_valid_r <= '1';
269
            rx_data_out <= x"00" & data_from_comm_in(23 downto 0);
270
            rx_bytes_valid_out <= "0111";
271
            state_r <= wait_re;
272
          end if;
273
 
274
        when read_last_16 =>
275
          assert mode_16bit_g = 0 report "Shouldn't be here!" severity failure;
276
 
277
          if data_from_comm_valid_in = '1' then
278
            rx_data_valid_r <= '1';
279
            rx_data_out <= x"0000" & data_from_comm_in(15 downto 0);
280
            rx_bytes_valid_out <= "0011";
281
            state_r <= wait_re;
282
          end if;
283
 
284
        when read_last_odd =>
285
          if data_from_comm_valid_in = '1' then
286
            rx_data_valid_r <= '1';
287
            rx_data_out <= x"000000" & data_from_comm_in(7 downto 0);
288
            rx_bytes_valid_out <= "0001";
289
            state_r <= wait_re;
290
          end if;
291
 
292
        when wait_re =>             -- wait for last re from the application.
293
          if rx_re_in = '1' then
294
            state_r <= remove_from_fifo;
295
          end if;
296
 
297
        when remove_from_fifo =>
298
          if comm_busy_in = '0' and config_valid_r = '0' then
299
            config_data_out <= x"000000" & "10000000";  -- REMOVE AND RELEASE TOP OF RX FIFO
300
            reg_addr_out <= "000"; nBE_out <= "1100"; read_not_write_out <= '0'; config_valid_r <= '1';
301
            state_r <= wait_for_mmu;
302
          end if;
303
 
304
        when wait_for_mmu =>
305
          if comm_busy_in = '0' and config_valid_r = '0' then
306
            reg_addr_out <= "000"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1';
307
            state_r <= check_mmu;
308
          end if;
309
 
310
        when check_mmu =>
311
          if data_from_comm_valid_in = '1' then
312
            if data_from_comm_in(0) = '1' then  -- BUSY, poll again.
313
              state_r <= wait_for_mmu;
314
            else
315
              state_r <= check_for_more;  -- Everything finished, let's check if there are new rx's waiting...
316
              reg_addr_out <= "010"; nBE_out <= "1100"; read_not_write_out <= '1'; config_valid_r <= '1';
317
            end if;
318
          end if;
319
 
320
        when check_for_more =>
321
          if data_from_comm_valid_in = '1' then
322
            new_r <= not data_from_comm_in(15);  -- RX FIFO not empty.
323
 
324
            state_r <= wait_rx;
325
            comm_req_r <= '0';
326
          end if;
327
 
328
        when others => null;
329
      end case;
330
 
331
    end if;
332
  end process main;
333
 
334
end rtl;

powered by: WebSVN 2.1.0

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