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

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_asip_pstllog_2w_p6.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 madsilicon
-----------------------------------------------------------------
2
--                                                             --
3
-----------------------------------------------------------------
4
--                                                             --
5
-- Copyright (C) 2013 Stefano Tonello                          --
6
--                                                             --
7
-- This source file may be used and distributed without        --
8
-- restriction provided that this copyright statement is not   --
9
-- removed from the file and that any derivative work contains --
10
-- the original copyright notice and the associated disclaimer.--
11
--                                                             --
12
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
13
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
14
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
15
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
16
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
17
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
18
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
19
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
20
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
21
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
22
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
23
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
24
-- POSSIBILITY OF SUCH DAMAGE.                                 --
25
--                                                             --
26
-----------------------------------------------------------------
27
 
28
---------------------------------------------------------
29
-- G.729A ASIP Pipeline stall logic 
30
---------------------------------------------------------
31
 
32
library IEEE;
33
use IEEE.std_logic_1164.all;
34
use IEEE.numeric_std.all;
35
 
36
library WORK;
37
use WORK.G729A_ASIP_PKG.all;
38
--use WORK.G729A_ASIP_BASIC_PKG.all;
39
--use WORK.G729A_ASIP_ARITH_PKG.all;
40
use work.G729A_ASIP_IDEC_2W_PKG.all;
41
 
42
entity G729A_ASIP_PSTLLOG_2W_P6 is
43
  generic(
44
    SIMULATION_ONLY : std_logic := '0'
45
  );
46
  port(
47
    CLK_i : in std_logic;
48
    ID_INSTR_i : in DEC_INSTR_T;
49
    ID_V_i : in std_logic;
50
    IX1_INSTR0_i : in DEC_INSTR_T;
51
    IX1_INSTR1_i : in DEC_INSTR_T;
52
    IX1_V_i : in std_logic_vector(2-1 downto 0);
53
    IX1_FWDE_i : in std_logic_vector(2-1 downto 0);
54
    IX2_INSTR0_i : in DEC_INSTR_T;
55
    IX2_INSTR1_i : in DEC_INSTR_T;
56
    IX2_V_i : in std_logic_vector(2-1 downto 0);
57
    IX2_FWDE_i : in std_logic_vector(2-1 downto 0);
58
    IX3_INSTR0_i : in DEC_INSTR_T;
59
    IX3_INSTR1_i : in DEC_INSTR_T;
60
    IX3_V_i : in std_logic_vector(2-1 downto 0);
61
    IX3_FWDE_i : in std_logic_vector(2-1 downto 0);
62
 
63
    PSTALL_o : out std_logic
64
  );
65
end G729A_ASIP_PSTLLOG_2W_P6;
66
 
67
architecture ARC of G729A_ASIP_PSTLLOG_2W_P6 is
68
 
69
  function qmark(C : std_logic; A,B : std_logic) return std_logic is
70
  begin
71
    if(C = '1') then
72
      return(A);
73
    else
74
      return(B);
75
    end if;
76
  end function;
77
 
78
  function qmark(C : boolean; A,B : std_logic) return std_logic is
79
  begin
80
    if(C) then
81
      return(A);
82
    else
83
      return(B);
84
    end if;
85
  end function;
86
 
87
  function plus1(A : RID_T) return RID_T is
88
    variable UA1,UA2 : unsigned(4-1 downto 0);
89
  begin
90
    UA1 := to_unsigned(A,4);
91
    UA2 := UA1(4-1 downto 1) & '1';
92
    return(to_integer(UA2));
93
  end function;
94
 
95
  function rmtch_a(IDI,IXI : DEC_INSTR_T; RAP1,RDP1 : RID_T) return std_logic is
96
  begin
97
    if(
98
      (IDI.RA = IXI.RD) or
99
      (IDI.LA = '1' and (RAP1 = IXI.RD)) or
100
      (IXI.LD = '1' and (IDI.RA = RDP1))
101
    ) then
