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 38

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

powered by: WebSVN 2.1.0

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