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_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-Slave 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
library work;
20
use work.opb_spi_slave_pack.all;
21
 
22
entity opb_if is
23
 
24
  generic (
25
    C_BASEADDR        : std_logic_vector(0 to 31) := X"00000000";
26
    C_HIGHADDR        : std_logic_vector(0 to 31) := X"FFFFFFFF";
27
    C_USER_ID_CODE    : integer                   := 3;
28
    C_OPB_AWIDTH      : integer                   := 32;
29
    C_OPB_DWIDTH      : integer                   := 32;
30
    C_FAMILY          : string                    := "virtex-4";
31
    C_SR_WIDTH        : integer                   := 8;
32
    C_FIFO_SIZE_WIDTH : integer                   := 4;
33
    C_DMA_EN          : boolean                   := true);
34
  port (
35
    -- OPB-Bus Signals
36
    OPB_ABus        : in  std_logic_vector(0 to C_OPB_AWIDTH-1);
37
    OPB_BE          : in  std_logic_vector(0 to C_OPB_DWIDTH/8-1);
38
    OPB_Clk         : in  std_logic;
39
    OPB_DBus        : in  std_logic_vector(0 to C_OPB_DWIDTH-1);
40
    OPB_RNW         : in  std_logic;
41
    OPB_Rst         : in  std_logic;
42
    OPB_select      : in  std_logic;
43
    OPB_seqAddr     : in  std_logic;
44
    Sln_DBus        : out std_logic_vector(0 to C_OPB_DWIDTH-1);
45
    Sln_errAck      : out std_logic;
46
    Sln_retry       : out std_logic;
47
    Sln_toutSup     : out std_logic;
48
    Sln_xferAck     : out std_logic;
49
    -- fifo ports
50
    opb_s_tx_en     : out std_logic;
51
    opb_s_tx_data   : out std_logic_vector(C_SR_WIDTH-1 downto 0);
52
    opb_s_rx_en     : out std_logic;
53
    opb_s_rx_data   : in  std_logic_vector(C_SR_WIDTH-1 downto 0);
54
    -- control register
55
    opb_ctl_reg     : out std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0);
56
    -- Fifo almost full/empty thresholds
57
    tx_thresh       : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0);
58
    rx_thresh       : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0);
59
    opb_fifo_flg    : in  std_logic_vector(C_NUM_FLG-1 downto 0);
60
    -- interrupts
61
    opb_dgie        : out std_logic;
62
    opb_ier         : out std_logic_vector(C_NUM_INT-1 downto 0);
63
    opb_isr         : in  std_logic_vector(C_NUM_INT-1 downto 0);
64
    opb_isr_clr     : out std_logic_vector(C_NUM_INT-1 downto 0);
65
    -- dma register
66
    opb_tx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0);
67
    opb_tx_dma_ctl  : out std_logic_vector(0 downto 0);
68 10 dkoethe
    opb_tx_dma_num  : out std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
69 2 dkoethe
    opb_rx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0);
70
    opb_rx_dma_ctl  : out std_logic_vector(0 downto 0);
71 10 dkoethe
    opb_rx_dma_num  : out std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0));
72 2 dkoethe
end opb_if;
73
 
74
architecture behavior of opb_if is
75
 
76
 
77
  signal Sln_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
78
  signal OPB_ABus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
79
  signal OPB_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
80
 
81
 
82
  type state_t is (idle,
83
                   done);
84
  signal state : state_t := idle;
85
 
86
  -- internal signals to enable readback
87
 
88
  signal tx_thresh_int : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0);
89
  signal rx_thresh_int : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0);
90
  signal opb_ier_int   : std_logic_vector(C_NUM_INT-1 downto 0);
91
  signal opb_dgie_int  : std_logic;
92
 
93
  signal opb_ctl_reg_int : std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0);
94
 
95
 
96
  -- only used if C_DMA_EN=true
97
  signal opb_tx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
98
  signal opb_tx_dma_ctl_int  : std_logic_vector(0 downto 0);
99 10 dkoethe
  signal opb_tx_dma_num_int  : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
100 2 dkoethe
  signal opb_rx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0);
101
  signal opb_rx_dma_ctl_int  : std_logic_vector(0 downto 0);
102 10 dkoethe
  signal opb_rx_dma_num_int  : std_logic_vector(C_WIDTH_DMA_NUM-1 downto 0);
103 2 dkoethe
 
104
begin  -- behavior
105
 
106
  tx_thresh <= tx_thresh_int;
107
  rx_thresh <= rx_thresh_int;
108
  opb_ier   <= opb_ier_int;
109
  opb_dgie  <= opb_dgie_int;
110
 
111
  opb_ctl_reg <= opb_ctl_reg_int;
112
 
113
  --* Signals for DMA-Engine control
114
  u1 : if C_DMA_EN generate
115
    opb_tx_dma_ctl  <= opb_tx_dma_ctl_int;
116
    opb_tx_dma_addr <= opb_tx_dma_addr_int;
