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

Subversion Repositories pif2wb

[/] [pif2wb/] [trunk/] [vhdl/] [pif2wb.vhd] - Blame information for rev 12

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

Line No. Rev Author Line
1 8 sergio.tot
------------------------------------------------------------------------------
2
-- Title       : PIF2WB
3
-- Project    : Bridge PIF to WISHBONE / WISHBONE to PIF
4
-------------------------------------------------------------------------------
5
-- File       : PIF2WB.vhd
6
-- Author     : Edoardo Paone, Paolo Motto, Sergio Tota, Mario Casu
7
--              {sergio.tota,mario.casu}@polito.it
8
--              http://vlsilab.polito.it
9
-- Company    : Politecnico of Torino, VLSI-Lab, Dipartimento di Elettronica,
10
--              Corso Duca degli Abruzzi 24, 10129 Torino, Italy
11
-- Last update: 2007/08/01
12
-- Platform   : 
13
-------------------------------------------------------------------------------
14
-- Description: This bridge interfaces the Tensilica (www.tensilica.com) proprietary
15
--              PIF bus protocol with the OpenCores WishBone. It currently supports
16
--              a master PIF and a slave WB. Single-cycle as well burst transfers
17
--              are possible.
18
-------------------------------------------------------------------------------
19
-- Revisions  :
20
-- Date        Version  Author          Description
21
-- 2007/04/18  1.0      Edoardo         Created
22
-- 2007/07/18  1.1      Paolo Motto     2nd Revision
23
-- 2007/08/01  1.2      Sergio Tota     3rd Revision
24
-------------------------------------------------------------------------------
25
 
26
-- I have replaced all undefined signals with the low value '0'
27
-- BTE_O, in case of burst transfer, must always be "00", because this bridge supports
28
-- only linear incremental burst mode
29
-- State :
30
-- IDLE
31
-- SR    : Single Read
32
-- BR    : Block Read
33
-- SW    : Single Write
34
-- BW    : Block Write
35
-- R_ACK : Response to ACK_I in Block Read
36
-- W_ACK : Response to ACK_I in Block Write
37
 
38
 
39
library ieee;
40
use ieee.std_logic_1164.all;
41
 
42
entity PIF2WB is
43
 
44
  generic (
45
    constant DATA_SIZE_PIF : integer := 32;  -- this value specifies the data bus PIF parallelism
46
    constant DATA_SIZE_WB  : integer := 32;  -- this value specifies the data bus Wishbone parallelism    
47
    constant ADRS_SIZE     : integer := 32;  -- this value specifies the address bus length
48
    constant CNTL_PIF      : integer := 8;   -- The PIF CNTL vector size
49
    constant MSB_PIF       : integer := 31;  -- The PIF most significant bit
50
    constant LSB_PIF       : integer := 0;   -- The PIF least significant bit 
51
    constant MSB_WB        : integer := 31;  -- The Wishbone most significant bit
52
    constant LSB_WB        : integer := 0;   -- The Wishbone least significant bit
53
    constant ADRS_BITS     : integer := 4;
54
    constant ADRS_RANGE    : integer := 8);
55
 
56
 
