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

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_asip_ifq.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
-- Instruction Fetching Queue
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_IFQ is
43
  port(
44
    CLK_i : in std_logic;
45
    RST_i : in std_logic;
46
    ID_HALT_i : in std_logic;
47
    IX_BJX_i : in std_logic;
48
    ID_ISSUE_i : in std_logic_vector(2-1 downto 0);
49
    IF_V_i : in std_logic_vector(2-1 downto 0);
50
    IF_PC0_i : in unsigned(ALEN-1 downto 0);
51
    IF_PC1_i : in unsigned(ALEN-1 downto 0);
52
    IF_INSTR0_i : in std_logic_vector(ILEN-1 downto 0);
53
    IF_INSTR1_i : in std_logic_vector(ILEN-1 downto 0);
54
    IF_DEC_INSTR0_i : in DEC_INSTR_T;
55
    IF_DEC_INSTR1_i : in DEC_INSTR_T;
56
    IF_IMM0_i : in std_logic;
57
    IF_IMM1_i : in std_logic;
58
    IF_OPB0_i : in LDWORD_T;
59
    IF_OPB1_i : in LDWORD_T;
60
 
61
    PSTALL_o : out std_logic;
62
    ID_V_o : out std_logic_vector(2-1 downto 0);
63
    ID_PC0_o : out unsigned(ALEN-1 downto 0);
64
    ID_PC1_o : out unsigned(ALEN-1 downto 0);
65
    ID_INSTR0_o : out std_logic_vector(ILEN-1 downto 0);
66
    ID_INSTR1_o : out std_logic_vector(ILEN-1 downto 0);
67
    ID_DEC_INSTR0_o : out DEC_INSTR_T;
68
    ID_DEC_INSTR1_o : out DEC_INSTR_T;
69
    ID_IMM0_o : out std_logic;
70
    ID_IMM1_o : out std_logic;
71
    ID_OPB0_o : out LDWORD_T;
72
    ID_OPB1_o : out LDWORD_T
73
  );
74
end G729A_ASIP_IFQ;
75
 
76
architecture ARC of G729A_ASIP_IFQ is
77
 
78
  constant IFQ_DEPTH : natural := 3;
79
 
80
  type IFQ_ENTRY_T is record
81
    DINSTR : DEC_INSTR_T;
82
    INSTR : std_logic_vector(ILEN-1 downto 0);
83
    PC : unsigned(ALEN-1 downto 0);
84
    IMM : std_logic;
85
    OPB : LDWORD_T;
86
  end record;
87
 
88
  type IFQ_T is array (natural range<>) of IFQ_ENTRY_T;
89
 
90
  signal IFQ_NEW_1,IFQ_NEW_0 : IFQ_ENTRY_T;
91
  signal IFQ,IFQ_q : IFQ_T(IFQ_DEPTH-1 downto 0);
92
  signal IFQV,IFQV_q : std_logic_vector(IFQ_DEPTH-1 downto 0);
93
  signal STALL,UPDT : std_logic;
94
 
95
begin
96
 
97
  ----------------------------------------------------
98
  -- Notes:
99
  -- The queue consists of 3 entries, entry #0 being the
100
  -- oldest entry and entry #2 being the newest one.
101
  -- Entries #0,1 act as pipeline registers between
102
  -- stages IF and ID (so that entries #0,1 are the
103
  -- currently decoded instructions).
104
  ----------------------------------------------------
105
 
106
  ----------------------------------------------------
107
  -- Fetch must stall if the number of empty queue
108
  -- entrie, plus the number of issued instructions
109
  -- is lower than two. 
110
  --
111
  -- Let's put this condition in truth table format:
112
  --
113
  -- 210 issue stall
114
  -- ---------------
115
  -- 000    00     0
116
  -- 001    00     0
117
  -- 001    01     0
118
  -- 01x    00     1
119
  -- 01x    01     0
120
  -- 01x    11     0
121
  -- 1xx    00     1
122
  -- 1xx    01     1
123
  -- 1xx    11     0 
124
  ----------------------------------------------------
125
 
126
  -- fetch stall flag
127
 
128
  --STALL <= '1' when (
129
  --  (IFQV_q(1) = '1' and ID_ISSUE_i = "00") or -- 2 instr. in queue and 0 issue
130
  --  (IFQV_q(2) = '1' and ID_ISSUE_i = "00") or -- 3 instr. in queue and 0 issue
131
  --  (IFQV_q(2) = '1' and ID_ISSUE_i = "01")    -- 3 instr. in queue and 1 issue
132
  --) else '0';
133
 
134
  -- ...re-coded to optimize timing
135
 
136
  STALL <= IFQV_q(2) when (ID_ISSUE_i = "01") else
137
    (IFQV_q(2) or IFQV_q(1)) when (ID_ISSUE_i = "00") else '0';
138
 
139
  ----------------------------------------------------
140
  -- Fetch queue data update
141
  -- 
142
  -- old       new
143
  -- 210 issue 210    keep entry
144
  -- ------------------------
145
  -- 000    ** 0nn B (keep -)
146
  -- 001    00 nno A (keep 0)
147
  -- 001    *1 0nn B (keep -)
