Root/plasma/logic/eth_dma.vhd

1---------------------------------------------------------------------
2-- TITLE: Ethernet DMA
3-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4-- DATE CREATED: 12/27/07
5-- FILENAME: eth_dma.vhd
6-- PROJECT: Plasma CPU core
7-- COPYRIGHT: Software placed into the public domain by the author.
8-- Software 'as is' without warranty. Author liable for nothing.
9-- DESCRIPTION:
10-- Ethernet DMA (Direct Memory Access) controller.
11-- Reads four bits and writes four bits from/to the Ethernet PHY each
12-- 2.5 MHz clock cycle. Received data is DMAed starting at 0x13ff0000
13-- transmit data is read from 0x13fd0000.
14-- To send a packet write bytes/4 to Ethernet send register.
15---------------------------------------------------------------------
16library ieee;
17use ieee.std_logic_1164.all;
18use ieee.std_logic_unsigned.all;
19use ieee.std_logic_arith.all;
20use work.mlite_pack.all;
21
22entity eth_dma is port(
23   clk : in std_logic; --25 MHz
24   reset : in std_logic;
25   enable_eth : in std_logic; --enable receive DMA
26   select_eth : in std_logic;
27   rec_isr : out std_logic; --data received
28   send_isr : out std_logic; --transmit done
29
30   address : out std_logic_vector(31 downto 2); --to DDR
31   byte_we : out std_logic_vector(3 downto 0);
32   data_write : out std_logic_vector(31 downto 0);
33   data_read : in std_logic_vector(31 downto 0);
34   pause_in : in std_logic;
35
36   mem_address : in std_logic_vector(31 downto 2); --from CPU
37   mem_byte_we : in std_logic_vector(3 downto 0);
38   data_w : in std_logic_vector(31 downto 0);
39   pause_out : out std_logic;
40
41   E_RX_CLK : in std_logic; --2.5 MHz receive
42   E_RX_DV : in std_logic; --data valid
43   E_RXD : in std_logic_vector(3 downto 0); --receive nibble
44   E_TX_CLK : in std_logic; --2.5 MHz transmit
45   E_TX_EN : out std_logic; --transmit enable
46   E_TXD : out std_logic_vector(3 downto 0)); --transmit nibble
47end; --entity eth_dma
48
49architecture logic of eth_dma is
50   signal rec_clk : std_logic_vector(1 downto 0); --receive
51   signal rec_store : std_logic_vector(31 downto 0); --to DDR
52   signal rec_data : std_logic_vector(27 downto 0);
53   signal rec_cnt : std_logic_vector(2 downto 0); --nibbles
54   signal rec_words : std_logic_vector(13 downto 0);
55   signal rec_dma : std_logic_vector(1 downto 0); --active & request
56   signal rec_done : std_logic;
57
58   signal send_clk : std_logic_vector(1 downto 0); --transmit
59   signal send_read : std_logic_vector(31 downto 0); --from DDR
60   signal send_data : std_logic_vector(31 downto 0);
61   signal send_cnt : std_logic_vector(2 downto 0); --nibbles
62   signal send_words : std_logic_vector(8 downto 0);
63   signal send_level : std_logic_vector(8 downto 0);
64   signal send_dma : std_logic_vector(1 downto 0); --active & request
65   signal send_enable: std_logic;
66
67begin --architecture
68
69   dma_proc: process(clk, reset, enable_eth, select_eth,
70         data_read, pause_in, mem_address, mem_byte_we, data_w,
71         E_RX_CLK, E_RX_DV, E_RXD, E_TX_CLK,
72         rec_clk, rec_store, rec_data,
73         rec_cnt, rec_words, rec_dma, rec_done,
74         send_clk, send_read, send_data, send_cnt, send_words,
75         send_level, send_dma, send_enable)
76   begin
77
78      if reset = '1' then
79         rec_clk <= "00";
80         rec_cnt <= "000";
81         rec_words <= ZERO(13 downto 0);
82         rec_dma <= "00";
83         rec_done <= '0';
84         send_clk <= "00";
85         send_cnt <= "000";
86         send_words <= ZERO(8 downto 0);
87         send_level <= ZERO(8 downto 0);
88         send_dma <= "00";
89         send_enable <= '0';
90      elsif rising_edge(clk) then
91
92         --Receive nibble on low->high E_RX_CLK. Send to DDR every 32 bits.
93         rec_clk <= rec_clk(0) & E_RX_CLK;
94         if rec_clk = "01" and enable_eth = '1' then
95            if E_RX_DV = '1' or rec_cnt /= "000" then
96               if rec_cnt = "111" then
97                  rec_store <= rec_data & E_RXD;
98                  rec_dma(0) <= '1'; --request DMA
99               end if;
100               rec_data <= rec_data(23 downto 0) & E_RXD;
101               rec_cnt <= rec_cnt + 1;
102            end if;
103         end if;
104
105         --Set transmit count or clear receive interrupt
106         if select_eth = '1' then
107            if mem_byte_we /= "0000" then
108               send_cnt <= "000";
109               send_words <= ZERO(8 downto 0);
110               send_level <= data_w(8 downto 0);
111               send_dma(0) <= '1';
112            else
113               rec_done <= '0';
114            end if;
115         end if;
116
117         --Transmit nibble on low->high E_TX_CLK. Get 32 bits from DDR.
118         send_clk <= send_clk(0) & E_TX_CLK;
119         if send_clk = "01" then
120            if send_cnt = "111" then
121               if send_words /= send_level then
122                  send_data <= send_read;
123                  send_dma(0) <= '1';
124                  send_enable <= '1';
125               else
126                  send_enable <= '0';
127               end if;
128            else
129               send_data(31 downto 4) <= send_data(27 downto 0);
130            end if;
131            send_cnt <= send_cnt + 1;
132         end if;
133
134         --Pick which type of DMA operation: bit0 = request; bit1 = active
135         if pause_in = '0' then
136            if rec_dma(1) = '1' then
137               rec_dma <= "00"; --DMA done
138               rec_words <= rec_words + 1;
139               if E_RX_DV = '0' then
140                  rec_done <= '1';
141               end if;
142            elsif send_dma(1) = '1' then
143               send_dma <= "00";
144               send_words <= send_words + 1;
145               send_read <= data_read;
146            elsif rec_dma(0) = '1' then
147               rec_dma(1) <= '1'; --start DMA
148            elsif send_dma(0) = '1' then
149               send_dma(1) <= '1'; --start DMA
150            end if;
151         end if;
152
153      end if; --rising_edge(clk)
154
155      E_TXD <= send_data(31 downto 28);
156      E_TX_EN <= send_enable;
157      rec_isr <= rec_done;
158      if send_words = send_level then
159         send_isr <= '1';
160      else
161         send_isr <= '0';
162      end if;
163
164      if rec_dma(1) = '1' then
165         address <= "0001001111111111" & rec_words; --0x13ff0000
166         byte_we <= "1111";
167         data_write <= rec_store;
168         pause_out <= '1'; --to CPU
169      elsif send_dma(1) = '1' then
170         address <= "000100111111111000000" & send_words; --0x13fe0000
171         byte_we <= "0000";
172         data_write <= data_w;
173         pause_out <= '1';
174      else
175         address <= mem_address; --Send request from CPU to DDR
176         byte_we <= mem_byte_we;
177         data_write <= data_w;
178         pause_out <= '0';
179      end if;
180
181   end process;
182
183end; --architecture logic
184

Archive Download this file

Branches:
master



interactive