57
  port (
58
 
59
    CLK     : in std_logic;             -- the clock signal
60
    RST     : in std_logic;             -- the syncronus reset signal
61
 
62
 
63
    -- PIF signals
64
 
65
    PIReqVALID  : in  std_logic;
66
                                        -- Indicates that there is a valid request
67
    PIReqCNTL   : in  std_logic_vector(CNTL_PIF-1 downto 0);
68
                                        -- Encodes the data, size and last transfer information for requests
69
    PIReqADRS   : in  std_logic_vector(ADRS_SIZE-1 downto 0);
70
                                        -- Request address
71
    PIReqDATA   : in  std_logic_vector(DATA_SIZE_PIF-1 downto 0);
72
                                        -- Data used by requests that require data
73
    PIReqDataBE : in  std_logic_vector(DATA_SIZE_PIF/8-1 downto 0);
74
                                        -- Indicates valid bytes lanes of PIReqDATA
75
    POReqRDY    : out std_logic;
76
                                        -- Indicates that the slave is ready to accept requests
77
    PORespVALID : out std_logic;
78
                                        -- Indicates that there is a valid response
79
    PORespCNTL  : out std_logic_vector(CNTL_PIF-1 downto 0);
80
                                        -- Encodes the response type and any error
81
    PORespDATA  : out std_logic_vector(DATA_SIZE_PIF-1 downto 0);
82
                                        --Response data
83
    PIRespRDY   : in  std_logic;
84
                                        -- Indicates that the master is ready to accept responses
85
 
86
    -- WISHBONE signals
87
 
88
    ACK_I : in  std_logic;              -- The acknowledge input
89
    DAT_I : in  std_logic_vector(DATA_SIZE_WB-1 downto 0);
90
                                        -- The data input array
91
    ERR_I : in  std_logic;              -- Incates address or data error in transaction
92
    ADR_O : out std_logic_vector(ADRS_SIZE-1 downto 0);
93
                                        -- The address data output array
94
    DAT_O : out std_logic_vector(DATA_SIZE_WB-1 downto 0);
95
                                        -- The data output array
96
    CYC_O : out std_logic;              -- The cycle output
97
    SEL_O : out std_logic_vector(DATA_SIZE_WB/8-1 downto 0);
98
                                        -- The select output array
99
    STB_O : out std_logic;              -- The strobe output
100
    WE_O  : out std_logic;              -- The write enable output
101
    BTE_O : out std_logic_vector(1 downto 0);
102
                                        -- Indicates the burst length
103
    CTI_O : out std_logic_vector(2 downto 0) );
104
                                        -- Indicates the bus cycle type
105
end PIF2WB;
106
 
107
 
108
architecture PIF2WB_3process of PIF2WB is
109
 
110
  component Counter is
111
          generic (
112
                constant DATA_SIZE_WB :     integer := 32;
113
                constant ADRS_SIZE    :     integer := 32 );  -- Address bus length
114
          port (
115
                CLK        : in  std_logic;
116
                RST        : in  std_logic;
117
                LOAD_ADDR  : in  std_logic;
118
                GO_UP      : in  std_logic;
119
                ADR_INIT   : in  std_logic_vector(ADRS_SIZE-1 downto 0);
120
                ADR_CNTR   : out std_logic_vector(ADRS_SIZE-1 downto 0);
121
                N_TRANSFER : out integer range 0 to 15);
122
  end component;
123
 
124
  component AdrDec is
125
          generic (
126
                constant ADRS_SIZE    :     integer := 32;
127
                constant ADRS_BITS    :     integer := 4;
128
                constant ADRS_RANGE   :     integer := 8 );
129
          port (
130
                AdrIn                 : in  std_logic_vector(ADRS_SIZE-1 downto ADRS_SIZE-ADRS_BITS);
131
                AdrValid              : out std_logic);
132
  end component;
133
 
134
  component sel_reg is
135
                port (
136
                                clk   : in std_logic;
137
                                rst   : in std_logic;
138
                                En    : in std_logic;
139
                                sel_i : in  std_logic_vector (3 downto 0);
140
                                sel_o : out std_logic_vector (3 downto 0)
141
                                );
142
  end component;
143
 
144
  component tran_reg is
145
                port (
146
                                clk   : in std_logic;
147
                                rst   : in std_logic;
148
                                En    : in std_logic;
149
                                Num_i : in  integer range 0 to 15;
150
                                Num_o : out integer range 0 to 15
151
                                );
152
  end component;
153
 
154
  type state_type is (IDLE, SR, BR, SW, BW, R_ACK, W_ACK);
155
 
156
  signal state, next_state : state_type;
157
  signal N_TRANSFER          : integer range 0 to 15;
158
  signal TOT_TRANSFER_I      : integer range 0 to 15;
