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 35

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 22 dkoethe
    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 2 dkoethe
    ---------------------------------------------------------------------------
55
    -- read transfer
56
    -- read data from memory and fill fifo
57 22 dkoethe
    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 2 dkoethe
    -- enable/disable dma transfer
61 22 dkoethe
    opb_tx_dma_ctl    : in  std_logic_vector(0 downto 0);
62 2 dkoethe
    -- base adress for transfer
63 22 dkoethe
    opb_tx_dma_addr   : in  std_logic_vector(C_OPB_DWIDTH-1 downto 0);
64
    opb_tx_dma_num    : in  std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
65
    opb_tx_dma_done   : out std_logic;
66 2 dkoethe
    ---------------------------------------------------------------------------
67
    -- write transfer
68
    -- read fifo an write to memory 
69 22 dkoethe
    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 2 dkoethe
    -- enable/disable dma transfer
73 22 dkoethe
    opb_rx_dma_ctl    : in  std_logic_vector(0 downto 0);
74 2 dkoethe
    -- base adress for transfer
75 22 dkoethe
    opb_rx_dma_addr   : in  std_logic_vector(C_OPB_DWIDTH-1 downto 0);
76
    opb_rx_dma_num    : in  std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
77
    opb_rx_dma_done   : out std_logic;
78 13 dkoethe
    ---------------------------------------------------------------------------
79 22 dkoethe
    opb_abort_flg     : out std_logic;
80
    opb_m_last_block : out std_logic);
81 2 dkoethe
end opb_m_if;
82
 
83
architecture behavior of opb_m_if is
84
 
85
  type state_t is (idle,
86
                   wait_grant,
87
                   transfer_write,
88
                   transfer_read,
89
                   done);
90
 
91
 
92
  signal state : state_t := idle;
93
 
94
  signal M_DBus_big_end   : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
95
  signal M_ABus_big_end   : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
96
  signal OPB_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
97
 
98
  signal M_select_int  : std_logic;
99
  signal read_transfer : boolean;
100
 
101
  -- read transfer
102
  signal opb_tx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
103
  signal opb_tx_dma_en       : std_logic;
104 10 dkoethe
  signal opb_tx_dma_num_int  : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
105 2 dkoethe
  signal opb_tx_dma_done_int : std_logic;
106 13 dkoethe
 
107 2 dkoethe
  -- write transfer
108
  signal opb_rx_dma_en       : std_logic;
109
  signal opb_rx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
110 10 dkoethe
  signal opb_rx_dma_num_int  : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
111 13 dkoethe
  signal opb_rx_dma_done_int : std_logic;
112 2 dkoethe
 
113
 
114
begin  -- behavior
115
 
116
  --* convert M_DBus_big_end to little endian
117
  process(M_DBus_big_end)
118
  begin
119
    for i in 0 to 31 loop
120
      M_DBus(31-i) <= M_DBus_big_end(i);
121
    end loop;  -- i  
122
  end process;
123
 
124
  --* convert M_ABus_big_end to little endian
125
  process(M_ABus_big_end)
126
  begin
127
    for i in 0 to 31 loop
128
      M_ABus(31-i) <= M_ABus_big_end(i);
129
    end loop;  -- i  
130
  end process;
131
 
132
  --* convert OPB_DBus to bi endian
133
  process(OPB_DBus)
134
  begin
135
    for i in 0 to 31 loop
136
      OPB_DBus_big_end(31-i) <= OPB_DBus(i);
137
    end loop;  -- i  
138
  end process;
139
 
140
  -- for both sides
141
  M_ABus_big_end <= opb_tx_dma_addr_int when (M_select_int = '1' and (read_transfer = true)) else
142
                    opb_rx_dma_addr_int when (M_select_int = '1' and (read_transfer = false)) else
143
                    (others => '0');
144
  M_select <= M_select_int;
145
 
146
 
147
 
148
  -- write transfer