102
      return('1');
103
    else
104
      return('0');
105
    end if;
106
  end function;
107
 
108
  function rmtch_b(IDI,IXI : DEC_INSTR_T; RBP1,RDP1 : RID_T)
109
    return std_logic is
110
  begin
111
    if(
112
      (IDI.RB = IXI.RD) or
113
      (IDI.LB = '1' and (RBP1 = IXI.RD)) or
114
      (IXI.LD = '1' and (IDI.RB = RDP1))
115
    ) then
116
      return('1');
117
    else
118
      return('0');
119
    end if;
120
  end function;
121
 
122
  function dep_a(RMTCH,IDV,IXV : std_logic;IDI,IXI : DEC_INSTR_T)
123
    return std_logic is
124
  begin
125
    if(
126
      (RMTCH = '1') -- and (IDI.RRA = '1') and (IXI.WRD = '1')
127
    ) then
128
      return(IDV and IXV and IDI.RRA and IXI.WRD);
129
    else
130
      return('0');
131
    end if;
132
  end function;
133
 
134
  function dep_b(RMTCH,IDV,IXV : std_logic;IDI,IXI : DEC_INSTR_T)
135
    return std_logic is
136
  begin
137
    if(
138
      (RMTCH = '1') -- and (IDI.RRB = '1') and (IXI.WRD = '1')
139
    ) then
140
      return(IDV and IXV and IDI.RRB and IXI.WRD);
141
    else
142
      return('0');
143
    end if;
144
  end function;
145
 
146
  function stall_a(DEP,FWDE,IX_2C : std_logic;IDI,IXI : DEC_INSTR_T)
147
    return std_logic is
148
  begin
149
    if(
150
      (DEP = '1') -- and ((FWDE = '0') or (IX_2C = '1') or (IDI.LA /= IXI.LD))
151
    ) then
152
      return(qmark((FWDE = '0') or (IX_2C = '1') or (IDI.LA /= IXI.LD),'1','0'));
153
    else
154
      return('0');
155
    end if;
156
  end function;
157
 
158
  function stall_b(DEP,FWDE,IX_2C : std_logic;IDI,IXI : DEC_INSTR_T)
159
    return std_logic is
160
  begin
161
    if(
162
      (DEP = '1') -- and ((FWDE = '0') or (IX_2C = '1') or (IDI.LB /= IXI.LD))
163
    ) then
164
      return(qmark((FWDE = '0') or (IX_2C = '1') or (IDI.LB /= IXI.LD),'1','0'));
165
    else
166
      return('0');
167
    end if;
168
  end function;
169
 
170
  signal IX_2C0,IX_2C1 : std_logic;
171
  signal DATA_DEPA_IX1_0,DATA_DEPA_IX2_0,DATA_DEPA_IX3_0 : std_logic;
172
  signal DATA_DEPB_IX1_0,DATA_DEPB_IX2_0,DATA_DEPB_IX3_0 : std_logic;
173
  signal DATA_DEPA_IX1_1,DATA_DEPA_IX2_1,DATA_DEPA_IX3_1 : std_logic;
174
  signal DATA_DEPB_IX1_1,DATA_DEPB_IX2_1,DATA_DEPB_IX3_1 : std_logic;
175
  signal RMTCH_A_IX1_0,RMTCH_A_IX2_0,RMTCH_A_IX3_0 : std_logic;
176
  signal RMTCH_B_IX1_0,RMTCH_B_IX2_0,RMTCH_B_IX3_0 : std_logic;
177
  signal RMTCH_A_IX1_1,RMTCH_A_IX2_1,RMTCH_A_IX3_1 : std_logic;
178
  signal RMTCH_B_IX1_1,RMTCH_B_IX2_1,RMTCH_B_IX3_1 : std_logic;
179
  signal RAP1,RBP1 : RID_T;
180
  signal RD1P1_0,RD2P1_0,RD3P1_0 : RID_T;
