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

Subversion Repositories spi_slave

[/] [spi_slave/] [trunk/] [pcore/] [opb_spi_slave_v1_00_a/] [hdl/] [vhdl/] [opb_m_if.vhd] - Blame information for rev 10

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

Line No. Rev Author Line
1 2 dkoethe
-------------------------------------------------------------------------------
2
--* 
3
--* @short OPB-Master Interface
4
--* 
5
--* Generics described in top entity.
6
--*
7
--* @see opb_spi_slave
8
--*    @author: Daniel Köthe
9
--*   @version: 1.0
10
--* @date: 2007-11-11
11
--/
12
-------------------------------------------------------------------------------
13
library ieee;
14
use ieee.std_logic_1164.all;
15
use IEEE.STD_LOGIC_ARITH.all;
16
use IEEE.STD_LOGIC_UNSIGNED.all;
17
use IEEE.numeric_std.all;               -- conv_integer()
18
 
19 10 dkoethe
library work;
20
use work.opb_spi_slave_pack.all;
21
 
22 2 dkoethe
entity opb_m_if is
23
  generic (
24
    C_BASEADDR        : std_logic_vector(0 to 31) := X"00000000";
25
    C_HIGHADDR        : std_logic_vector(0 to 31) := X"FFFFFFFF";
26
    C_USER_ID_CODE    : integer                   := 0;
27
    C_OPB_AWIDTH      : integer                   := 32;
28
    C_OPB_DWIDTH      : integer                   := 32;
29
    C_FAMILY          : string                    := "virtex-4";
30
    C_SR_WIDTH        : integer                   := 8;
31
    C_MSB_FIRST       : boolean                   := true;
32
    C_CPOL            : integer range 0 to 1      := 0;
33
    C_PHA             : integer range 0 to 1      := 0;
34
    C_FIFO_SIZE_WIDTH : integer range 4 to 7      := 7);
35
 
36
  port (
37
    -- opb master interface
38
    OPB_Clk         : in  std_logic;
39
    OPB_Rst         : in  std_logic;
40
    OPB_DBus        : in  std_logic_vector(0 to C_OPB_DWIDTH-1);
41
    M_request       : out std_logic;
42
    MOPB_MGrant     : in  std_logic;
43
    M_busLock       : out std_logic;
44
    M_ABus          : out std_logic_vector(0 to C_OPB_AWIDTH-1);
45
    M_BE            : out std_logic_vector(0 to C_OPB_DWIDTH/8-1);
46
    M_DBus          : out std_logic_vector(0 to C_OPB_DWIDTH-1);
47
    M_RNW           : out std_logic;
48
    M_select        : out std_logic;
49
    M_seqAddr       : out std_logic;
50
    MOPB_errAck     : in  std_logic;
51
    MOPB_retry      : in  std_logic;
52
    MOPB_timeout    : in  std_logic;
53
    MOPB_xferAck    : in  std_logic;
54
    ---------------------------------------------------------------------------
55
    -- read transfer
56
    -- read data from memory and fill fifo
57
    opb_m_tx_req    : in  std_logic;
58
    opb_m_tx_en     : out std_logic;
59
    opb_m_tx_data   : out std_logic_vector(C_SR_WIDTH-1 downto 0);
60
    -- enable/disable dma transfer
61
    opb_tx_dma_ctl  : in  std_logic_vector(0 downto 0);
62
    -- base adress for transfer
63
    opb_tx_dma_addr : in  std_logic_vector(C_OPB_DWIDTH-1 downto 0);
64 10 dkoethe
    opb_tx_dma_num  : in  std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
65 2 dkoethe
    opb_tx_dma_done : out std_logic;
66
    ---------------------------------------------------------------------------
67
    -- write transfer
68
    -- read fifo an write to memory 
69
    opb_m_rx_req    : in  std_logic;
70
    opb_m_rx_en     : out std_logic;
71
    opb_m_rx_data   : in  std_logic_vector(C_SR_WIDTH-1 downto 0);
72
    -- enable/disable dma transfer
73
    opb_rx_dma_ctl  : in  std_logic_vector(0 downto 0);
74
    -- base adress for transfer
75
    opb_rx_dma_addr : in  std_logic_vector(C_OPB_DWIDTH-1 downto 0);
76 10 dkoethe
    opb_rx_dma_num  : in  std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
77 2 dkoethe
    opb_rx_dma_done : out std_logic);
78
end opb_m_if;
79
 
80
architecture behavior of opb_m_if is
81
 
