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

Subversion Repositories plb2wbbridge

[/] [plb2wbbridge/] [trunk/] [systems/] [EDK_Libs/] [WishboneIPLib/] [pcores/] [plb2wb_bridge_v1_00_a/] [hdl/] [vhdl/] [plb2wb_stu.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 feddischso
----------------------------------------------------------------------
2
----                                                              ----
3
----  PLB2WB-Bridge                                               ----
4
----                                                              ----
5
----  This file is part of the PLB-to-WB-Bridge project           ----
6
----  http://opencores.org/project,plb2wbbridge                   ----
7
----                                                              ----
8
----  Description                                                 ----
9
----  Implementation of a PLB-to-WB-Bridge according to           ----
10
----  PLB-to-WB Bridge specification document.                    ----
11
----                                                              ----
12
----  To Do:                                                      ----
13
----   Nothing                                                    ----
14
----                                                              ----
15
----  Author(s):                                                  ----
16
----      - Christian Haettich                                    ----
17
----        feddischson@opencores.org                             ----
18
----                                                              ----
19
----------------------------------------------------------------------
20
----                                                              ----
21
---- Copyright (C) 2010 Authors                                   ----
22
----                                                              ----
23
---- This source file may be used and distributed without         ----
24
---- restriction provided that this copyright statement is not    ----
25
---- removed from the file and that any derivative work contains  ----
26
---- the original copyright notice and the associated disclaimer. ----
27
----                                                              ----
28
---- This source file is free software; you can redistribute it   ----
29
---- and/or modify it under the terms of the GNU Lesser General   ----
30
---- Public License as published by the Free Software Foundation; ----
31
---- either version 2.1 of the License, or (at your option) any   ----
32
---- later version.                                               ----
33
----                                                              ----
34
---- This source is distributed in the hope that it will be       ----
35
---- useful, but WITHOUT ANY WARRANTY; without even the implied   ----
36
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ----
37
---- PURPOSE.  See the GNU Lesser General Public License for more ----
38
---- details.                                                     ----
39
----                                                              ----
40
---- You should have received a copy of the GNU Lesser General    ----
41
---- Public License along with this source; if not, download it   ----
42
---- from http://www.opencores.org/lgpl.shtml                     ----
43
----                                                              ----
44
----------------------------------------------------------------------
45
 
46
 
47
library ieee;
48
use ieee.std_logic_1164.all;
49
use ieee.numeric_std.all;
50
 
51
library plb2wb_bridge_v1_00_a;
52
use plb2wb_bridge_v1_00_a.plb2wb_pkg.all;
53
 
54
entity plb2wb_stu is
55
   generic(
56
      SYNCHRONY                     : boolean            := true;
57
      WB_DWIDTH                     : integer            := 32;
58
      WB_AWIDTH                     : integer            := 32;
59
      C_SPLB_AWIDTH                 : integer            := 32;
60
      C_SPLB_DWIDTH                 : integer            := 128;
61
      C_SPLB_MID_WIDTH              : integer            := 3;
62
      C_SPLB_NUM_MASTERS            : integer            := 1;
63
      C_SPLB_SIZE_WIDTH             : integer            := 4;
64
      C_SPLB_BE_WIDTH               : integer            := 4;
65
      C_SPLB_NATIVE_BE_WIDTH        : integer            := 4;
66
      C_SPLB_NATIVE_DWIDTH          : integer            := 32
67
 
68
 
69
   );
70
   port(
71
 
72
      wb_clk_i                      : in  std_logic;
73
      SPLB_Clk                      : in  std_logic;
74
      SPLB_Rst                      : in  std_logic;
75
 
76
      PLB_size                      : in  std_logic_vector( 0 to C_SPLB_SIZE_WIDTH  -1 );
77
      PLB_wrDBus                    : in  std_logic_vector( 0 to C_SPLB_DWIDTH      -1 );
78
      PLB_masterID                  : in  std_logic_vector( 0 to C_SPLB_MID_WIDTH   -1 );
79
      PLB_BE                        : in  std_logic_vector( 0 to C_SPLB_BE_WIDTH    -1 );
80
 
81
      PLB_ABus                      : in  std_logic_vector( 0 to C_SPLB_AWIDTH      -1 );
82
 
83
      --TODO  remove this four signals,  they are not used!
84
      AMU_masterID                  : in  std_logic_vector( 0 to C_SPLB_MID_WIDTH   -1 );
85
      AMU_buf_masterID              : in  std_logic_vector( 0 to C_SPLB_MID_WIDTH   -1 );
86
      AMU_pipe_adr                  : in  std_logic_vector( 0 to C_SPLB_AWIDTH      -1 );
87
      AMU_buf_adr_wo                : in  std_logic_vector( WB_AWIDTH-1 downto 0       );    -- without offset
88
 
89
      ----
90
      --  When TCU_stat2plb_en is '1', TCU_wb_status_info is written to
91
      --  the status pipe, which transfers this info to the plb-side
92
      TCU_wb_status_info            : in  std_logic_vector( STATUS2PLB_INFO_SIZE-1 downto 0 ) ;
93
      TCU_stat2plb_en               : in  std_logic;
94
 
95
 
96
      ----
97
      -- This two signals says if we either do a write transfer, which is 
98
      -- addressed directly with PLB_ABus or if we do a write transfer
99
      -- which is addressed with a secondary address AMU_pipe_adr 
100
      -- (which comes from address-pipe -> see amu)
101
      --
102
      TCU_stuWritePA                : in  std_logic;     -- write, addressed with primary address
103
      TCU_stuWriteSA                : in  std_logic;     -- write, addressed with second. address
104
 
105
      ----
106
      -- This two signals says, if we must latch the primary address 
107
      -- from PLB_ABus or the secondary address from AMU_pipe_adr
108
      -- With latching the address, the read-bus STU_rdDBus has 
109
      -- assigned the desired data
110
      --
111
      TCU_stuLatchPA                : in  std_logic;
112
      TCU_stuLatchSA                : in  std_logic;
113
 
114
 
115
      -- This signal enalbes the read-bus STU_rdDBus.
116
      -- If this signal is '0', STU_rdDBus is complete '0'
117
      --
118
      TCU_enStuRdDBus               : in  std_logic;
119
      TCU_wb_irq_info               : in  std_logic_vector( IRQ_INFO_SIZE-1 downto 0 );
120
      Sl_rdWdAddr                   : in  std_logic_vector( 0 to 3 );
121
      Sl_MIRQ                       : out std_logic_vector( 0 to C_SPLB_NUM_MASTERS-1 );
122
 
123
      WBF_wBus                      : in  std_logic_vector( 0 to C_SPLB_NATIVE_DWIDTH  -1 );
124
 
125
      PLB2WB_IRQ                    : out  std_logic;
126
 
127
 
128
      ----
129
      -- This two signals are used on the wb-side to decide if a transfer must be
130
      -- continued or aborted
131
      --
132
      STU_abort                     : out std_logic;
133
      STU_continue                  : out std_logic;
134
 
135
 
136
      STU_full                      : out std_logic;
137
      STU_rdDBus                    : out std_logic_vector( 0 to C_SPLB_DWIDTH-1 );
138
 
139
      -- The reset-signal, which does a software reset
140
      STU_softReset                 : out std_logic
141
   );
142
 
143
end entity plb2wb_stu;
144
 
145
architecture IMP of plb2wb_stu is
146
 
147
   type  reg_type is array( integer range<> ) of std_logic_vector( 0 to C_SPLB_NATIVE_DWIDTH-1 );
148
 
149
   signal status_regs      : reg_type( 0 to 3);
150
   signal status_reg_out   : std_logic_vector( 0 to C_SPLB_NATIVE_DWIDTH-1 );
151
 
152
 
153
 
154
 
155
   -------
156
   --
157
   --    This two bit are used for read transfers from our status registers.
158
   --    We DON'T need this for write transfers, because we write in 
159
   --    one clock cycle ( we don't need to latch the address ).
160
   --
161
   --    This address-register is loaded with TCU_stuLatchPA or TCU_stuLatchSA
162
   --
163
   signal address_reg      : std_logic_vector( 0 to 1 );
164
 
165
   signal stat2plb_rd_en   : std_logic;
166
   signal stat2plb_empty   : std_logic;
167
   signal stat2plb_dout    : std_logic_vector( IRQ_INFO_SIZE + C_SPLB_NATIVE_DWIDTH + C_SPLB_AWIDTH + C_SPLB_MID_WIDTH + STATUS2PLB_INFO_SIZE -1 downto 0 );
168
   signal stat2plb_din     : std_logic_vector( IRQ_INFO_SIZE + C_SPLB_NATIVE_DWIDTH + C_SPLB_AWIDTH + C_SPLB_MID_WIDTH + STATUS2PLB_INFO_SIZE -1 downto 0 );
169
 
170
   signal stat2wb_rd_en   : std_logic;
171
   signal stat2wb_wr_en   : std_logic;
172
   signal stat2wb_empty   : std_logic;
173
   signal stat2wb_full    : std_logic;
174
   signal stat2wb_dout    : std_logic_vector( 1-1 downto 0 );
175
   signal stat2wb_din     : std_logic_vector( 1-1 downto 0 );
176
 
177
   signal addr_with_offset : std_logic_vector( 0 to 31 );
178
 
179
   signal STU_softReset_t  : std_logic;
180
   signal soft_reset_count : std_logic_vector( 0 to 1 );    -- counter, implemented with gray-code
181
 
182
 
183
 
184
   signal plb2wb_rst       : std_logic;
185
   signal status_loaded    : std_logic;
186
 
187
   signal wb_status_info : std_logic_vector( STATUS2PLB_INFO_SIZE-1 downto 0  );
188
   signal wb_master_id   : std_logic_vector( 0 to C_SPLB_MID_WIDTH -1         );
189
 
190
 
191
   signal Sl_MIRQ_t   : std_logic_vector( C_SPLB_NUM_MASTERS -1    downto 0  );
192
 
193
 
194
begin
195
 
196
   Sl_MIRQ <= ( others => '0' );
197
 
198
 
199
   plb2wb_rst     <= SPLB_Rst or STU_softReset_t;
200
   STU_softReset  <= STU_softReset_t;
201
 
202
 
203
   status_reg_out <= status_regs(0) when std_logic_vector( unsigned (  address_reg ) + unsigned( Sl_rdWdAddr( 2 to 3 ) ) )= "00"  else
204
                     status_regs(1) when std_logic_vector( unsigned (  address_reg ) + unsigned( Sl_rdWdAddr( 2 to 3 ) ) )= "01"  else
205
                     status_regs(2) when std_logic_vector( unsigned (  address_reg ) + unsigned( Sl_rdWdAddr( 2 to 3 ) ) )= "10"  else
206
                     status_regs(3);
207
 
208
 
209
   gen_128 : if C_SPLB_DWIDTH = 128 generate
210
      STU_rdDBus  <= status_reg_out & status_reg_out & status_reg_out & status_reg_out when TCU_enStuRdDBus = '1' else
211
                                                ( others => '0' );
212
   end generate;
213
 
214
   gen_64 : if C_SPLB_DWIDTH = 64 generate
215
      STU_rdDBus  <= status_reg_out & status_reg_out                       when TCU_enStuRdDBus = '1' else
216
                                                ( others => '0' );
217
   end generate;
218
 
219
   gen_32 : if C_SPLB_DWIDTH = 32 generate
220
      STU_rdDBus  <= status_reg_out                                  when TCU_enStuRdDBus = '1' else
221
                                                ( others => '0' );
222
   end generate;
223
 
224
 
225
 
226
 
227
   stat2plb : entity plb2wb_bridge_v1_00_a.fifo_stat2plb
228
      generic map(
229
         SYNCHRONY         => SYNCHRONY,
230
         WB_DWIDTH         => WB_DWIDTH,
231
         WB_AWIDTH         => WB_AWIDTH,
232
         C_SPLB_MID_WIDTH  => C_SPLB_MID_WIDTH
233
         )
234
      port map(
235
         rd_en    => stat2plb_rd_en,
236
         wr_en    => TCU_stat2plb_en,
237
         full     => STU_full,
238
         empty    => stat2plb_empty,
239
         wr_clk   => wb_clk_i,
240
         rst      => plb2wb_rst,
241
         rd_clk   => SPLB_Clk,
242
         dout     => stat2plb_dout,
243
         din      => stat2plb_din
244
      );
245
 
246
 
247
 
248
   stat2wb : entity plb2wb_bridge_v1_00_a.fifo_stat2wb
249
      generic map(
250
         SYNCHRONY   => SYNCHRONY
251
      )
252
      port map(
253
         rd_en    => stat2wb_rd_en,
254
         wr_en    => stat2wb_wr_en,
255
         full     => stat2wb_full,
256
         empty    => stat2wb_empty,
257
         wr_clk   => SPLB_Clk,
258
         rst      => plb2wb_rst,
259
         rd_clk   => wb_clk_i,
260
         dout     => stat2wb_dout,
261
         din      => stat2wb_din
262
      );
263
 
264
   stat2plb_din   <= TCU_wb_irq_info &  AMU_buf_adr_wo & WBF_wBus & TCU_wb_status_info & AMU_buf_masterID;
265
 
266
   wb_status_info <=  stat2plb_dout( STATUS2PLB_INFO_SIZE + C_SPLB_MID_WIDTH -1 downto C_SPLB_MID_WIDTH );
267
 
268
   wb_master_id   <= stat2plb_dout( C_SPLB_MID_WIDTH-1 downto 0 );
269
 
270
 
271
 
272
 
273
   status_reg_p : process( SPLB_Clk, SPLB_Rst, stat2plb_rd_en, Sl_MIRQ_t, status_regs, plb2wb_rst  )
274
   begin
275
 
276
      if plb2wb_rst = '1' then
277
         status_regs    <= ( others => ( others => '0' ) );
278
         address_reg    <= ( others => '0'               );
279
         status_loaded  <= '0';
280
      elsif SPLB_Clk'event and SPLB_Clk = '1' then
281
 
282
 
283
         if TCU_stuLatchPA = '1' then
284
            address_reg <= PLB_ABus( 28 to 29 );
285
         elsif TCU_stuLatchSA = '1' then
286
            address_reg <= AMU_pipe_adr( 28 to 29 );
287
         end if;
288
 
289
 
290
         ----
291
         -- Write acceess to the first regser     address = "00"
292
         --    -> clears the irq 
293
         if ( ( TCU_stuWritePA = '1' and  PLB_ABus( 28 to 29 ) = "00"      ) or
294
              ( TCU_stuWriteSA = '1' and  AMU_pipe_adr( 28 to 29 ) = "00"  ) )
295
         then
296
            status_loaded    <= '0';
297
            status_regs( 0 ) <= ( others => '0' );
298
         end if;
299
 
300
 
301
         -----
302
         --
303
         -- if there is something in the pipe, we save it 
304
         -- (we don't save the bit about the finished transfer!)
305
         --
306
         -- NOTE: This has a higher priority than writing from plb-bus!!
307
         --
308
         --
309
         if (  stat2plb_rd_en = '1' ) then
310
            status_regs(0)(0 to STATUS2PLB_INFO_SIZE-1 ) <= status_regs(0)(0 to STATUS2PLB_INFO_SIZE-1 ) or wb_status_info( STATUS2PLB_INFO_SIZE-1 downto 0 );
311
            status_loaded <= '1';
312
 
313
 
314
            status_regs(3)          <= stat2plb_dout( IRQ_INFO_SIZE        +
315
                                                      C_SPLB_AWIDTH        +
316
                                                      C_SPLB_NATIVE_DWIDTH +
317
                                                      STATUS2PLB_INFO_SIZE +
318
                                                      C_SPLB_MID_WIDTH     -1
319
                                                               downto
320
                                                      C_SPLB_AWIDTH        +
321
                                                      C_SPLB_NATIVE_DWIDTH +
322
                                                      STATUS2PLB_INFO_SIZE +
323
                                                      C_SPLB_MID_WIDTH    );
324
 
325
 
326
            status_regs(2)          <= stat2plb_dout( C_SPLB_AWIDTH        + C_SPLB_NATIVE_DWIDTH +
327
                                                      STATUS2PLB_INFO_SIZE + C_SPLB_MID_WIDTH -1
328
                                                               downto
329
                                                      C_SPLB_NATIVE_DWIDTH + STATUS2PLB_INFO_SIZE +
330
                                                      C_SPLB_MID_WIDTH    );
331
 
332
 
333
 
334
            status_regs(1)          <= stat2plb_dout( C_SPLB_NATIVE_DWIDTH + STATUS2PLB_INFO_SIZE +
335
                                                      C_SPLB_MID_WIDTH     -1
336
                                                               downto
337
                                                      STATUS2PLB_INFO_SIZE + C_SPLB_MID_WIDTH );
338
 
339
            status_regs(0)( C_SPLB_NATIVE_DWIDTH - C_SPLB_MID_WIDTH    to C_SPLB_NATIVE_DWIDTH -1 ) <= wb_master_id;
340
 
341
 
342
 
343
         end if;
344
 
345
      end if;
346
 
347
 
348
 
349
 
350
   end process;
351
 
352
 
353
   stat2plb_rd_en <= '1' when ( stat2plb_empty = '0' and status_loaded = '0' and TCU_stuWritePA = '0' and TCU_stuWriteSA = '0' ) else
354
                     '0';
355
 
356
 
357
   --------
358
   --
359
   --   Interrupt generation
360
   --
361
   Sl_MIRQ_t   <= ( others => '0' );   -- is not supported by xilinx!
362
   PLB2WB_IRQ  <= status_regs(0)( 2 ) or status_regs(0)( 1 ) or status_regs(0)( 0 );
363
 
364
 
365
 
366
 
367
 
368
 
369
   ----------
370
   -- 
371
   --    Handling of write access to the status registers 
372
   --       (except clearing the irq)
373
   --       - soft reset (for 4 clock cycles)   address = "11"
374
   --       - continue failed write transfer    address = "01"
375
   --       - abort failed write transfer       address = "10"
376
   --
377
   status_state_p : process( SPLB_Clk, SPLB_Rst, TCU_stuWritePA, PLB_ABus, TCU_stuWriteSA, AMU_pipe_adr )
378
   begin
379
 
380
      if SPLB_Rst = '1' then
381
         soft_reset_count  <= ( others => '0' );
382
      elsif SPLB_Clk'event and SPLB_Clk = '1' then
383
 
384
         -- if the status-address range is selected:
385
         -- do a soft reset, depending on the address
386
         if (  ( soft_reset_count = "00" and TCU_stuWritePA = '1' and PLB_ABus( 28 to 29 ) = "11"      ) or
387
               ( soft_reset_count = "00" and TCU_stuWriteSA = '1' and AMU_pipe_adr( 28 to 29 ) = "11"  ) ) then
388
            soft_reset_count <= "10";
389
         end if;
390
 
391
         if soft_reset_count = "10" then
392
            soft_reset_count <= "11";
393
         elsif soft_reset_count = "11" then
394
            soft_reset_count <= "01";
395
         elsif soft_reset_count = "01" then
396
            soft_reset_count <= "00";
397
         end if;
398
 
399
 
400
 
401
      end if;
402
 
403
 
404
      -- if the status-address range is selected:
405
      -- add a continue or abort information to the fifo, depending on the address
406
      --
407
      stat2wb_din    <= "0";
408
      stat2wb_wr_en  <= '0';
409
      if (  ( TCU_stuWritePA = '1' and PLB_ABus( 28 to 29 ) = "01"      ) or
410
            ( TCU_stuWriteSA = '1' and AMU_pipe_adr( 28 to 29 ) = "01"  ) ) then
411
         stat2wb_din    <= STATUS_CONTINUE;
412
         stat2wb_wr_en  <= '1';
413
      elsif (  ( TCU_stuWritePA = '1' and PLB_ABus( 28 to 29 ) = "10"      ) or
414
            ( TCU_stuWriteSA = '1' and AMU_pipe_adr( 28 to 29 ) = "10"  ) ) then
415
         stat2wb_din    <= STATUS_ABORT;
416
         stat2wb_wr_en  <= '1';
417
      end if;
418
 
419
   end process;
420
 
421
 
422
   stat2wb_rd_en <= not stat2wb_empty;
423
   STU_continue <= '1' when stat2wb_empty = '0' and stat2wb_dout = STATUS_CONTINUE else
424
                   '0';
425
   STU_abort    <= '1' when stat2wb_empty = '0' and stat2wb_dout = STATUS_ABORT    else
426
                   '0';
427
 
428
 
429
 
430
   STU_softReset_t   <= '0' when soft_reset_count = "00" else
431
                        '1';
432
 
433
 
434
 
435
end architecture IMP;

powered by: WebSVN 2.1.0

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