181
  signal RD1P1_1,RD2P1_1,RD3P1_1 : RID_T;
182
  signal STALL_A_IX1_0,STALL_A_IX2_0,STALL_A_IX3_0 : std_logic;
183
  signal STALL_B_IX1_0,STALL_B_IX2_0,STALL_B_IX3_0 : std_logic;
184
  signal STALL_A_IX1_1,STALL_A_IX2_1,STALL_A_IX3_1 : std_logic;
185
  signal STALL_B_IX1_1,STALL_B_IX2_1,STALL_B_IX3_1 : std_logic;
186
 
187
  type NVEC is array (8-1 downto 0) of natural;
188
  signal STALL_STATS : NVEC := (0,0,0,0,0,0,0,0);
189
 
190
begin
191
 
192
  ----------------------------------------------------
193
  -- General rules:
194
  ----------------------------------------------------
195
  --
196
  -- 1) Pipeline stall if ID instruction #0 can't be issued
197
  -- (if ID instruction #0 can be issued and instruction #1
198
  -- can't, pipeline is not stalled).
199
  --
200
  -- 2) Pipeline must be therefore stalled if oldest 
201
  -- ID stage instruction #0 needs a
202
  -- result generated by an instruction in IX1, or IX2, stage,
203
  -- and this instruction is not enabled to result forwarding
204
  -- (only add/i, sub/i, mul/i, movi, lmac/i, lmsu/i and ld/pp
205
  -- instructions are, and the latter three types are 2-cycle
206
  -- instructions that allow forwarding only from stage IX2).
207
  --
208
  -- 3) A long operand can be forwarded only from an instruction
209
  -- generating a long result, and not from two instructions (one
210
  -- in stage IX1 and one in stage IX2) generating each a short
211
  -- result.
212
 
213
  -- As a consequence, pipeline must be stalled (because result
214
  -- forwarding is not possible) if:
215
  -- 1) instruction #0 in ID stage needs a result generated by
216
  -- an instructions in IX1 or IX2 stage, AND [
217
  -- 2.a) the instruction in IX1, is not enabled to
218
  -- result forwarding or is a two-cycle instruction, OR
219
  -- 2.b) the instruction in IX2 stage is not enabled to result
220
  -- forwarding ] AND
221
  -- 3) the instruction in ID stage needs a long (short) result,
222
  -- while the instruction in IX1/2 generates a short (long) one.
223
 
224
  -- NOTE: only stages IF and ID get actually stalled, allowing
225
  -- following stages to proceed.
226
 
227
  ----------------------------------------------------
228
 
229
  -- two-cycle forward-enabled instruction flags
230
 
231
  IX_2C0 <= '1' when (
232
   (IX1_INSTR0_i.IMNMC = IM_LMAC) or
233
   (IX1_INSTR0_i.IMNMC = IM_LMACI) or
234
   (IX1_INSTR0_i.IMNMC = IM_LMSU) or
235
   (IX1_INSTR0_i.IMNMC = IM_LMSUI) or
236
   (IX1_INSTR0_i.IMNMC = IM_LD)
237
  ) else '0';
238
 
239
  IX_2C1 <= '1' when (
240
   (IX1_INSTR1_i.IMNMC = IM_LMAC) or
241
   (IX1_INSTR1_i.IMNMC = IM_LMACI) or
242
   (IX1_INSTR1_i.IMNMC = IM_LMSU) or
243
   (IX1_INSTR1_i.IMNMC = IM_LMSUI) or
244
   (IX1_INSTR1_i.IMNMC = IM_LD)
245
  ) else '0';
246
 
247
  ----------------------------------------------------
248
 
249
  -- Note: when a long result is needed/generated,
250
  -- register id. RX is always an even one, and therefore
251
  -- RX+1 can be generated simply setting LSb to '1'.
252
 
253
  -- ID instr. #0 RA+1
254
  RAP1 <= plus1(ID_INSTR_i.RA);
255
 
256
  -- ID instr. #0 RB+1