159
  signal TOT_TRANSFER_O      : integer range 0 to 15;
160
 
161
  -- Signals used by Counter
162
  signal LOAD_ADDR : std_logic;
163
  signal GO_UP     : std_logic;
164
 
165
  -- Signals used by Registers and Address Comparator
166
  signal AddressValid : std_logic;
167
  signal Enable       : std_logic;
168
 
169
 
170
begin
171
 
172
  Dec : AdrDec
173
        port map (
174
                AdrIn    => PIReqADRS (ADRS_SIZE-1 downto ADRS_SIZE-ADRS_BITS),
175
                AdrValid => AddressValid);
176
 
177
  reg0 : sel_reg
178
        port map (
179
                clk     => clk,
180
                rst     => rst,
181
                En      => Enable,
182
                sel_i   => PIReqDataBE,
183
                sel_o   => SEL_O);
184
 
185
  reg1 : tran_reg
186
        port map (
187
                clk     => clk,
188
                rst     => rst,
189
                En      => Enable,
190
                Num_i   => TOT_TRANSFER_I,
191
                Num_o   => TOT_TRANSFER_O);
192
 
193
  -- Counter used in burst mode
194
  Counter_Burst_Transfer : COUNTER
195
        port map( CLK, RST, LOAD_ADDR, GO_UP, PIReqADRS, ADR_O, N_TRANSFER);
196
 
197
  -- purpose: every clock cycle updates the signals
198
  -- type   : sequential
199
  -- inputs : CLK, RST
200
  State_Register : process (CLK, RST)
201
  begin  -- process State_Register
202
    if  RST = '1' then
203
      state   <= IDLE;
204
    elsif CLK'event and CLK = '1' then  -- rising clock edge
205
      state <= next_state;
206
    end if;
207
  end process State_Register;
208
 
209
  -- purpose: It determines which will be the next state
210
  -- type   : combinational
211
  -- inputs : state, PIReqVALID, PIRespRDY, ACK_I, PIReqCNTL, N_TRANSFER, TOT_TRANSFER_O
212
  -- outputs: next_state
213
  Next_State_Function : process (state, PIReqVALID, PIRespRDY, ACK_I, PIReqCNTL, N_TRANSFER, TOT_TRANSFER_O, AddressValid)
214
  begin  -- process Next_State_Function
215
    case state is
216
 
217
      when IDLE =>
218
        if(PIReqVALID = '1' and ACK_I = '0' and AddressValid = '1') then  -- ACK_I=0 means POReqRDY='1'
219
          if(PIReqCNTL(7) = '0' and PIReqCNTL(4) = '0') then
220
                next_state <= SR;       -- single read cycle                    
221
          elsif(PIReqCNTL(7) = '0' and PIReqCNTL(4) = '1') then
222
                next_state <= BR;       -- burst read cycle
223
          elsif(PIReqCNTL(7) = '1' and PIReqCNTL(4) = '0') then
224
                next_state <= SW;       -- single write cycle
225
          elsif(PIReqCNTL(7) = '1' and PIReqCNTL(4) = '1') then
226
                next_state <= BW;       -- burst write cycle
227
          else
228
                next_state <=  IDLE;
229
          end if;
230
        else
231
                next_state <= IDLE;
232
        end if;
233
 
234
      when SR =>
235
        if(ACK_I = '1' and PIRespRDY = '1') then
236
            next_state <= IDLE;
237
        else
238
            next_state <= SR;
239
        end if;
240
 
241
      when BR =>
242
        if (ACK_I = '1' and PIRespRDY = '1') then
243
                next_state <= R_ACK;
244
        else
245
                next_state <= BR;
246
     end if;
247
 
248
      when SW =>
249
        if(ACK_I = '1' and PIRespRDY = '1') then
250
            next_state <= IDLE;
251
        else
252
            next_state <= SW;
253
        end if;
254
 
255
      when BW =>