82
  type state_t is (idle,
83
                   wait_grant,
84
                   transfer_write,
85
                   transfer_read,
86
                   done);
87
 
88
 
89
  signal state : state_t := idle;
90
 
91
  signal M_DBus_big_end   : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
92
  signal M_ABus_big_end   : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
93
  signal OPB_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
94
 
95
  signal M_select_int  : std_logic;
96
  signal read_transfer : boolean;
97
 
98
  -- read transfer
99
  signal opb_tx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
100
  signal opb_tx_dma_en       : std_logic;
101 10 dkoethe
  signal opb_tx_dma_num_int  : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
102 2 dkoethe
  signal opb_tx_dma_done_int : std_logic;
103
 
104
  -- write transfer
105
  signal opb_rx_dma_en       : std_logic;
106
  signal opb_rx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
107 10 dkoethe
  signal opb_rx_dma_num_int  : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
108 2 dkoethe
  signal opb_rx_dma_done_int : std_logic;
109
 
110
 
111
 
112
begin  -- behavior
113
 
114
  --* convert M_DBus_big_end to little endian
115
  process(M_DBus_big_end)
116
  begin
117
    for i in 0 to 31 loop
118
      M_DBus(31-i) <= M_DBus_big_end(i);
119
    end loop;  -- i  
120
  end process;
121
 
122
  --* convert M_ABus_big_end to little endian
123
  process(M_ABus_big_end)
124
  begin
125
    for i in 0 to 31 loop
126
      M_ABus(31-i) <= M_ABus_big_end(i);
127
    end loop;  -- i  
128
  end process;
129
 
130
  --* convert OPB_DBus to bi endian
131
  process(OPB_DBus)
132
  begin
133
    for i in 0 to 31 loop
134
      OPB_DBus_big_end(31-i) <= OPB_DBus(i);
135
    end loop;  -- i  
136
  end process;
137
 
138
  -- for both sides
139
  M_ABus_big_end <= opb_tx_dma_addr_int when (M_select_int = '1' and (read_transfer = true)) else
140
                    opb_rx_dma_addr_int when (M_select_int = '1' and (read_transfer = false)) else
141
                    (others => '0');
142
  M_select <= M_select_int;
143
 
144
 
145
 
146
  -- write transfer
147
  opb_m_rx_en <= MOPB_xferAck when (M_select_int = '1' and (read_transfer = false)) else
148
                 '0';
149
 
150
  M_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_m_rx_data when (M_select_int = '1' and (read_transfer = false)) else
151
                                           (others => '0');
152
  M_DBus_big_end(C_OPB_DWIDTH-1 downto C_SR_WIDTH) <= (others => '0');
153
 
154
  opb_tx_dma_done <= opb_tx_dma_done_int;
155
 
156
  -- read transfer
157
  opb_m_tx_en <= MOPB_xferAck when (M_select_int = '1' and (read_transfer = true)) else
158
                 '0';
159
  opb_m_tx_data <= OPB_DBus_big_end(C_SR_WIDTH-1 downto 0);
160
 
161
  opb_rx_dma_done <= opb_rx_dma_done_int;
162
 
163
 
164
 
165
-------------------------------------------------------------------------------
166
  opb_masteer_proc: process(OPB_Rst, OPB_Clk)
167
  begin
168
    if (OPB_Rst = '1') then
169
      M_BE            <= (others => '0');
170
      M_busLock       <= '0';
171
      M_request       <= '0';
172
      M_RNW           <= '0';
173
      M_select_int    <= '0';
174
      M_seqAddr       <= '0';
175
      opb_tx_dma_done_int <= '0';
176
      opb_rx_dma_done_int <= '0';
177
    elsif rising_edge(OPB_Clk) then
178
      case state is
179
        when idle =>
180
          opb_tx_dma_en <= opb_tx_dma_ctl(0);
181
          opb_rx_dma_en <= opb_rx_dma_ctl(0);
182
 
183
          if (opb_tx_dma_ctl(0) = '1' and opb_tx_dma_en = '0') then
184
            opb_tx_dma_addr_int <= opb_tx_dma_addr;
185
            opb_tx_dma_num_int  <= opb_tx_dma_num;
186
            opb_tx_dma_done_int     <= '0';
187
 
188
          end if;
189
 
190
          if (opb_rx_dma_ctl(0) = '1' and opb_rx_dma_en = '0') then
191
            opb_rx_dma_addr_int <= opb_rx_dma_addr;
