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_dm9000a_ctrl/] [1.0/] [vhd/] [DM9kA_init_module.vhd] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
-------------------------------------------------------------------------------
2
-- Title      : Initialization module
3
-- Project    : 
4
-------------------------------------------------------------------------------
5
-- File       : DM9kA_init_module.vhd
6
-- Author     : Jussi Nieminen
7
-- Company    : 
8
-- Last update: 2012-04-04
9
-- Platform   : 
10
-------------------------------------------------------------------------------
11
-- Description: Initializes DM9kA. Includes two state machines.
12
-------------------------------------------------------------------------------
13
-- Revisions  :
14
-- Date        Version  Author  Description
15
-- 2009/08/24  1.0      niemin95        Created
16
-------------------------------------------------------------------------------
17
 
18
library ieee;
19
use ieee.std_logic_1164.all;
20
use ieee.numeric_std.all;
21
 
22
-- constants
23
use work.DM9kA_ctrl_pkg.all;
24
 
25
 
26
entity DM9kA_init_module is
27
 
28
  port (
29
    clk                     : in  std_logic;
30
    rst_n                   : in  std_logic;
31
    ready_out               : out std_logic;
32
    sleep_time_out          : out std_logic_vector(sleep_time_w_c-1 downto 0);
33
    reg_addr_out            : out std_logic_vector(7 downto 0);
34
    config_data_out         : out std_logic_vector(7 downto 0);
35
    read_not_write_out      : out std_logic;
36
    config_valid_out        : out std_logic;
37
    data_from_comm_in       : in  std_logic_vector(data_width_c-1 downto 0);
38
    data_from_comm_valid_in : in  std_logic;
39
    comm_busy_in            : in  std_logic
40
    );
41
 
42
end DM9kA_init_module;
43
 
44
 
45
architecture rtl of DM9kA_init_module is
46
 
47
  type init_table_type is record
48
    addr       : std_logic_vector(7 downto 0);
49
    value      : std_logic_vector(7 downto 0);
50
    writing    : std_logic;
51
    sleep_time : integer;
52
  end record;
53
 
54
  constant init_values_c : integer := 24;
55
  type     init_table_array is array (0 to init_values_c-1) of init_table_type;
56
 
57
  constant init_table_c : init_table_array := (
58
    (GPCR_c, x"01", '1', 0),            -- 1
59
    (GPR_c, x"00", '1', power_up_sleep_c),    -- power up PHY
60
    (NCR_c, x"03", '1', 500),           -- software reset
61
    (NCR_c, x"00", '1', 0),
62
    (GPR_c, x"01", '1', 0),  -- shut down PHY, and start it once again
63
    (GPR_c, x"00", '1', 2*power_up_sleep_c),  -- don't know why, but it must be done
64
    (ISR_c, x"3F", '1', 0),             -- 16bit mode + reseting status
65
    (NSR_c, x"2C", '1', 0),             -- 10   reset NSR
66
    (NCR_c, x"00", '1', 0),
67
 
68
    (MAC1_c, MAC_addr_c(47 downto 40), '1', 0),  -- write MAC address
69
    (MAC2_c, MAC_addr_c(39 downto 32), '1', 0),
70
    (MAC3_c, MAC_addr_c(31 downto 24), '1', 0),
71
    (MAC4_c, MAC_addr_c(23 downto 16), '1', 0),
72
    (MAC5_c, MAC_addr_c(15 downto 8), '1', 0),
73
    (MAC6_c, MAC_addr_c(7 downto 0), '1', 0),
74
 
75
    (BPTR_c, x"3F", '1', 0),  -- send 600 us jam pattern when 3k left in RxRAM
76
    (FCTR_c, x"5A", '1', 0),            -- High/low water overflow thresholds
77
    (FCR_c, x"29", '1', 0),             -- 20   flow cntrl
78
    (WUCR_r, x"00", '1', 0),  -- wake up control (all wake up stuff disabled)
79
    (TCR2_c, x"80", '1', 0),            -- led mode 1
80
    (ETXCSR_c, x"83", '1', 0),          -- early transmit OFF.
81
    (IMR_c, x"83", '1', 0),   -- interrupt masks, allow rx and tx interrupts
82
    (RCR_c, x"39", '1', 0),   -- discard error/too long packets, enable rx
83
    (NSR_c, x"00", '0', 0));            -- 26   test read, bit 6 is link status
84
 
85
  signal init_cnt_r       : integer range 0 to init_values_c - 1;
86
  signal ready_r          : std_logic;
87
  signal data_from_comm_r : std_logic_vector(data_width_c-1 downto 0);
88
 
89
  type   init_state_type is (start, read_data, wait_busy, wait_link_up);
90
  signal state_r : init_state_type;
91
 
92
  signal reset_sleep_cnt_r : integer range 0 to reset_sleep_c;
93
 