257
  RBP1 <= plus1(ID_INSTR_i.RB);
258
 
259
  -- IX1 instr. #0 RD+1
260
  RD1P1_0 <= plus1(IX1_INSTR0_i.RD);
261
 
262
  -- IX2 instr. #0 RD+1
263
  RD2P1_0 <= plus1(IX2_INSTR0_i.RD);
264
 
265
  -- IX3 instr. #0 RD+1
266
  RD3P1_0 <= plus1(IX3_INSTR0_i.RD);
267
 
268
  -- IX1 instr. #1 RD+1
269
  RD1P1_1 <= plus1(IX1_INSTR1_i.RD);
270
 
271
  -- IX2 instr. #1 RD+1
272
  RD2P1_1 <= plus1(IX2_INSTR1_i.RD);
273
 
274
  -- IX3 instr. #1 RD+1
275
  RD3P1_1 <= plus1(IX3_INSTR1_i.RD);
276
 
277
  ----------------------------------------------------
278
 
279
  -- ID instr. vs. IX1/2 instr. register match flags 
280
  -- (when a flag is asserted, there's a mtach between a
281
  -- register read by ID instruction and the register
282
  -- written by IX1/2 instruction).
283
  -- Three possible cases must be checked:
284
  -- 1) ID instruction needs a short (long) result and 
285
  -- IX1/2 instruction generates a short (long) one -> 
286
  -- comparing RA/B to RD is enough.
287
  -- 2) ID instruction needs a long result and IX1/2
288
  -- instruction generates a short one -> RD must be
289
  -- compared to RA/B and (RA/B)+1.
290
  -- 3) ID instruction needs a short result and IX1/2
291
  -- instruction generates a long one -> RA/B must be
292
  -- compared to RD and (RD)+1.
293
 
294
  -- RMTCH_x_IXy_z = '1' when there's a match between ID instruction
295
  -- operand register id. x and IXy instruction #z destination
296
  -- register id..
297
 
298
  RMTCH_A_IX1_0 <= rmtch_a(ID_INSTR_i,IX1_INSTR0_i,RAP1,RD1P1_0);
299
  RMTCH_A_IX2_0 <= rmtch_a(ID_INSTR_i,IX2_INSTR0_i,RAP1,RD2P1_0);
300
  RMTCH_A_IX3_0 <= rmtch_a(ID_INSTR_i,IX3_INSTR0_i,RAP1,RD3P1_0);
301
  RMTCH_B_IX1_0 <= rmtch_b(ID_INSTR_i,IX1_INSTR0_i,RBP1,RD1P1_0);
302
  RMTCH_B_IX2_0 <= rmtch_b(ID_INSTR_i,IX2_INSTR0_i,RBP1,RD2P1_0);
303
  RMTCH_B_IX3_0 <= rmtch_b(ID_INSTR_i,IX3_INSTR0_i,RBP1,RD3P1_0);
304
  RMTCH_A_IX1_1 <= rmtch_a(ID_INSTR_i,IX1_INSTR1_i,RAP1,RD1P1_1);
305
  RMTCH_A_IX2_1 <= rmtch_a(ID_INSTR_i,IX2_INSTR1_i,RAP1,RD2P1_1);
306
  RMTCH_A_IX3_1 <= rmtch_a(ID_INSTR_i,IX3_INSTR1_i,RAP1,RD3P1_1);
307
  RMTCH_B_IX1_1 <= rmtch_b(ID_INSTR_i,IX1_INSTR1_i,RBP1,RD1P1_1);
308
  RMTCH_B_IX2_1 <= rmtch_b(ID_INSTR_i,IX2_INSTR1_i,RBP1,RD2P1_1);
309
  RMTCH_B_IX3_1 <= rmtch_b(ID_INSTR_i,IX3_INSTR1_i,RBP1,RD3P1_1);
310
 
311
  ----------------------------------------------------
312
 
313
  -- DATA_DEPx_IXy_z = '1' when there's a data dependency between