256
        if (ACK_I = '1' and PIRespRDY = '1') then
257
                next_state <= W_ACK;
258
        else
259
                next_state <= BW;
260
     end if;
261
 
262
      when R_ACK =>
263
        if (ACK_I = '0') then
264
                if N_TRANSFER = TOT_TRANSFER_O then
265
                        next_state <= IDLE;
266
                else
267
                        next_state <= BR;
268
                end if;
269
        else
270
                next_state <= R_ACK;
271
        end if;
272
 
273
      when W_ACK =>
274
        if (ACK_I = '0') then
275
                if (N_TRANSFER = TOT_TRANSFER_O  and  PIReqCNTL(0) = '1') then
276
                        next_state <= IDLE;
277
                else
278
                        next_state <= BW;
279
                end if;
280
        else
281
                next_state <= W_ACK;
282
        end if;
283
 
284
      when others =>
285
        next_state <= IDLE;
286
 
287
     end case;
288
  end process Next_State_Function;
289
 
290
  -- purpose: It assigns the correct values to output signals
291
  -- type   : combinational
292
  -- inputs : state, N_TRANSFER_O, PIReqCNTL, PIReqDATA, DAT_I, GO_UP, ERR_I
293
  -- outputs: 
294
  Output_Function : process (state, N_TRANSFER, TOT_TRANSFER_O, PIReqCNTL, PIReqDATA, DAT_I, ERR_I, ACK_I, DAT_I)
295
  begin  -- process Output_Function
296
 
297
    LOAD_ADDR                                   <= '0';
298
    Enable                                      <= '0';
299
    GO_UP                                       <= '0';
300
 
301
    BTE_O                                       <= "00";
302
    DAT_O                                       <= (others => 'Z');
303
    CYC_O                                       <= '0';
304
    STB_O                                       <= '0';
305
    WE_O                                        <= '0';
306
    CTI_O                                       <= (others => '0');
307
 
308
    PORespVALID                                 <= ACK_I;
309
    POReqRDY                                    <= '1';
310
    PORespDATA                                  <= (others => 'Z');
311
    PORespCNTL (7 downto 3)                     <= (others => '0');
312
    PORespCNTL (0)                               <= '0';
313
 
314
    if ERR_I = '1' then
315
      PORespCNTL(2 downto 1)                    <= "11";
316
    else
317
      PORespCNTL(2 downto 1)                    <= "00";
318
    end if;
319
 
320
    case state is
321
      when IDLE =>
322
        Enable                                  <= '1';
323
        LOAD_ADDR                               <= '1';
324
        CYC_O                                   <= '0';
325
        STB_O                                   <= '0';
326
        DAT_O                                   <= (others => 'Z');
327
        WE_O                                    <= '0';
328
        CTI_O                                   <= (others => '0');
329
        PORespCNTL(7 downto 3)                  <= "00000";
330
        PORespCNTL(0)                            <= '0';
331
        PORespDATA                              <= (others => 'Z');
332
 
333
        case PIReqCNTL(2 downto 1) is
334
                when "00"   =>
335
                        TOT_TRANSFER_I          <= 1;
336
                when "01"   =>
337
                        TOT_TRANSFER_I          <= 3;
338
                when "10"   =>
339
                        TOT_TRANSFER_I          <= 7;
340
                when "11"   =>
341
                        TOT_TRANSFER_I          <= 15;
342
                when others =>
343
                        TOT_TRANSFER_I          <= 0;
344
        end case;
345
 
346
     when SR =>
347
        CYC_O                                   <= '1';
348
        STB_O                                   <= '1';
349
        CTI_O                                   <= (others => '0');               -- single transfer
350
        WE_O                                    <= '0';
351
        DAT_O                                   <= (others => 'Z');
352
        PORespDATA(MSB_PIF downto LSB_PIF)      <= DAT_I(MSB_WB downto LSB_WB);
353
        PORespCNTL(7 downto 3)                  <= "00000";
354
        PORespCNTL(0)                            <= '1';