149
  opb_m_rx_en <= MOPB_xferAck when (M_select_int = '1' and (read_transfer = false)) else
150
                 '0';
151
 
152
  M_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_m_rx_data when (M_select_int = '1' and (read_transfer = false)) else
153
                                           (others => '0');
154
  M_DBus_big_end(C_OPB_DWIDTH-1 downto C_SR_WIDTH) <= (others => '0');
155
 
156 13 dkoethe
  opb_tx_dma_done <= opb_tx_dma_done_int;
157 2 dkoethe
 
158
  -- read transfer
159
  opb_m_tx_en <= MOPB_xferAck when (M_select_int = '1' and (read_transfer = true)) else
160
                 '0';
161
  opb_m_tx_data <= OPB_DBus_big_end(C_SR_WIDTH-1 downto 0);
162
 
163
  opb_rx_dma_done <= opb_rx_dma_done_int;
164
 
165
 
166
 
167
-------------------------------------------------------------------------------
168 13 dkoethe
  opb_masteer_proc : process(OPB_Rst, OPB_Clk)
169 2 dkoethe
  begin
170
    if (OPB_Rst = '1') then
171 13 dkoethe
      M_BE                <= (others => '0');
172
      M_busLock           <= '0';
173
      M_request           <= '0';
174
      M_RNW               <= '0';
175
      M_select_int        <= '0';
176
      M_seqAddr           <= '0';
177 2 dkoethe
      opb_tx_dma_done_int <= '0';
178
      opb_rx_dma_done_int <= '0';
179 13 dkoethe
      opb_abort_flg       <= '0';
180 22 dkoethe
      opb_m_last_block   <= '0';
181
      opb_tx_dma_num_int <= (others => '0');
182
      opb_rx_dma_num_int <= (others => '0');
183 2 dkoethe
    elsif rising_edge(OPB_Clk) then
184
      case state is
185
        when idle =>
186 13 dkoethe
          opb_abort_flg <= '0';
187 2 dkoethe
          opb_tx_dma_en <= opb_tx_dma_ctl(0);
188
          opb_rx_dma_en <= opb_rx_dma_ctl(0);
189
 
190
          if (opb_tx_dma_ctl(0) = '1' and opb_tx_dma_en = '0') then
191
            opb_tx_dma_addr_int <= opb_tx_dma_addr;
192
            opb_tx_dma_num_int  <= opb_tx_dma_num;
193 13 dkoethe
            opb_tx_dma_done_int <= '0';
194 2 dkoethe
 
195
          end if;
196
 
197
          if (opb_rx_dma_ctl(0) = '1' and opb_rx_dma_en = '0') then
198
            opb_rx_dma_addr_int <= opb_rx_dma_addr;
199
            opb_rx_dma_num_int  <= opb_rx_dma_num;
200 13 dkoethe
            opb_rx_dma_done_int <= '0';
201 2 dkoethe
          end if;
202
 
203
          if (opb_tx_dma_en = '1' and opb_m_tx_req = '1' and opb_tx_dma_done_int = '0') then
204
            -- read from memory to fifo
205
            M_request     <= '1';
206
            read_transfer <= true;
207
            state         <= wait_grant;
208
          elsif (opb_rx_dma_en = '1' and opb_m_rx_req = '1'and opb_rx_dma_done_int = '0') then
209
            -- read from fifo and write memory
210
            M_request     <= '1';
211
            read_transfer <= false;
212
            state         <= wait_grant;
213
          else
214
            state <= idle;
215
          end if;
216
 
217
        when wait_grant =>
218
          if (MOPB_MGrant = '1') then
219
            M_request    <= '0';
220
            M_busLock    <= '1';
221
            M_select_int <= '1';
222
            M_seqAddr    <= '1';
223
            M_BE         <= "1111";
224
            if (read_transfer) then
225
              -- read
226
              M_RNW <= '1';
227 22 dkoethe
              if (conv_integer(opb_tx_dma_num_int) = 0) then
228
                opb_m_last_block <= '1';