314
  -- ID instruction operand x and IXy instruction #z result 
315
 
316
  DATA_DEPA_IX1_0 <=
317
    dep_a(RMTCH_A_IX1_0,ID_V_i,IX1_V_i(0),ID_INSTR_i,IX1_INSTR0_i);
318
 
319
  DATA_DEPA_IX2_0 <=
320
    dep_a(RMTCH_A_IX2_0,ID_V_i,IX2_V_i(0),ID_INSTR_i,IX2_INSTR0_i);
321
 
322
  DATA_DEPA_IX3_0 <=
323
    dep_a(RMTCH_A_IX3_0,ID_V_i,IX3_V_i(0),ID_INSTR_i,IX3_INSTR0_i);
324
 
325
  DATA_DEPB_IX1_0 <=
326
    dep_b(RMTCH_B_IX1_0,ID_V_i,IX1_V_i(0),ID_INSTR_i,IX1_INSTR0_i);
327
 
328
  DATA_DEPB_IX2_0 <=
329
    dep_b(RMTCH_B_IX2_0,ID_V_i,IX2_V_i(0),ID_INSTR_i,IX2_INSTR0_i);
330
 
331
  DATA_DEPB_IX3_0 <=
332
    dep_b(RMTCH_B_IX3_0,ID_V_i,IX3_V_i(0),ID_INSTR_i,IX3_INSTR0_i);
333
 
334
  DATA_DEPA_IX1_1 <=
335
    dep_a(RMTCH_A_IX1_1,ID_V_i,IX1_V_i(1),ID_INSTR_i,IX1_INSTR1_i);
336
 
337
  DATA_DEPA_IX2_1 <=
338
    dep_a(RMTCH_A_IX2_1,ID_V_i,IX2_V_i(1),ID_INSTR_i,IX2_INSTR1_i);
339
 
340
  DATA_DEPA_IX3_1 <=
341
    dep_a(RMTCH_A_IX3_1,ID_V_i,IX3_V_i(1),ID_INSTR_i,IX3_INSTR1_i);
342
 
343
  DATA_DEPB_IX1_1 <=
344
    dep_b(RMTCH_B_IX1_1,ID_V_i,IX1_V_i(1),ID_INSTR_i,IX1_INSTR1_i);
345
 
346
  DATA_DEPB_IX2_1 <=
347
    dep_b(RMTCH_B_IX2_1,ID_V_i,IX2_V_i(1),ID_INSTR_i,IX2_INSTR1_i);
348
 
349
  DATA_DEPB_IX3_1 <=
350
    dep_b(RMTCH_B_IX3_1,ID_V_i,IX3_V_i(1),ID_INSTR_i,IX3_INSTR1_i);
351
 
352
  ----------------------------------------------------
353
 
354
  -- STALL_x_IXy_z = '1' when there's a stall condition caused by
355
  -- ID instruction operand x and IXy instruction #z result
356
 
357
  STALL_A_IX1_0 <=
358
    stall_a(DATA_DEPA_IX1_0,IX1_FWDE_i(0),IX_2C0,ID_INSTR_i,IX1_INSTR0_i);
359
 
360
  STALL_A_IX2_0 <=
361
    stall_a(DATA_DEPA_IX2_0,IX2_FWDE_i(0),'0',ID_INSTR_i,IX2_INSTR0_i);
362
 
363
  STALL_A_IX3_0 <=
364
    stall_a(DATA_DEPA_IX3_0,IX3_FWDE_i(0),'0',ID_INSTR_i,IX3_INSTR0_i);
365
 
366
  STALL_B_IX1_0 <=
367
    stall_b(DATA_DEPB_IX1_0,IX1_FWDE_i(0),IX_2C0,ID_INSTR_i,IX1_INSTR0_i);
368
 
369
  STALL_B_IX2_0 <=
370
    stall_b(DATA_DEPB_IX2_0,IX2_FWDE_i(0),'0',ID_INSTR_i,IX2_INSTR0_i);