94
  -- 1 second with 25MHz (yes, it's really necessary)
95
  constant link_wait_time_c : integer := 25_000_000;
96
  --constant link_wait_time_c : integer := 250;  -- ES simulation only!!!
97
 
98
  type   wait_link_type is (send_query, wait_reply, idle);
99
  signal wait_link_state_r : wait_link_type;
100
  signal wait_link_cnt_r   : integer range 0 to link_wait_time_c;
101
 
102
 
103
  -- how many seconds we wait until we are ready
104
  -- **************************************************************************
105
  -- * Okay, this might seem a bit weird thing to do (wait n seconds even after
106
  -- * the DM9kA tells us that it's link is up), but there's a reason to it.
107
  -- * When testing this block I noticed, that the PC on the other end needed
108
  -- * some time too to figure out that there is someone who might want to send
109
  -- * something. So if we start sending right after the DM9kA is ready, the PC
110
  -- * might not be ready to receive it.
111
  -- **************************************************************************
112
  constant continue_times_c : integer := 5;
113
  signal   continue_r       : integer range 0 to continue_times_c;
114
 
115
 
116
-------------------------------------------------------------------------------
117
begin  -- rtl
118
-------------------------------------------------------------------------------
119
 
120
  ready_out <= ready_r;
121
 
122
 
123
  --
124
  -- Sequential process for state machine
125
  --  
126
  init : process (clk, rst_n)
127
  begin  -- process init
128
    if rst_n = '0' then                 -- asynchronous reset (active low)
129
 
130
      ready_r            <= '0';
131
      init_cnt_r         <= 0;
132
      data_from_comm_r   <= (others => '0');
133
      reset_sleep_cnt_r  <= 0;
134
      wait_link_cnt_r    <= 0;
135
      continue_r         <= 0;
136
      sleep_time_out     <= (others => '0');
137
      reg_addr_out       <= (others => '0');
138
      config_data_out    <= (others => '0');
139
      read_not_write_out <= '0';
140
      config_valid_out   <= '0';
141
      state_r            <= start;
142
      wait_link_state_r  <= send_query;
143
 
144
    elsif clk'event and clk = '1' then  -- rising clock edge
145
 
146
      if reset_sleep_cnt_r /= reset_sleep_c then
147
        -- sleep for a while after reset release
148
        reset_sleep_cnt_r <= reset_sleep_cnt_r + 1;
149
 
150
      elsif ready_r = '0' then
151
 
152
        case state_r is
153
          when start =>
154
 
155
            reg_addr_out       <= init_table_c(init_cnt_r).addr;
156
            config_data_out    <= init_table_c(init_cnt_r).value;
157
            read_not_write_out <= not init_table_c(init_cnt_r).writing;
158
            sleep_time_out     <= std_logic_vector(to_unsigned(init_table_c(init_cnt_r).sleep_time, sleep_time_w_c));
159
            config_valid_out   <= '1';
160
 
161
            -- change state once busy is up (comm is working)
162
            if comm_busy_in = '1' then
163
              if init_table_c(init_cnt_r).writing = '0' then
164
                state_r <= read_data;
165
              else
166
                state_r <= wait_busy;
167
              end if;
168
            end if;
169
 
170
          when read_data =>
171
 
172
            -- reading is quite useless at the moment, but for example some
173
            -- registers can be cleared by reading if necessary
174
            if data_from_comm_valid_in = '1' then
175
              data_from_comm_r <= data_from_comm_in;
176
              state_r          <= wait_busy;
177
            end if;
178
 
179
          when wait_busy =>
180
 
181
            if comm_busy_in = '0' then
182
              config_valid_out <= '0';
183
 
184
              if init_cnt_r = init_values_c-1 then
185
                state_r <= wait_link_up;
186
              else
187
                init_cnt_r <= init_cnt_r + 1;
188
                state_r    <= start;
189
              end if;
190
            end if;
191
 
192
 
193
          when wait_link_up =>
194
 
195
            -- wait until link is up, before raising ready signal
196
            case wait_link_state_r is
197
              when send_query =>
198
 
199
                reg_addr_out       <= NSR_c;
200
                config_data_out    <= (others => '0');
201
                read_not_write_out <= '1';
202
                config_valid_out   <= '1';
203
                wait_link_state_r  <= wait_reply;
204
 
205
              when wait_reply =>
206
 
207
                if data_from_comm_valid_in = '1' then
208
                  if data_from_comm_in(6) = '1' then
209
                    -- if bit 6 from NSR - the link up bit - is up, wait continue_times_c
210
                    -- more and then continue
211
                    continue_r <= continue_r + 1;
212
                  end if;
213
                  wait_link_state_r <= idle;
214
                  config_valid_out  <= '0';
215
                end if;
216
 
217
              when idle =>
218
 
219
                if wait_link_cnt_r = link_wait_time_c then
220
 
221
                  wait_link_cnt_r <= 0;
222
                  -- check if link is up, and raise ready if so
223
                  if continue_r = continue_times_c then
224
                    ready_r <= '1';
225
                    state_r <= start;
226
                  end if;
227
                  wait_link_state_r <= send_query;
228
 
229
                else
230
                  wait_link_cnt_r <= wait_link_cnt_r + 1;
231
                end if;
232
              when others => null;
233
            end case;
234
          when others => null;
235
        end case;
236
 
237
      else
238
        -- ready_r = '1'
239
 
240
        reg_addr_out       <= (others => '0');
241
        config_data_out    <= (others => '0');
242
        read_not_write_out <= '0';
243
        config_valid_out   <= '0';
244
 
245
      end if;
246
    end if;
247
  end process init;
248
 
249
 
250
end rtl;

powered by: WebSVN 2.1.0

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