355
 
356
     when BR =>
357
        CYC_O                                   <= '1';
358
        STB_O                                   <= '1';
359
        WE_O                                    <= '0';
360
        CTI_O                                   <= "010";
361
        DAT_O                                   <= (others => 'Z');
362
        PORespDATA(MSB_PIF downto LSB_PIF)      <= DAT_I(MSB_WB downto LSB_WB);
363
        PORespCNTL(7 downto 3)                  <= "00000";
364
        if (N_TRANSFER = TOT_TRANSFER_O) then
365
                PORespCNTL(0)            <= '1';
366
                CTI_O                           <= "111";
367
        else
368
                PORespCNTL(0)                    <= '0';
369
                CTI_O                           <= "010";
370
        end if;
371
 
372
     when SW =>
373
        CYC_O                                   <= '1';
374
        STB_O                                   <= '1';
375
        CTI_O                                   <= (others => '0');              -- single transfer
376
        WE_O                                    <= '1';
377
        DAT_O(MSB_WB downto LSB_WB)             <= PIReqDATA(MSB_PIF downto LSB_PIF);
378
        PORespDATA                              <= (others => 'Z');
379
        PORespCNTL(7 downto 3)                  <= "00000";
380
        PORespCNTL(0)                            <= '1';
381
 
382
     when BW =>
383
        CYC_O                                   <= '1';
384
        STB_O                                   <= '1';
385
        WE_O                                    <= '1';
386
        CTI_O                                   <= "010";
387
        DAT_O(MSB_WB downto LSB_WB)             <= PIReqDATA(MSB_PIF downto LSB_PIF);
388
        PORespDATA                              <= (others => 'Z');
389
        PORespCNTL(7 downto 3)                  <= "00000";
390
        if (N_TRANSFER = TOT_TRANSFER_O) then
391
                PORespCNTL(0)                    <= '1';
392
                CTI_O                           <= "111";
393
        else
394
                PORespCNTL(0)                    <= '0';
395
                CTI_O                           <= "010";
396
        end if;
397
 
398
     when R_ACK =>
399
        GO_UP                                   <= '1';
400
        STB_O                                   <= '0';
401
        WE_O                                    <= '0';
402
        CTI_O                                   <= "010";
403
        DAT_O                                   <= (others => 'Z');
404
        PORespDATA(MSB_PIF downto LSB_PIF)      <= DAT_I(MSB_WB downto LSB_WB);
405
        PORespCNTL(7 downto 3)                  <= "00000";
406
        PORespCNTL(0)                            <= '0';
407
        if (N_TRANSFER = TOT_TRANSFER_O) then
408
                PORespCNTL(0)                    <= '1';
409
                CTI_O                           <= "111";
410
                CYC_O                           <= '0';
411
        else
412
                PORespCNTL(0)                    <= '0';
413
                CTI_O                           <= "010";
414
                CYC_O                           <= '1';
415
        end if;
416
 
417
     when W_ACK =>
418
        GO_UP                                   <= '1';
419
        STB_O                                   <= '0';
420
        CTI_O                                   <= "010";
421
        DAT_O(MSB_WB downto LSB_WB)             <= PIReqDATA(MSB_PIF downto LSB_PIF);
422
        PORespDATA                              <= (others => 'Z');
423
        PORespCNTL(7 downto 3)                  <= "00000";
424
        if (N_TRANSFER = TOT_TRANSFER_O) then
425
                PORespCNTL(0)                    <= '1';
426
                CTI_O                           <= "111";
427
                CYC_O                           <= '0';
428
                WE_O                            <= '0';
429
        else
430
                PORespCNTL(0)                    <= '0';
431
                CTI_O                           <= "010";
432
                CYC_O                           <= '1';
433
                WE_O                            <= '1';
434
        end if;
435
 
436
     end case;
437
  end process Output_Function;
438
 
439
end PIF2WB_3process;

powered by: WebSVN 2.1.0

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