371
 
372
  STALL_B_IX3_0 <=
373
    stall_b(DATA_DEPB_IX3_0,IX3_FWDE_i(0),'0',ID_INSTR_i,IX3_INSTR0_i);
374
 
375
  STALL_A_IX1_1 <=
376
    stall_a(DATA_DEPA_IX1_1,IX1_FWDE_i(1),IX_2C1,ID_INSTR_i,IX1_INSTR1_i);
377
 
378
  STALL_A_IX2_1 <=
379
    stall_a(DATA_DEPA_IX2_1,IX2_FWDE_i(1),'0',ID_INSTR_i,IX2_INSTR1_i);
380
 
381
  STALL_A_IX3_1 <=
382
    stall_a(DATA_DEPA_IX3_1,IX3_FWDE_i(1),'0',ID_INSTR_i,IX3_INSTR1_i);
383
 
384
  STALL_B_IX1_1 <=
385
    stall_b(DATA_DEPB_IX1_1,IX1_FWDE_i(1),IX_2C1,ID_INSTR_i,IX1_INSTR1_i);
386
 
387
  STALL_B_IX2_1 <=
388
    stall_b(DATA_DEPB_IX2_1,IX2_FWDE_i(1),'0',ID_INSTR_i,IX2_INSTR1_i);
389
 
390
  STALL_B_IX3_1 <=
391
    stall_b(DATA_DEPB_IX3_1,IX3_FWDE_i(1),'0',ID_INSTR_i,IX3_INSTR1_i);
392
  ----------------------------------------------------
393
 
394
  -- pipeline stall flag
395
 
396
  PSTALL_o <=
397
    STALL_A_IX1_0 or
398
    STALL_A_IX2_0 or
399
    STALL_A_IX3_0 or
400
    STALL_B_IX1_0 or
401
    STALL_B_IX2_0 or
402
    STALL_B_IX3_0 or
403
    STALL_A_IX1_1 or
404
    STALL_A_IX2_1 or
405
    STALL_A_IX3_1 or
406
    STALL_B_IX1_1 or
407
    STALL_B_IX2_1 or
408
    STALL_B_IX3_1;
409
 
410
 
411
  GSTAT: if(SIMULATION_ONLY = '1') generate
412
 
413
    process(CLK_i)
414
    begin
415
      if(CLK_i = '1' and CLK_i'event) then
416
 
417
        --if(ID_V_i = '1') then
418
 
419
          if(STALL_A_IX1_0 = '1') then
420
            STALL_STATS(0) <= STALL_STATS(0) + 1;
421
          end if;
422
 
423
          if(STALL_A_IX2_0 = '1') then
424
            STALL_STATS(1) <= STALL_STATS(1) + 1;
425
          end if;
426
 
427
          if(STALL_B_IX1_0 = '1') then
428
            STALL_STATS(2) <= STALL_STATS(2) + 1;
429
          end if;
430
 
431
          if(STALL_B_IX2_0 = '1') then
432
            STALL_STATS(3) <= STALL_STATS(3) + 1;
433
          end if;
434
 
435
          if(STALL_A_IX1_1 = '1') then
436
            STALL_STATS(4) <= STALL_STATS(4) + 1;
437
          end if;
438
 
439
          if(STALL_A_IX2_1 = '1') then
440
            STALL_STATS(5) <= STALL_STATS(5) + 1;
441
          end if;
442
 
443
          if(STALL_B_IX1_1 = '1') then
444
            STALL_STATS(6) <= STALL_STATS(6) + 1;
445
          end if;
446
 
447
          if(STALL_B_IX2_1 = '1') then
448
            STALL_STATS(7) <= STALL_STATS(7) + 1;
449
          end if;
450
 
451
        --end if;
452
 
453
      end if;
454
 
455
    end process;
456
 
457
  end generate;
458
 
459
end;
460
 

powered by: WebSVN 2.1.0

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