229
              end if;
230 2 dkoethe
              state <= transfer_read;
231
            else
232
              -- write
233
              M_RNW <= '0';
234 22 dkoethe
              if (conv_integer(opb_rx_dma_num_int) = 0) then
235
                opb_m_last_block <= '1';
236
              end if;
237 2 dkoethe
              state <= transfer_write;
238
            end if;
239
          else
240
            state <= wait_grant;
241
          end if;
242
 
243
        when transfer_read =>
244
          if (MOPB_xferAck = '1') then
245
            opb_tx_dma_addr_int <= opb_tx_dma_addr_int +4;
246
            if (opb_tx_dma_addr_int(5 downto 2) = conv_std_logic_vector(14, 4)) then
247
              -- cycle 14
248
              -- deassert buslock and seq_address 1 cycle before transfer complete
249
              M_busLock <= '0';
250
              M_seqAddr <= '0';
251
            elsif (opb_tx_dma_addr_int(5 downto 2) = conv_std_logic_vector(15, 4)) then
252
              -- cycle 15
253
              M_RNW        <= '0';
254
              M_select_int <= '0';
255
              M_BE         <= (others => '0');
256
              if (conv_integer(opb_tx_dma_num_int) = 0) then
257
                opb_tx_dma_done_int <= '1';
258 22 dkoethe
                opb_m_last_block   <= '0';
259 2 dkoethe
              else
260
                opb_tx_dma_num_int <= opb_tx_dma_num_int-1;
261
              end if;
262
              state <= done;
263
            end if;
264
          elsif (MOPB_retry = '1' or MOPB_errAck = '1' or MOPB_timeout = '1') then
265
            -- cancel transfer
266 13 dkoethe
            M_busLock     <= '0';
267
            M_seqAddr     <= '0';
268
            M_RNW         <= '0';
269
            M_select_int  <= '0';
270
            M_BE          <= (others => '0');
271
            opb_abort_flg <= '1';
272
            state         <= done;
273 2 dkoethe
          else
274
            state <= transfer_read;
275
          end if;
276
 
277
        when transfer_write =>
278
          if (MOPB_xferAck = '1') then
279
            opb_rx_dma_addr_int <= opb_rx_dma_addr_int +4;
280
            if (opb_rx_dma_addr_int(5 downto 2) = conv_std_logic_vector(14, 4)) then
281
              -- cycle 14
282
              -- deassert buslock and seq_address 1 cycle before transfer complete
283
              M_busLock <= '0';
284
              M_seqAddr <= '0';
285
            elsif (opb_rx_dma_addr_int(5 downto 2) = conv_std_logic_vector(15, 4)) then
286
              -- cycle 15
287
              M_RNW        <= '0';
288
              M_select_int <= '0';
289
              M_BE         <= (others => '0');
290
              if (conv_integer(opb_rx_dma_num_int) = 0) then
291
                opb_rx_dma_done_int <= '1';
292 22 dkoethe
                opb_m_last_block   <= '0';
293 2 dkoethe
              else
294
                opb_rx_dma_num_int <= opb_rx_dma_num_int-1;
295
              end if;
296
              state <= done;
297
            end if;
298
          elsif (MOPB_retry = '1' or MOPB_errAck = '1' or MOPB_timeout = '1') then
299
            -- cancel transfer
300 13 dkoethe
            M_busLock     <= '0';
301
            M_seqAddr     <= '0';
302
            M_RNW         <= '0';
303
            M_select_int  <= '0';
304
            M_BE          <= (others => '0');
305
            opb_abort_flg <= '1';
306
            state         <= done;
307 2 dkoethe
          else
308
            state <= transfer_write;
309
          end if;
310
 
311
        when done =>
312
 
313
          state <= idle;
314
 
315
        when others =>
316
          state <= idle;
317
      end case;
318
    end if;
319
  end process opb_masteer_proc;
320
end behavior;

powered by: WebSVN 2.1.0

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