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

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_asip_bjxlog.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 Branch/Jump eXecute 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_OP_PKG.all;
39
 
40
entity G729A_ASIP_BJXLOG is
41
  port(
42
    CLK_i : in std_logic;
43
    RST_i : in std_logic;
44
    BJ_OP : in BJ_OP_T;
45
    PC0P1_i : in unsigned(ALEN-1 downto 0);
46
    PC1P1_i : in unsigned(ALEN-1 downto 0);
47
    PC0_i : in unsigned(ALEN-1 downto 0);
48
    PCSEL_i : in std_logic;
49
    OPA_i : in LDWORD_T;
50
    OPB_i : in LDWORD_T;
51
    OPC_i : in SDWORD_T;
52
    IV_i : in std_logic;
53
    LLCRX_i : in std_logic;
54
    FSTLL_i : in std_logic;
55
 
56
    BJX_o : out std_logic;
57
    BJTA_o : out unsigned(ALEN-1 downto 0)
58
  );
59
end G729A_ASIP_BJXLOG;
60
 
61
architecture ARC of G729A_ASIP_BJXLOG is
62
 
63
  constant SZERO : SDWORD_T := (others => '0');
64
  constant LZERO : LDWORD_T := (others => '0');
65
 
66
  signal BJX : std_logic;
67
  signal BJTA,BJTA_q : unsigned(SDLEN-1 downto 0);
68
  signal BJX_q : std_logic;
69
  signal BJTA1,BJTA2,BJTA3,BJTA4 : unsigned(SDLEN-1 downto 0);
70
 
71
  function to_unsigned(S : signed) return unsigned is
72
    variable U : unsigned(S'HIGH downto S'LOW);
73
  begin
74
    for i in S'HIGH downto S'LOW loop
75
      U(i) := S(i);
76
    end loop;
77
    return(U);
78
  end function;
79
 
80
  function to_signed(U : unsigned) return signed is
81
    variable S : signed(U'HIGH downto U'LOW);
82
  begin
83
    for i in U'HIGH downto U'LOW loop
84
      S(i) := U(i);
85
    end loop;
86
    return(S);
87
  end function;
88
 
89
  function qmark(C : std_logic; A,B : std_logic) return std_logic is
90
  begin
91
    if(C = '1') then
92
      return(A);
93
    else
94
      return(B);
95
    end if;
96
  end function;
97
 
98
  function qmark(C : boolean; A,B : std_logic) return std_logic is
99
  begin
100
    if(C) then
101
      return(A);
102
    else
103
      return(B);
104
    end if;
105
  end function;
106
 
107
  function wrap_sum(A,B : unsigned(SDLEN-1 downto 0)) return unsigned is
108
    variable TMP : unsigned(SDLEN downto 0);
109
  begin
110
    -- A is an unsigned value and thus is zero-extended
111
    -- B has to be instead treated as a signed value and thus is sign-extended
112
    TMP := ('0' & A) + (B(SDLEN-1) & B);
113
    -- result is TMP with MSb removed (wrap-up)
114
    return(TMP(SDLEN-1 downto 0));
115
  end function;
116
 
117
begin
118
 
119
  -- Note:
120
  -- llcr and llcri instructions are treated ad unconditional
121
  -- jumps to address PC+1. This is needed to insure that
122
  -- a possible loop closing instruction located at PC+1 or
123
  -- PC+2 is properly handled (such instruction would leave
124
  -- IF stage before llcr* instruction is executed). The
125
  -- "ad-hoc" jump to PC+1 essentially re-fetches the two
126
  -- instructions at risk.
127
 
128
  -- Pre-calculate all possible target addresses
129
 
130
  -- TA for LLCRX "unconditional jump"
131
  BJTA1 <= PC0P1_i when PCSEL_i = '0' else PC1P1_i;
132
 
133
  -- TA for beq/bne
134
  BJTA2 <= wrap_sum(PC0_i,to_unsigned(OPC_i));
135
 
136
  -- TA for branches
137
  BJTA3 <= wrap_sum(PC0_i,to_unsigned(OPB_i(SDLEN-1 downto 0)));
138
 
139
  -- TA for jumps
140
  BJTA4 <= to_unsigned(OPA_i(SDLEN-1 downto 0))
141
    when ((BJ_OP = BJ_JR) or (BJ_OP = BJ_JRL))
142
    else to_unsigned(OPB_i(SDLEN-1 downto 0));
143
 
144
  -- Select target address
145
 
146
  process(LLCRX_i,BJ_OP,BJTA1,BJTA2,BJTA3,BJTA4)
147
  begin
148
    if(LLCRX_i = '1') then