148
  -- 01x    00 ooo - (stall)
149
  -- 01x    01 nno A (keep 1)
150
  -- 01x    11 0nn B (keep -)
151
  -- 1xx    00 ooo - (stall)
152
  -- 1xx    01 0oo C (stall) <- (*)
153
  -- 1xx    11 nno A (keep 2)
154
  --
155
  -- n = new instruction
156
  -- o = old instruction
157
  -- 0 = garbage
158
 
159
  -- (*) this is special case: fetch must be stalled because
160
  -- there's no room for a new instruction pair in the queue,
161
  -- but queue data must be updated, because one instruction
162
  -- is issued.
163
 
164
  ----------------------------------------------------
165
 
166
  -- queue update flag
167
 
168
  UPDT <= '0' when (
169
    (IFQV_q(1) = '1' and ID_ISSUE_i = "00") or -- 2 instr. in queue and 0 issue
170
    (IFQV_q(2) = '1' and ID_ISSUE_i = "00") -- 3 instr. in queue and 0 issue
171
  ) else '1';
172
 
173
  IFQ_NEW_0 <= (
174
    IF_DEC_INSTR0_i,
175
    IF_INSTR0_i,
176
    IF_PC0_i,
177
    IF_IMM0_i,
178
    IF_OPB0_i
179
  );
180
 
181
  IFQ_NEW_1 <= (
182
    IF_DEC_INSTR1_i,
183
    IF_INSTR1_i,
184
    IF_PC1_i,
185
    IF_IMM1_i,
186
    IF_OPB1_i
187
  );
188
 
189
  -- fetch queue data update logic
190
  process(IFQV_q,IFQ_q,IF_V_i,ID_ISSUE_i,IFQ_NEW_1,IFQ_NEW_0)
191
    variable KEEP : natural range 2 downto 0;
192
  begin
193
    case ID_ISSUE_i is
194
      when "00" => KEEP := 0;
195
      when "01" => KEEP := 1;
196
      when others => KEEP := 2;
197
    end case;
198
    if(
199
      (IFQV_q(2 downto 0) = "001" and ID_ISSUE_i = "00") or
200
      (IFQV_q(2 downto 1) = "01" and ID_ISSUE_i = "01") or
201
      (IFQV_q(2) = '1' and ID_ISSUE_i = "11")
202
    ) then
203
      -- "A" case (1 old instr. in queue)
204
      IFQV <= IF_V_i & IFQV_q(KEEP);
205
      IFQ <= (IFQ_NEW_1,IFQ_NEW_0,IFQ_q(KEEP));
206
    elsif(
207
      (IFQV_q(2 downto 0) = "000") or
208
      (IFQV_q(2 downto 0) = "001" and ID_ISSUE_i(0) = '1') or
209
      (IFQV_q(2 downto 1) = "01" and ID_ISSUE_i = "11")
210
    ) then
211
      -- "B" case (no old instr. in queue)
212
      IFQV <= '0' & IF_V_i;
213
      IFQ <= (IFQ_q(2),IFQ_NEW_1,IFQ_NEW_0);
214
    else -- if(IFQV_q(2) = '1' and ID_ISSUE_i = "01")
215
      -- "C" case (2 old instr. in queue)
216
      IFQV <= '0' & IFQV_q(2 downto 1);
217
      IFQ <= (IFQ_q(2),IFQ_q(2),IFQ_q(1));
218
    end if;
219
  end process;
220
 
221
  -- fetch queue data registers
222
  process(CLK_i)
223
  begin
224
    if(CLK_i = '1' and CLK_i'event) then
225
 
226
      if(RST_i = '1' or IX_BJX_i = '1') then
227
        IFQV_q <= (others => '0');
228
      elsif(UPDT = '1' and ID_HALT_i = '0') then
229
        IFQV_q <= IFQV;
230
      elsif(ID_HALT_i = '1') then
231
        IFQV_q <= (others => '0');
232
      end if;
233
 
234
      if(UPDT = '1') then
235
        IFQ_q <= IFQ;
236
      end if;
237
 
238
    end if;
239
  end process;
240
 
241
  ----------------------------------------------------
242
  -- outputs
243
  ----------------------------------------------------
244
 
245
  PSTALL_o <= STALL;
246
 
247
  ID_V_o <= IFQV_q(1 downto 0);
248
  ID_PC0_o <= IFQ_q(0).PC;
249
  ID_PC1_o <= IFQ_q(1).PC;
250
  ID_INSTR0_o <= IFQ_q(0).INSTR;
251
  ID_INSTR1_o <= IFQ_q(1).INSTR;
252
  ID_DEC_INSTR0_o <= IFQ_q(0).DINSTR;
253
  ID_DEC_INSTR1_o <= IFQ_q(1).DINSTR;
254
  ID_IMM0_o <= IFQ_q(0).IMM;
255
  ID_IMM1_o <= IFQ_q(1).IMM;
256
  ID_OPB0_o <= IFQ_q(0).OPB;
257
  ID_OPB1_o <= IFQ_q(1).OPB;
258
 
259
end;
260
 

powered by: WebSVN 2.1.0

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