117
    opb_tx_dma_num  <= opb_tx_dma_num_int;
118
    opb_rx_dma_ctl  <= opb_rx_dma_ctl_int;
119
    opb_rx_dma_addr <= opb_rx_dma_addr_int;
120
    opb_rx_dma_num  <= opb_rx_dma_num_int;
121
  end generate u1;
122
 
123
 
124
-- unused outputs
125
  Sln_errAck  <= '0';
126
  Sln_retry   <= '0';
127
  Sln_toutSup <= '0';
128
 
129
  --* convert Sln_DBus_big_end  to little mode
130
  conv_big_Sln_DBus_proc: process(Sln_DBus_big_end)
131
  begin
132
    for i in 0 to 31 loop
133
      Sln_DBus(31-i) <= Sln_DBus_big_end(i);
134
    end loop;  -- i  
135
  end process conv_big_Sln_DBus_proc;
136
 
137
  --* convert OPB_ABus to big endian
138
  conv_big_OPB_ABus_proc: process(OPB_ABus)
139
  begin
140
    for i in 0 to 31 loop
141
      OPB_ABus_big_end(31-i) <= OPB_ABus(i);
142
    end loop;  -- i  
143
  end process conv_big_OPB_ABus_proc;
144
 
145
  --* convert OPB_DBus  to little mode
146
  conv_big_OPB_DBus_proc: process(OPB_DBus)
147
  begin
148
    for i in 0 to 31 loop
149
      OPB_DBus_big_end(31-i) <= OPB_DBus(i);
150
    end loop;  -- i  
151
  end process conv_big_OPB_DBus_proc;
152
 
153
  --* control OPB requests
154
  --*
155
  --* handles OPB-read and -write request
156
  opb_slave_proc: process (OPB_Rst, OPB_Clk)
157
  begin
158
    if (OPB_Rst = '1') then
159
      -- OPB
160
      Sln_xferAck      <= '0';
161
      Sln_DBus_big_end <= (others => '0');
162
      -- FIFO
163
      opb_s_rx_en      <= '0';
164
      opb_s_tx_en      <= '0';
165
      -- 
166
      state            <= idle;
167
      -- Register
168
      tx_thresh_int    <= (others => '0');
169
      rx_thresh_int    <= (others => '0');
170
      opb_ier_int      <= (others => '0');
171
      opb_dgie_int     <= '0';
172
      opb_ctl_reg_int  <= (others => '0');
173
 
174
      if C_DMA_EN then
175
        opb_tx_dma_ctl_int  <= (others => '0');
176
        opb_tx_dma_addr_int <= (others => '0');
177
        opb_tx_dma_num_int  <= (others => '0');
178
        opb_rx_dma_ctl_int  <= (others => '0');
179
        opb_rx_dma_addr_int <= (others => '0');
180
        opb_rx_dma_num_int  <= (others => '0');
181
      end if;
182
 
183
 
184
    elsif (OPB_Clk'event and OPB_Clk = '1') then
185
      case state is
186
        when idle =>
187
          if (OPB_select = '1' and
188
              ((OPB_ABus >= C_BASEADDR) and (OPB_ABus <= C_HIGHADDR))) then
189
            -- *device selected
190
            Sln_xferAck <= '1';
191
            state       <= done;
192
            if (OPB_RNW = '1') then
193
              -- read acess
194
              case OPB_ABus_big_end(7 downto 2) is
195
                when C_ADR_CTL =>
196
                  Sln_DBus_big_end(C_OPB_CTL_REG_WIDTH-1 downto 0) <= opb_ctl_reg_int;
197
 
198
                when C_ADR_RX_DATA =>
199
                  opb_s_rx_en                             <= '1';
200
                  Sln_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_s_rx_data;
201
 
202
                when C_ADR_STATUS =>
203
                  Sln_DBus_big_end(C_NUM_FLG-1 downto 0) <= opb_fifo_flg;
204
 
205
                when C_ADR_TX_THRESH =>
206
                  Sln_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0)     <= tx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0);
207
                  Sln_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16) <= tx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH);
208
 
209
                when C_ADR_RX_THRESH =>
210
                  Sln_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0)     <= rx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0);
211
                  Sln_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16) <= rx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH);
212
 
213
                when C_ADR_DGIE =>
214
                  Sln_DBus_big_end(0) <= opb_dgie_int;
215
                when C_ADR_IER =>
216
                  Sln_DBus_big_end(C_NUM_INT-1 downto 0) <= opb_ier_int;
217
 
218
                when C_ADR_ISR =>
219
                  Sln_DBus_big_end(C_NUM_INT-1 downto 0) <= opb_isr;
220
 
221
                when C_ADR_TX_DMA_CTL =>
222
                  if C_DMA_EN then
223
                    Sln_DBus_big_end(0 downto 0) <= opb_tx_dma_ctl_int;
224
                  end if;
225
 
226
                when C_ADR_TX_DMA_ADDR =>