149
      BJTA <= BJTA1;
150
    elsif((BJ_OP = BJ_BEQ) or (BJ_OP = BJ_BNE)) then
151
      BJTA <= BJTA2;
152
    elsif((BJ_OP /= BJ_JI) and (BJ_OP /= BJ_JIL) and (BJ_OP /= BJ_JR) and (BJ_OP /= BJ_JRL)) then
153
      BJTA <= BJTA3;
154
    else
155
      BJTA <= BJTA4;
156
    end if;
157
  end process;
158
 
159
  -- Set branch/jump execute flag
160
 
161
  process(BJ_OP,OPA_i,OPB_i,OPC_i,LLCRX_i)
162
    variable OPA_LO : SDWORD_T;
163
    variable OPB_LO : SDWORD_T;
164
    variable AEQB_S : std_logic;
165
    variable AEQ0_S : std_logic;
166
    variable ALT0_S : std_logic;
167
    variable AEQ0_L : std_logic;
168
    variable ALT0_L : std_logic;
169
  begin
170
 
171
    OPA_LO := OPA_i(SDLEN-1 downto 0);
172
    OPB_LO := OPB_i(SDLEN-1 downto 0);
173
 
174
    -- Generate comparison flags
175
 
176
    AEQB_S := qmark(OPA_LO = OPB_LO,'1','0');
177
 
178
    AEQ0_S := qmark(OPA_LO = 0,'1','0');
179
 
180
    ALT0_S := OPA_LO(SDLEN-1);
181
 
182
    AEQ0_L := qmark(OPA_i = 0,'1','0');
183
 
184
    ALT0_L := OPA_i(LDLEN-1);
185
 
186
    -- B/J instructions involving comparison of long-type data
187
    -- (LBLEZ or LBGTZ) or between two non-constant values
188
    -- (BEQ or BNE) are given priority to improve timing.
189
 
190
    if(BJ_OP = BJ_LBLEZ or BJ_OP = BJ_LBGTZ or BJ_OP = BJ_BEQ or BJ_OP = BJ_BNE) then
191
 
192
      BJX <=
193
        qmark(BJ_OP = BJ_LBLEZ,ALT0_L or AEQ0_L,'0') or
194
        qmark(BJ_OP = BJ_LBGTZ,not(ALT0_L) and not(AEQ0_L),'0') or
195
        qmark(BJ_OP = BJ_BEQ,AEQB_S,'0') or
196
        qmark(BJ_OP = BJ_BNE,not(AEQB_S),'0');
197
 
198
    else
199
 
200
    case BJ_OP is
201
 
202
      when BJ_JI|BJ_JIL|BJ_JR|BJ_JRL  =>
203
        BJX <= '1';
204
 
205
      when BJ_BLEZ =>
206
        BJX <= ALT0_S or AEQ0_S;
207
 
208
      when BJ_BGTZ =>
209
        BJX <= not(ALT0_S) and not(AEQ0_S);
210
 
211
      when BJ_BLTZ =>
212
        BJX <= ALT0_S;
213
 
214
      when BJ_BGEZ =>
215
        BJX <= not(ALT0_S);
216
 
217
      when BJ_LBLTZ =>
218
        BJX <= ALT0_L;
219
 
220
      when BJ_LBGEZ =>
221
        BJX <= not(ALT0_L);
222
 
223
      when others =>
224
        BJX <= LLCRX_i; --'0';
225
 
226
    end case;
227
 
228
    end if;
229
 
230
  end process;
231
 
232
  -- B/J execute flag and target address register.
233
  -- These registers are needed when a B/J is taken
234
  -- while fecth is stalled: in such condition B/J
235
  -- must deferred to first un-stalled cycle.
236
 
237
  process(CLK_i)
238
  begin
239
    if(CLK_i = '1' and CLK_i'event) then
240
      if(FSTLL_i = '1') then
241
        BJTA_q <= BJTA;
242
      end if;
243
      if(RST_i = '1' or FSTLL_i = '0') then
244
        BJX_q <= '0';
245
      elsif(FSTLL_i = '1') then
246
        BJX_q <= (BJX and IV_i);
247
      end if;
248
    end if;
249
  end process;
250
 
251
  -- A branch/jump is actually executed if:
252
  -- 1) there's a valid B/J instruction in IX1 stage, OR
253
  -- 2) there's a pending B/J.
254
 
255
  BJX_o <= (BJX and IV_i) or (BJX_q);
256
 
257
  BJTA_o <= BJTA_q when (BJX_q = '1') else BJTA;
258
 
259
end ARC;

powered by: WebSVN 2.1.0

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