192
            opb_rx_dma_num_int  <= opb_rx_dma_num;
193
            opb_rx_dma_done_int    <= '0';
194
          end if;
195
 
196
          if (opb_tx_dma_en = '1' and opb_m_tx_req = '1' and opb_tx_dma_done_int = '0') then
197
            -- read from memory to fifo
198
            M_request     <= '1';
199
            read_transfer <= true;
200
            state         <= wait_grant;
201
          elsif (opb_rx_dma_en = '1' and opb_m_rx_req = '1'and opb_rx_dma_done_int = '0') then
202
            -- read from fifo and write memory
203
            M_request     <= '1';
204
            read_transfer <= false;
205
            state         <= wait_grant;
206
          else
207
            state <= idle;
208
          end if;
209
 
210
        when wait_grant =>
211
          if (MOPB_MGrant = '1') then
212
            M_request    <= '0';
213
            M_busLock    <= '1';
214
            M_select_int <= '1';
215
            M_seqAddr    <= '1';
216
            M_BE         <= "1111";
217
            if (read_transfer) then
218
              -- read
219
              M_RNW <= '1';
220
              state <= transfer_read;
221
            else
222
              -- write
223
              M_RNW <= '0';
224
              state <= transfer_write;
225
            end if;
226
          else
227
            state <= wait_grant;
228
          end if;
229
 
230
        when transfer_read =>
231
          if (MOPB_xferAck = '1') then
232
            opb_tx_dma_addr_int <= opb_tx_dma_addr_int +4;
233
            if (opb_tx_dma_addr_int(5 downto 2) = conv_std_logic_vector(14, 4)) then
234
              -- cycle 14
235
              -- deassert buslock and seq_address 1 cycle before transfer complete
236
              M_busLock <= '0';
237
              M_seqAddr <= '0';
238
            elsif (opb_tx_dma_addr_int(5 downto 2) = conv_std_logic_vector(15, 4)) then
239
              -- cycle 15
240
              M_RNW        <= '0';
241
              M_select_int <= '0';
242
              M_BE         <= (others => '0');
243
              if (conv_integer(opb_tx_dma_num_int) = 0) then
244
                opb_tx_dma_done_int <= '1';
245
              else
246
                opb_tx_dma_num_int <= opb_tx_dma_num_int-1;
247
              end if;
248
              state <= done;
249
            end if;
250
          elsif (MOPB_retry = '1' or MOPB_errAck = '1' or MOPB_timeout = '1') then
251
            -- cancel transfer
252
            M_busLock    <= '0';
253
            M_seqAddr    <= '0';
254
            M_RNW        <= '0';
255
            M_select_int <= '0';
256
            M_BE         <= (others => '0');
257
            state        <= done;
258
          else
259
            state <= transfer_read;
260
          end if;
261
 
262
        when transfer_write =>
263
          if (MOPB_xferAck = '1') then
264
            opb_rx_dma_addr_int <= opb_rx_dma_addr_int +4;
265
            if (opb_rx_dma_addr_int(5 downto 2) = conv_std_logic_vector(14, 4)) then
266
              -- cycle 14
267
              -- deassert buslock and seq_address 1 cycle before transfer complete
268
              M_busLock <= '0';
269
              M_seqAddr <= '0';
270
            elsif (opb_rx_dma_addr_int(5 downto 2) = conv_std_logic_vector(15, 4)) then
271
              -- cycle 15
272
              M_RNW        <= '0';
273
              M_select_int <= '0';
274
              M_BE         <= (others => '0');
275
              if (conv_integer(opb_rx_dma_num_int) = 0) then
276
                opb_rx_dma_done_int <= '1';
277
              else
278
                opb_rx_dma_num_int <= opb_rx_dma_num_int-1;
279
              end if;
280
              state <= done;
281
            end if;
282
          elsif (MOPB_retry = '1' or MOPB_errAck = '1' or MOPB_timeout = '1') then
283
            -- cancel transfer
284
            M_busLock    <= '0';
285
            M_seqAddr    <= '0';
286
            M_RNW        <= '0';
287
            M_select_int <= '0';
288
            M_BE         <= (others => '0');
289
            state        <= done;
290
          else
291
            state <= transfer_write;
292
          end if;
293
 
294
        when done =>
295
 
296
          state <= idle;
297
 
298
        when others =>
299
          state <= idle;
300
      end case;
301
    end if;
302
  end process opb_masteer_proc;
303
end behavior;

powered by: WebSVN 2.1.0

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