227
                  if C_DMA_EN then
228
                    Sln_DBus_big_end(C_OPB_DWIDTH-1 downto 0) <= opb_tx_dma_addr_int;
229
                  end if;
230
 
231
                when C_ADR_TX_DMA_NUM =>
232
                  if C_DMA_EN then
233 10 dkoethe
                    Sln_DBus_big_end(C_WIDTH_DMA_NUM-1 downto 0) <= opb_tx_dma_num_int;
234 2 dkoethe
                  end if;
235
 
236
 
237
                when C_ADR_RX_DMA_CTL =>
238
                  if C_DMA_EN then
239
                    Sln_DBus_big_end(0 downto 0) <= opb_rx_dma_ctl_int;
240
                  end if;
241
 
242
                when C_ADR_RX_DMA_ADDR =>
243
                  if C_DMA_EN then
244
                    Sln_DBus_big_end(C_OPB_DWIDTH-1 downto 0) <= opb_rx_dma_addr_int;
245
                  end if;
246
 
247
                when C_ADR_RX_DMA_NUM =>
248
                  if C_DMA_EN then
249 10 dkoethe
                    Sln_DBus_big_end(C_WIDTH_DMA_NUM-1 downto 0) <= opb_rx_dma_num_int;
250 2 dkoethe
                  end if;
251
 
252
 
253
 
254
                when others =>
255
                  null;
256
              end case;
257
            else
258
              -- write acess
259
              case OPB_ABus_big_end(7 downto 2) is
260
                when C_ADR_CTL =>
261
                  opb_ctl_reg_int <= OPB_DBus_big_end(C_OPB_CTL_REG_WIDTH-1 downto 0);
262
 
263
                when C_ADR_TX_DATA =>
264
                  opb_s_tx_en   <= '1';
265
                  opb_s_tx_data <= OPB_DBus_big_end(C_SR_WIDTH-1 downto 0);
266
 
267
                when C_ADR_TX_THRESH =>
268
                  tx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0)                     <= OPB_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0);
269
                  tx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH) <= OPB_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16);
270
 
271
                when C_ADR_RX_THRESH =>
272
                  rx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0)                     <= OPB_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0);
273
                  rx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH) <= OPB_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16);
274
 
275
                when C_ADR_DGIE =>
276
                  opb_dgie_int <= OPB_DBus_big_end(0);
277
 
278
                when C_ADR_IER =>
279
                  opb_ier_int <= OPB_DBus_big_end(C_NUM_INT-1 downto 0);
280
 
281
                when C_ADR_ISR =>
282
                  opb_isr_clr <= OPB_DBus_big_end(C_NUM_INT-1 downto 0);
283
 
284
                when C_ADR_TX_DMA_CTL =>
285
                  if C_DMA_EN then
286
                    opb_tx_dma_ctl_int <= OPB_DBus_big_end(0 downto 0);
287
                  end if;
288
 
289
                when C_ADR_TX_DMA_ADDR =>
290
                  if C_DMA_EN then
291
                    opb_tx_dma_addr_int <= OPB_DBus_big_end(C_OPB_DWIDTH-1 downto 0);
292
                  end if;
293
 
294
                when C_ADR_TX_DMA_NUM =>
295
                  if C_DMA_EN then
296 10 dkoethe
                    opb_tx_dma_num_int <= OPB_DBus_big_end(C_WIDTH_DMA_NUM-1 downto 0);
297 2 dkoethe
                  end if;
298
 
299
                when C_ADR_RX_DMA_CTL =>
300
                  if C_DMA_EN then
301
                    opb_rx_dma_ctl_int <= OPB_DBus_big_end(0 downto 0);
302
                  end if;
303
 
304
                when C_ADR_RX_DMA_ADDR =>
305
                  if C_DMA_EN then
306
                    opb_rx_dma_addr_int <= OPB_DBus_big_end(C_OPB_DWIDTH-1 downto 0);
307
                  end if;
308
 
309
                when C_ADR_RX_DMA_NUM =>
310
                  if C_DMA_EN then
311 10 dkoethe
                    opb_rx_dma_num_int <= OPB_DBus_big_end(C_WIDTH_DMA_NUM-1 downto 0);
312 2 dkoethe
                  end if;
313
 
314
                when others =>
315
                  null;
316
              end case;
317
            end if;  -- OPB_RNW
318
          else
319
            -- not selected
320
            state <= idle;
321
          end if;
322
        when done =>
323
          opb_ctl_reg_int(3) <= '0';
324
          opb_isr_clr        <= (others => '0');
325
          opb_s_rx_en        <= '0';
326
          opb_s_tx_en        <= '0';
327
          Sln_xferAck        <= '0';
328
          Sln_DBus_big_end   <= (others => '0');
329
          state              <= idle;
330
 
331
        when others =>
332
          state <= idle;
333
      end case;
334
    end if;
335
  end process opb_slave_proc;
336
end behavior;

powered by: WebSVN 2.1.0

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