1 |
2 |
__alexs__ |
-- --------------------------------------------------------------------------
|
2 |
|
|
-- >>>>>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
3 |
|
|
-- --------------------------------------------------------------------------
|
4 |
|
|
-- TITLE: Plasma CONTROL LOGIC
|
5 |
|
|
-- AUTHOR: Alex Schoenberger (Alex.Schoenberger@ies.tu-darmstadt.de)
|
6 |
|
|
-- COMMENT: This project is based on Plasma CPU core by Steve Rhoads
|
7 |
|
|
--
|
8 |
|
|
-- www.ies.tu-darmstadt.de
|
9 |
|
|
-- TU Darmstadt
|
10 |
|
|
-- Institute for Integrated Systems
|
11 |
|
|
-- Merckstr. 25
|
12 |
|
|
--
|
13 |
|
|
-- 64283 Darmstadt - GERMANY
|
14 |
|
|
-- --------------------------------------------------------------------------
|
15 |
|
|
-- PROJECT: Plasma CPU core with FPU
|
16 |
|
|
-- FILENAME: plasma_control.vhd
|
17 |
|
|
-- --------------------------------------------------------------------------
|
18 |
|
|
-- COPYRIGHT:
|
19 |
|
|
-- This project is distributed by GPLv2.0
|
20 |
|
|
-- Software placed into the public domain by the author.
|
21 |
|
|
-- Software 'as is' without warranty. Author liable for nothing.
|
22 |
|
|
-- --------------------------------------------------------------------------
|
23 |
|
|
-- DESCRIPTION:
|
24 |
|
|
-- switches input for computational units
|
25 |
|
|
--
|
26 |
|
|
-- SYNTHESIZABLE
|
27 |
|
|
--
|
28 |
|
|
----------------------------------------------------------------------------
|
29 |
|
|
-- Revision History
|
30 |
|
|
-- --------------------------------------------------------------------------
|
31 |
|
|
-- Revision Date Author CHANGES
|
32 |
|
|
-- 1.0 4/2014 AS initial
|
33 |
|
|
-- 2.0 12/2014 AS separated into MIPS1 simple architecture
|
34 |
|
|
-- and with FPU included
|
35 |
|
|
-- 3.0 05/2015 AS made port more generic, removed FPU and imm
|
36 |
|
|
-- mux
|
37 |
|
|
-- --------------------------------------------------------------------------
|
38 |
|
|
library IEEE;
|
39 |
|
|
use IEEE.std_logic_1164.ALL;
|
40 |
|
|
use IEEE.numeric_std.ALL;
|
41 |
|
|
|
42 |
|
|
library PLASMA;
|
43 |
|
|
use PLASMA.mips_instruction_set.ALL;
|
44 |
|
|
use PLASMA.plasma_pack.ALL;
|
45 |
|
|
|
46 |
|
|
entity plasma_control_MIPSI_FPU is
|
47 |
|
|
generic(
|
48 |
|
|
core_idx : natural := 0
|
49 |
|
|
);
|
50 |
|
|
port(
|
51 |
|
|
control : in t_main_control;
|
52 |
|
|
instr_in : in t_plasma_word; -- input instruction
|
53 |
|
|
-- memory stalls
|
54 |
|
|
prog_stall : in std_logic;
|
55 |
|
|
data_stall : in std_logic;
|
56 |
|
|
-- control flags
|
57 |
|
|
comp_out : in std_logic; -- comparator output
|
58 |
|
|
fpu_cc : in std_logic; -- FPU comparator output
|
59 |
|
|
unit_busy : in t_unit_busy; -- busy flags of units
|
60 |
|
|
-- register bank control
|
61 |
|
|
reg_addr : out t_reg_addr; -- register bank
|
62 |
|
|
fpu_reg_addr : out t_reg_addr; -- FPU register bank
|
63 |
|
|
mux_ctrl : out t_plasma_mux_ctrl; -- datapath muxes
|
64 |
|
|
mux_fpu : out t_plasma_mux_fpu; -- additional FPU muxes
|
65 |
|
|
stall_src : out t_stall_source; -- control registers of datapath
|
66 |
|
|
unit_ctrl : out t_plasma_subunits_ctrl;
|
67 |
|
|
fpu_ctrl : out t_fpu_ctrl;
|
68 |
|
|
-- memory access control
|
69 |
|
|
mem_func : out t_mips_opcode
|
70 |
|
|
);
|
71 |
|
|
end entity plasma_control_MIPSI_FPU;
|
72 |
|
|
--
|
73 |
|
|
architecture structure_plasma_control_MIPSI_FPU of plasma_control_MIPSI_FPU is
|
74 |
|
|
|
75 |
|
|
-- -----------------------------------------------------
|
76 |
|
|
-- ___ ____ ____ ____ ___ ____ ____
|
77 |
|
|
-- | \ |___ | | | | \ |___ |__/
|
78 |
|
|
-- |__/ |___ |___ |__| |__/ |___ | \
|
79 |
|
|
-- -----------------------------------------------------
|
80 |
|
|
-- ---------- 1. STAGE: FETCH AND DECODE ---------------
|
81 |
|
|
signal instr_dec : t_plasma_word;
|
82 |
|
|
|
83 |
|
|
--
|
84 |
|
|
-- operation decode
|
85 |
|
|
--
|
86 |
|
|
alias i_opcode_dec : t_mips_opcode is instr_dec(31 downto 26);
|
87 |
|
|
alias i_format_dec : t_mips_format is instr_dec(20 downto 16);
|
88 |
|
|
alias i_func_dec : t_mips_function is instr_dec( 5 downto 0);
|
89 |
|
|
|
90 |
|
|
--
|
91 |
|
|
-- FPU operation code
|
92 |
|
|
--
|
93 |
|
|
alias i_fpu_fmt_dec : t_mips_reg_addr is instr_dec(25 downto 21); -- i_rs_dec
|
94 |
|
|
alias i_fpu_func_dec : t_mips_function is i_func_dec;
|
95 |
|
|
alias i_fpu_cc_dec : t_mips_cc is instr_dec(10 downto 8);
|
96 |
|
|
alias i_fpu_tf_dec : std_logic is instr_dec(16);
|
97 |
|
|
|
98 |
|
|
--
|
99 |
|
|
-- register addresses
|
100 |
|
|
--
|
101 |
|
|
alias i_rs_dec : t_mips_reg_addr is instr_dec(25 downto 21);
|
102 |
|
|
alias i_rt_dec : t_mips_reg_addr is instr_dec(20 downto 16);
|
103 |
|
|
alias i_rd_dec : t_mips_reg_addr is instr_dec(15 downto 11);
|
104 |
|
|
|
105 |
|
|
alias i_fpu_rs_dec : t_mips_reg_addr is i_rd_dec;
|
106 |
|
|
alias i_fpu_rt_dec : t_mips_reg_addr is i_rt_dec;
|
107 |
|
|
alias i_fpu_rd_dec : t_mips_reg_addr is instr_dec(10 downto 6);
|
108 |
|
|
|
109 |
|
|
--
|
110 |
|
|
-- operation units control
|
111 |
|
|
--
|
112 |
|
|
signal i_unit_ctrl : t_plasma_subunits_ctrl;
|
113 |
|
|
signal i_fpu_mode : t_fpu_mode;
|
114 |
|
|
signal i_mem_func : t_mips_opcode;
|
115 |
|
|
|
116 |
|
|
constant FUNC_INIT : t_mips_opcode := (others => '0'); -- do nothing
|
117 |
|
|
constant SHIFT_INIT : t_mips_opcode := b"10_0000";
|
118 |
|
|
constant COMP_INIT : t_mips_opcode := b"01_1000";
|
119 |
|
|
|
120 |
|
|
--
|
121 |
|
|
-- pipelined mux control
|
122 |
|
|
--
|
123 |
|
|
signal i_src_out_select : t_src_out_select;
|
124 |
|
|
signal i_wb_select : t_wb_select;
|
125 |
|
|
|
126 |
|
|
--
|
127 |
|
|
-- register bank access
|
128 |
|
|
--
|
129 |
|
|
signal i_reg_addr : t_reg_addr;
|
130 |
|
|
signal i_fpu_reg_addr : t_reg_addr;
|
131 |
|
|
|
132 |
|
|
--
|
133 |
|
|
-- intern flags
|
134 |
|
|
--
|
135 |
|
|
signal flag_pc_store : std_logic; -- store pc value
|
136 |
|
|
signal flag_branch : std_logic; -- branch command
|
137 |
|
|
signal flag_fpu_branch : std_logic; -- FPU branch command
|
138 |
|
|
signal flag_fpu_mem : std_logic; -- FPU memory access command
|
139 |
|
|
|
140 |
|
|
signal flag_mult_unit : std_logic; -- indicates mult operation
|
141 |
|
|
signal flag_fpu_unit : std_logic; -- indicates fpu operation
|
142 |
|
|
signal flag_fpu_stall : std_logic; -- FPU no memory command
|
143 |
|
|
|
144 |
|
|
-- ---------- 2. STAGE: EXECUTE ------------------------
|
145 |
|
|
--
|
146 |
|
|
-- pipelined register bank access type
|
147 |
|
|
--
|
148 |
|
|
type t_reg_bank_access is
|
149 |
|
|
record
|
150 |
|
|
we : std_logic;
|
151 |
|
|
rd : t_mips_reg_addr;
|
152 |
|
|
end record;
|
153 |
|
|
|
154 |
|
|
--
|
155 |
|
|
-- unit control
|
156 |
|
|
--
|
157 |
|
|
signal ex_pc_func : t_pc_function; -- pc after branch evaluation
|
158 |
|
|
signal i_ex_rd : t_mips_reg_addr; -- rd after branch evaluation
|
159 |
|
|
|
160 |
|
|
signal reg_ex_unit_ctrl : t_plasma_subunits_ctrl;
|
161 |
|
|
signal reg_ex_mem_func : t_mips_opcode;
|
162 |
|
|
|
163 |
|
|
--
|
164 |
|
|
-- mux control
|
165 |
|
|
--
|
166 |
|
|
signal reg_ex_src_out_sel : t_src_out_select;
|
167 |
|
|
signal reg_ex_wb_sel : t_wb_select;
|
168 |
|
|
|
169 |
|
|
--
|
170 |
|
|
-- register bank access
|
171 |
|
|
--
|
172 |
|
|
signal reg_ex_rb : t_reg_bank_access;
|
173 |
|
|
signal reg_ex_fpu_rb : t_reg_bank_access;
|
174 |
|
|
|
175 |
|
|
--
|
176 |
|
|
-- intern flags
|
177 |
|
|
--
|
178 |
|
|
signal reg_ex_pc_store : std_logic;
|
179 |
|
|
signal reg_flag_branch : std_logic;
|
180 |
|
|
signal reg_ex_fpu_branch : std_logic;
|
181 |
|
|
signal reg_ex_fpu_mem : std_logic;
|
182 |
|
|
|
183 |
|
|
-- ---------- 3. STAGE: MEMORY ACCESS ------------------
|
184 |
|
|
--
|
185 |
|
|
-- unit control
|
186 |
|
|
--
|
187 |
|
|
signal reg_mem_mem_func : t_mips_opcode;
|
188 |
|
|
|
189 |
|
|
--
|
190 |
|
|
-- mux control
|
191 |
|
|
--
|
192 |
|
|
signal reg_mem_wb_sel : t_wb_select;
|
193 |
|
|
|
194 |
|
|
--
|
195 |
|
|
-- register bank access
|
196 |
|
|
--
|
197 |
|
|
signal reg_mem_rb : t_reg_bank_access;
|
198 |
|
|
signal reg_mem_fpu_rb : t_reg_bank_access;
|
199 |
|
|
|
200 |
|
|
--
|
201 |
|
|
-- intern flags
|
202 |
|
|
--
|
203 |
|
|
signal reg_mem_fpu_mem : std_logic;
|
204 |
|
|
|
205 |
|
|
-- ---------- 4. STAGE: WRITE BACK ---------------------
|
206 |
|
|
--
|
207 |
|
|
-- register bank access
|
208 |
|
|
--
|
209 |
|
|
signal reg_wb_rb : t_reg_bank_access;
|
210 |
|
|
|
211 |
|
|
-- ---------- FORWARDING -------------------------------
|
212 |
|
|
type t_forward_stage_flag is
|
213 |
|
|
record
|
214 |
|
|
rd_zero : std_logic;
|
215 |
|
|
rs : std_logic;
|
216 |
|
|
rt : std_logic;
|
217 |
|
|
end record;
|
218 |
|
|
|
219 |
|
|
type t_forward_flag is
|
220 |
|
|
record
|
221 |
|
|
ex : t_forward_stage_flag;
|
222 |
|
|
mem : t_forward_stage_flag;
|
223 |
|
|
wb : t_forward_stage_flag;
|
224 |
|
|
end record;
|
225 |
|
|
|
226 |
|
|
signal forward_flags : t_forward_flag;
|
227 |
|
|
|
228 |
|
|
-- ---------- STALL LOGIC ------------------------------
|
229 |
|
|
signal stall_ex_possible : std_logic; -- memory access in the previous command
|
230 |
|
|
signal stall_ex_detect : std_logic; -- stall detection
|
231 |
|
|
signal stall_unit_detect : std_logic; -- a unit causes stall
|
232 |
|
|
signal stall_fpu_detect : std_logic; -- fpu stall detection
|
233 |
|
|
|
234 |
|
|
signal i_stall : std_logic; -- intern stall flag
|
235 |
|
|
|
236 |
|
|
-- ---------- BRANCH -----------------------------------
|
237 |
|
|
signal branch_true : std_logic; -- branch should be taken
|
238 |
|
|
signal fpu_branch_true : std_logic; -- FPU branch is true
|
239 |
|
|
|
240 |
|
|
-- ---------- DEBUGGING --------------------------------
|
241 |
|
|
--
|
242 |
|
|
begin
|
243 |
|
|
|
244 |
|
|
-- --------------------------------------------------------------------------
|
245 |
|
|
-- _____ ______ _____ ____ _____ ______ _____
|
246 |
|
|
-- | __ \| ____/ ____/ __ \| __ \| ____| __ \
|
247 |
|
|
-- | | | | |__ | | | | | | | | | |__ | |__) |
|
248 |
|
|
-- | | | | __|| | | | | | | | | __| | _ /
|
249 |
|
|
-- | |__| | |___| |___| |__| | |__| | |____| | \ \
|
250 |
|
|
-- |_____/|______\_____\____/|_____/|______|_| \_\
|
251 |
|
|
-- --------------------------------------------------------------------------
|
252 |
|
|
instr_dec <= instr_in;
|
253 |
|
|
|
254 |
|
|
-- _ ____ ____ ___ ____ _ _ ____ _ _ ___ ___ ____ ____ ____ ___ ____
|
255 |
|
|
-- | . |___ |___ | | |__| |__| |\ | | \ | \ |___ | | | | \ |___
|
256 |
|
|
-- | . | |___ | |___ | | | | | \| |__/ |__/ |___ |___ |__| |__/ |___
|
257 |
|
|
-- --------------------------------------------------------------------------
|
258 |
|
|
--
|
259 |
|
|
-- UNIT and MUX control
|
260 |
|
|
-- REGISTER BANK REGULAR ADDRESSES
|
261 |
|
|
--
|
262 |
|
|
-- ___ ____ ____ ____ ___ ____
|
263 |
|
|
-- | \ |___ | | | | \ |___
|
264 |
|
|
-- |__/ |___ |___ |__| |__/ |___
|
265 |
|
|
decode_process:
|
266 |
|
|
process( instr_dec )
|
267 |
|
|
variable clear_rb_access : boolean := FALSE;
|
268 |
|
|
begin
|
269 |
|
|
-- -------------------------------------------------------------------
|
270 |
|
|
-- ___ ____ ____ ____ _ _ _ ___ _ _ ____ _ _ _ ____ ____
|
271 |
|
|
-- | \ |___ |___ |__| | | | | | | |__| | | | |___ [__
|
272 |
|
|
-- |__/ |___ | | | |__| |___ | \/ | | |___ |__| |___ ___]
|
273 |
|
|
-- -------------------------------------------------------------------
|
274 |
|
|
--
|
275 |
|
|
-- SUBCOMPONENTS CONTROL
|
276 |
|
|
--
|
277 |
|
|
i_unit_ctrl <= (pc_func => PLASMA_PC_INC,
|
278 |
|
|
alu_func => i_opcode_dec,
|
279 |
|
|
shift_func => SHIFT_INIT,
|
280 |
|
|
mult_func => FUNC_INIT,
|
281 |
|
|
comp_func => COMP_INIT);
|
282 |
|
|
|
283 |
|
|
-- FPU :
|
284 |
|
|
fpu_ctrl.operation <= MIPS_FUNC_FMT_MOV; -- do nothing
|
285 |
|
|
fpu_ctrl.c_reg <= '0'; -- no FPU control register access
|
286 |
|
|
fpu_ctrl.fix <= '0'; -- no inter conversion
|
287 |
|
|
fpu_ctrl.double <= '0'; -- single precision
|
288 |
|
|
|
289 |
|
|
-- memory control
|
290 |
|
|
i_mem_func <= i_opcode_dec; -- pass opcode
|
291 |
|
|
|
292 |
|
|
--
|
293 |
|
|
-- MUX CONTROL
|
294 |
|
|
--
|
295 |
|
|
-- source mux control:
|
296 |
|
|
mux_ctrl.src_imm <= IMM_SIGN; -- IMMEDIATE = SIGN EXTENDED
|
297 |
|
|
mux_ctrl.src_b_imm <= B_IMM_ON; -- PASS IMMEDIATE VALUE FOR 2. source
|
298 |
|
|
|
299 |
|
|
-- FPU intern muxes
|
300 |
|
|
mux_fpu.fpu_id <= FPU_DATA_INTERN; -- intern FPU data
|
301 |
|
|
|
302 |
|
|
-- coprocessor mux
|
303 |
|
|
mux_fpu.cop <= COP_SELECT_CORE; -- MAIN CORE
|
304 |
|
|
|
305 |
|
|
-- units mux control
|
306 |
|
|
i_src_out_select <= SRC_OUT_ALU; -- ALU output
|
307 |
|
|
|
308 |
|
|
-- write back control
|
309 |
|
|
i_wb_select <= WB_OP_UNIT; -- unit output
|
310 |
|
|
|
311 |
|
|
--
|
312 |
|
|
-- REBULAR REGISTER BANK
|
313 |
|
|
--
|
314 |
|
|
i_reg_addr <= (we => '1', -- write access enable
|
315 |
|
|
rs => i_rs_dec, -- 1. source
|
316 |
|
|
rt => i_rt_dec, -- target
|
317 |
|
|
rd => i_rt_dec); -- destination
|
318 |
|
|
|
319 |
|
|
clear_rb_access := FALSE; -- access to regular register bank
|
320 |
|
|
|
321 |
|
|
--
|
322 |
|
|
-- FPU REGISTER BANK
|
323 |
|
|
--
|
324 |
|
|
i_fpu_mode <= FPU_MODE_NONE; -- NO FPU register bank access
|
325 |
|
|
i_fpu_reg_addr <= ( we => '0',
|
326 |
|
|
rs => i_fpu_rs_dec,
|
327 |
|
|
rt => i_fpu_rt_dec,
|
328 |
|
|
rd => i_fpu_rd_dec);
|
329 |
|
|
|
330 |
|
|
--
|
331 |
|
|
-- INTERN FLAGS
|
332 |
|
|
--
|
333 |
|
|
flag_pc_store <= '0'; -- store next pc value by linked jumps, disabled
|
334 |
|
|
flag_branch <= '0'; -- no branch command
|
335 |
|
|
flag_fpu_branch <= '0'; -- FPU branch command
|
336 |
|
|
flag_fpu_mem <= '0'; -- FPU memory access command
|
337 |
|
|
|
338 |
|
|
flag_mult_unit <= '0'; -- no mult operation
|
339 |
|
|
flag_fpu_unit <= '0'; -- no FPU operation
|
340 |
|
|
flag_fpu_stall <= '0'; -- FPU no memmory access command
|
341 |
|
|
|
342 |
|
|
--
|
343 |
|
|
-- DEBUGGING
|
344 |
|
|
--
|
345 |
|
|
--synthesis translate_off
|
346 |
|
|
i_sim_control.sim_message(core_idx) <= '0';
|
347 |
|
|
i_sim_control.sim_stop <= '0';
|
348 |
|
|
i_sim_control.print_message <= '0';
|
349 |
|
|
i_sim_control.sim_finish <= '0';
|
350 |
|
|
i_sim_control.track_en(core_idx) <= '0';
|
351 |
|
|
i_sim_control.track_mark <= '0';
|
352 |
|
|
--synthesis translate_on
|
353 |
|
|
|
354 |
|
|
-- ------------ OPERATION DECODE -------------------------------------------------------------------
|
355 |
|
|
case i_opcode_dec is
|
356 |
|
|
-- ----------- REGISTER FORMAT -------------------------------------------------------------------
|
357 |
|
|
when MIPS_OPCODE_REG =>
|
358 |
|
|
|
359 |
|
|
mux_ctrl.src_b_imm <= B_IMM_OF; -- DEFAULT: cut immediate value passing
|
360 |
|
|
i_reg_addr.rd <= i_rd_dec; -- DEFAULT: destination is on rd field
|
361 |
|
|
|
362 |
|
|
case i_func_dec is
|
363 |
|
|
-- ------------------------------------ SHIFTER ----------------------------------------------
|
364 |
|
|
when MIPS_FUNC_SLL |
|
365 |
|
|
MIPS_FUNC_SRL |
|
366 |
|
|
MIPS_FUNC_SRA => i_unit_ctrl.shift_func <= i_func_dec; -- pass function
|
367 |
|
|
|
368 |
|
|
mux_ctrl.src_imm <= IMM_SHAMT; -- shift amount for immediate mux
|
369 |
|
|
mux_ctrl.src_b_imm <= B_IMM_ON; -- pass immediate value
|
370 |
|
|
|
371 |
|
|
i_src_out_select <= SRC_OUT_SHIFT; -- output from shifter
|
372 |
|
|
|
373 |
|
|
i_reg_addr.rs <= i_rt_dec; -- source is on rt field
|
374 |
|
|
|
375 |
|
|
when MIPS_FUNC_SLLV |
|
376 |
|
|
MIPS_FUNC_SRLV |
|
377 |
|
|
MIPS_FUNC_SRAV => i_unit_ctrl.shift_func <= i_func_dec; -- pass function
|
378 |
|
|
|
379 |
|
|
i_src_out_select <= SRC_OUT_SHIFT; -- output from shifter
|
380 |
|
|
|
381 |
|
|
i_reg_addr.rs <= i_rt_dec; -- 1. and 2. source are switched
|
382 |
|
|
i_reg_addr.rt <= i_rs_dec;
|
383 |
|
|
|
384 |
|
|
-- ------------------------------------ JUMP REGISTER ----------------------------------------
|
385 |
|
|
when MIPS_FUNC_JR => i_unit_ctrl.pc_func <= PLASMA_PC_REG; -- pc operation code
|
386 |
|
|
|
387 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
388 |
|
|
|
389 |
|
|
when MIPS_FUNC_JALR => i_unit_ctrl.pc_func <= PLASMA_PC_REG; -- pc operation code
|
390 |
|
|
i_src_out_select <= SRC_OUT_PC; -- output source select
|
391 |
|
|
|
392 |
|
|
i_reg_addr.rd <= MIPS_R_RA; -- return address
|
393 |
|
|
|
394 |
|
|
-- ------------------------------------ INTERRUPTS -------------------------------------------
|
395 |
|
|
--synthesis translate_off
|
396 |
|
|
when MIPS_FUNC_SYSCALL =>
|
397 |
|
|
case( instr_dec(10 downto 6) ) is
|
398 |
|
|
when b"00000" => i_sim_control.sim_message(core_idx) <= '1';
|
399 |
|
|
when b"00001" => i_sim_control.sim_stop <= '1';
|
400 |
|
|
when b"00010" => i_sim_control.print_message <= '1';
|
401 |
|
|
when b"00011" => i_sim_control.sim_finish <= '1';
|
402 |
|
|
when b"00100" => i_sim_control.track_en(core_idx) <= '1';
|
403 |
|
|
when b"00101" => i_sim_control.track_mark <= '1';
|
404 |
|
|
when others =>
|
405 |
|
|
end case;
|
406 |
|
|
--synthesis translate_on
|
407 |
|
|
-- when MIPS_FUNC_BREAK =>
|
408 |
|
|
|
409 |
|
|
-- ------------------------------------ MULTIPLICATOR ----------------------------------------
|
410 |
|
|
when MIPS_FUNC_MFHI |
|
411 |
|
|
MIPS_FUNC_MFLO => i_unit_ctrl.mult_func <= i_func_dec; -- pass function
|
412 |
|
|
|
413 |
|
|
i_src_out_select <= SRC_OUT_MULT; -- output from mult
|
414 |
|
|
|
415 |
|
|
flag_mult_unit <= '1'; -- possible unit stall
|
416 |
|
|
|
417 |
|
|
when MIPS_FUNC_MTHI |
|
418 |
|
|
MIPS_FUNC_MTLO |
|
419 |
|
|
MIPS_FUNC_MULT |
|
420 |
|
|
MIPS_FUNC_MULTU |
|
421 |
|
|
MIPS_FUNC_DIV |
|
422 |
|
|
MIPS_FUNC_DIVU => i_unit_ctrl.mult_func <= i_func_dec; -- pass function
|
423 |
|
|
|
424 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
425 |
|
|
|
426 |
|
|
flag_mult_unit <= '1'; -- possible unit stall
|
427 |
|
|
|
428 |
|
|
-- ------------------------------------ ALU --------------------------------------------------
|
429 |
|
|
when MIPS_FUNC_ADD |
|
430 |
|
|
MIPS_FUNC_ADDU |
|
431 |
|
|
MIPS_FUNC_SUB |
|
432 |
|
|
MIPS_FUNC_SUBU |
|
433 |
|
|
MIPS_FUNC_AND |
|
434 |
|
|
MIPS_FUNC_OR |
|
435 |
|
|
MIPS_FUNC_XOR |
|
436 |
|
|
MIPS_FUNC_NOR |
|
437 |
|
|
MIPS_FUNC_SLT |
|
438 |
|
|
MIPS_FUNC_SLTU => i_unit_ctrl.alu_func <= i_func_dec; -- pass function to ALU -- pass command to ALU
|
439 |
|
|
|
440 |
|
|
when others =>
|
441 |
|
|
--synthesis translate_off
|
442 |
|
|
report "WARNING:Unknown function code " & sv2string( i_func_dec );
|
443 |
|
|
--synthesis translate_on
|
444 |
|
|
end case;
|
445 |
|
|
|
446 |
|
|
-- ----------------------------------- COPROCESSOR 1 (FPU)----------------------------------------------
|
447 |
|
|
when MIPS_OPCODE_COP1 =>
|
448 |
|
|
|
449 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
450 |
|
|
|
451 |
|
|
flag_fpu_unit <= '1'; -- possible unit stall
|
452 |
|
|
flag_fpu_stall <= '1'; -- FPU no memory command
|
453 |
|
|
|
454 |
|
|
case i_fpu_fmt_dec is
|
455 |
|
|
-- ------------------------------------ FPU ALU OPERATION ------------------------------------
|
456 |
|
|
when MIPS_FMT_FLOAT_SINGLE |
|
457 |
|
|
MIPS_FMT_FLOAT_DOUBLE |
|
458 |
|
|
MIPS_FMT_FIXED_WORD =>
|
459 |
|
|
|
460 |
|
|
fpu_ctrl.operation <= i_fpu_func_dec; -- pass FPU operation
|
461 |
|
|
|
462 |
|
|
if i_fpu_fmt_dec = MIPS_FMT_FLOAT_DOUBLE then fpu_ctrl.double <= '1'; end if; -- double precision operation
|
463 |
|
|
if i_fpu_fmt_dec = MIPS_FMT_FIXED_WORD then fpu_ctrl.fix <= '1'; end if; -- integer (fix point) operation
|
464 |
|
|
|
465 |
|
|
i_fpu_reg_addr.we <= '1'; -- write to FPU register bank
|
466 |
|
|
|
467 |
|
|
if std_match(i_fpu_func_dec, MIPS_FUNC_FMT_COND) then
|
468 |
|
|
i_fpu_mode <= FPU_MODE_C; -- COMPARATOR operation
|
469 |
|
|
else
|
470 |
|
|
i_fpu_mode <= FPU_MODE_ALU; -- ALU operation
|
471 |
|
|
end if;
|
472 |
|
|
|
473 |
|
|
-- ------------------------------------ FPU BRANCH -------------------------------------------
|
474 |
|
|
when MIPS_FMT_BRANCH => mux_ctrl.src_imm <= IMM_BRANCH; -- immediate mux control
|
475 |
|
|
|
476 |
|
|
flag_branch <= '1'; -- set branch flag
|
477 |
|
|
flag_fpu_branch <= '1'; -- set FPU branch flag
|
478 |
|
|
|
479 |
|
|
-- ------------------------------------ EXCHANGE DATA ----------------------------------------
|
480 |
|
|
when MIPS_FMT_MTC => mux_fpu.fpu_id <= FPU_DATA_CORE; -- data from core
|
481 |
|
|
|
482 |
|
|
i_fpu_mode <= FPU_MODE_FGR; -- access to FPU register bank
|
483 |
|
|
i_fpu_reg_addr.we <= '1'; -- write enable
|
484 |
|
|
i_fpu_reg_addr.rd <= i_rd_dec; -- destination is on rd field
|
485 |
|
|
|
486 |
|
|
when MIPS_FMT_CTC => mux_fpu.fpu_id <= FPU_DATA_CORE; -- data from core
|
487 |
|
|
|
488 |
|
|
i_fpu_mode <= FPU_MODE_CTC; -- access to FPU control register
|
489 |
|
|
i_fpu_reg_addr.we <= '1'; -- write enable
|
490 |
|
|
|
491 |
|
|
when MIPS_FMT_MFC => mux_fpu.cop <= COP_SELECT_COP1; -- input data from FPU
|
492 |
|
|
i_src_out_select <= SRC_OUT_MEM_DATA; -- inject data from memory path
|
493 |
|
|
|
494 |
|
|
i_reg_addr.we <= '1'; -- write to regular register bank
|
495 |
|
|
i_reg_addr.rd <= i_rt_dec; -- destination is on rt field
|
496 |
|
|
clear_rb_access := FALSE;
|
497 |
|
|
|
498 |
|
|
when MIPS_FMT_CFC => mux_fpu.cop <= COP_SELECT_COP1; -- input data from FPU
|
499 |
|
|
i_src_out_select <= SRC_OUT_MEM_DATA; -- inject data from memory path
|
500 |
|
|
|
501 |
|
|
i_reg_addr.we <= '1'; -- write to regular register bank
|
502 |
|
|
i_reg_addr.rd <= i_rt_dec; -- destination is on rt field
|
503 |
|
|
clear_rb_access := FALSE;
|
504 |
|
|
|
505 |
|
|
|
506 |
|
|
fpu_ctrl.c_reg <= '1'; -- access to control register of FPU
|
507 |
|
|
|
508 |
|
|
when others =>
|
509 |
|
|
--synthesis translate_off
|
510 |
|
|
report "WARNING:Unknown FPU function code " & sv2string( i_fpu_fmt_dec );
|
511 |
|
|
--synthesis translate_on
|
512 |
|
|
end case;
|
513 |
|
|
|
514 |
|
|
-- ------------------------------------ REGIMM ---------------------------------------------------
|
515 |
|
|
when MIPS_OPCODE_REGIMM =>
|
516 |
|
|
|
517 |
|
|
i_unit_ctrl.comp_func <= '0' & i_format_dec; -- pass format
|
518 |
|
|
|
519 |
|
|
mux_ctrl.src_imm <= IMM_BRANCH; -- pass branch immediate value
|
520 |
|
|
|
521 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
522 |
|
|
|
523 |
|
|
flag_branch <= '1'; -- set branch command
|
524 |
|
|
|
525 |
|
|
case i_format_dec is
|
526 |
|
|
when MIPS_OPCODE_BLTZ |
|
527 |
|
|
MIPS_OPCODE_BGEZ => -- pass opcode
|
528 |
|
|
|
529 |
|
|
when MIPS_OPCODE_BLTZAL |
|
530 |
|
|
MIPS_OPCODE_BGEZAL => i_src_out_select <= SRC_OUT_PC; -- pc value as output source
|
531 |
|
|
|
532 |
|
|
flag_pc_store <= '1'; -- set pc store flag
|
533 |
|
|
|
534 |
|
|
when others =>
|
535 |
|
|
-- synthesis translate_off
|
536 |
|
|
report "WARNING:Unknown format code " & sv2string( i_format_dec );
|
537 |
|
|
-- synthesis translate_on
|
538 |
|
|
end case;
|
539 |
|
|
|
540 |
|
|
when MIPS_OPCODE_BEQ |
|
541 |
|
|
MIPS_OPCODE_BNE => i_unit_ctrl.comp_func <= i_opcode_dec; -- pass function
|
542 |
|
|
|
543 |
|
|
mux_ctrl.src_b_imm <= B_IMM_OF; -- disable immediate pass
|
544 |
|
|
mux_ctrl.src_imm <= IMM_BRANCH; -- pass branch immediate
|
545 |
|
|
|
546 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
547 |
|
|
|
548 |
|
|
flag_branch <= '1'; -- set branch command
|
549 |
|
|
|
550 |
|
|
when MIPS_OPCODE_BLEZ |
|
551 |
|
|
MIPS_OPCODE_BGTZ => i_unit_ctrl.comp_func <= i_opcode_dec; -- pass function
|
552 |
|
|
|
553 |
|
|
mux_ctrl.src_imm <= IMM_BRANCH; -- pass branch immediate
|
554 |
|
|
|
555 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
556 |
|
|
|
557 |
|
|
flag_branch <= '1'; -- set branch command
|
558 |
|
|
|
559 |
|
|
-- ------------------------------------ ALU ------------------------------------------------------
|
560 |
|
|
when MIPS_OPCODE_ADDI |
|
561 |
|
|
MIPS_OPCODE_ADDIU |
|
562 |
|
|
MIPS_OPCODE_SLTI |
|
563 |
|
|
MIPS_OPCODE_SLTIU => -- pass operation code
|
564 |
|
|
|
565 |
|
|
when MIPS_OPCODE_ANDI |
|
566 |
|
|
MIPS_OPCODE_ORI |
|
567 |
|
|
MIPS_OPCODE_XORI => mux_ctrl.src_imm <= IMM_UNSIGN; -- pass unsigned immediate
|
568 |
|
|
|
569 |
|
|
when MIPS_OPCODE_LUI => mux_ctrl.src_imm <= IMM_HIGH; -- pass shifted immediate
|
570 |
|
|
|
571 |
|
|
-- ------------------------------------ LOAD MEMORY ----------------------------------------------
|
572 |
|
|
when MIPS_OPCODE_LB |
|
573 |
|
|
MIPS_OPCODE_LH |
|
574 |
|
|
MIPS_OPCODE_LWL |
|
575 |
|
|
MIPS_OPCODE_LW |
|
576 |
|
|
-- MIPS_OPCODE_LWR | -- COMPILER BUG !!
|
577 |
|
|
MIPS_OPCODE_LBU |
|
578 |
|
|
MIPS_OPCODE_LHU => i_unit_ctrl.alu_func <= MIPS_FUNC_ADD; -- switch ALU to addition -> address calcultion
|
579 |
|
|
|
580 |
|
|
i_wb_select <= WB_MEMORY; -- pass memory data
|
581 |
|
|
|
582 |
|
|
when MIPS_OPCODE_LWR => -- DO NOTHING !!
|
583 |
|
|
|
584 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
585 |
|
|
|
586 |
|
|
when MIPS_OPCODE_LWC1 => i_unit_ctrl.alu_func <= MIPS_FUNC_ADD; -- switch ALU to addition -> address calcultion
|
587 |
|
|
|
588 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
589 |
|
|
i_fpu_reg_addr.rd <= i_rt_dec; -- destination is on rt field
|
590 |
|
|
|
591 |
|
|
flag_fpu_mem <= '1'; -- set FPU memory access flag
|
592 |
|
|
|
593 |
|
|
-- ------------------------------------ STORE MEMORY ---------------------------------------------
|
594 |
|
|
when MIPS_OPCODE_SB |
|
595 |
|
|
MIPS_OPCODE_SH |
|
596 |
|
|
MIPS_OPCODE_SWL |
|
597 |
|
|
MIPS_OPCODE_SW |
|
598 |
|
|
MIPS_OPCODE_SWR => i_unit_ctrl.alu_func <= MIPS_FUNC_ADD; -- switch ALU to addition -> address calcultion
|
599 |
|
|
|
600 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
601 |
|
|
|
602 |
|
|
when MIPS_OPCODE_SWC1 => i_unit_ctrl.alu_func <= MIPS_FUNC_ADD; -- switch ALU to addition -> address calcultion
|
603 |
|
|
|
604 |
|
|
mux_fpu.cop <= COP_SELECT_COP1; -- data from FPU
|
605 |
|
|
|
606 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
607 |
|
|
i_fpu_reg_addr.rs <= i_fpu_rt_dec; -- source is on rt field
|
608 |
|
|
|
609 |
|
|
-- ------------------------------------ JUMP -----------------------------------------------------
|
610 |
|
|
when MIPS_OPCODE_J => i_unit_ctrl.pc_func <= PLASMA_PC_IMM; -- pc = long immedate
|
611 |
|
|
|
612 |
|
|
mux_ctrl.src_imm <= IMM_JUMP; -- pass long immediate
|
613 |
|
|
|
614 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
615 |
|
|
|
616 |
|
|
when MIPS_OPCODE_JAL => i_unit_ctrl.pc_func <= PLASMA_PC_IMM; -- pc = long immedate
|
617 |
|
|
|
618 |
|
|
mux_ctrl.src_imm <= IMM_JUMP; -- pass long immediate
|
619 |
|
|
i_src_out_select <= SRC_OUT_PC; -- pass pc value
|
620 |
|
|
|
621 |
|
|
i_reg_addr.rd <= MIPS_R_RA; -- return address
|
622 |
|
|
|
623 |
|
|
when others =>
|
624 |
|
|
--synthesis translate_off
|
625 |
|
|
report "Unknown opcode " & sv2string( i_opcode_dec );
|
626 |
|
|
--synthesis translate_on
|
627 |
|
|
end case;
|
628 |
|
|
|
629 |
|
|
--
|
630 |
|
|
-- clear register bank access
|
631 |
|
|
--
|
632 |
|
|
if clear_rb_access then
|
633 |
|
|
i_reg_addr.we <= '0'; -- no write enable
|
634 |
|
|
i_reg_addr.rd <= MIPS_R_ZERO; -- for forward logic
|
635 |
|
|
end if;
|
636 |
|
|
end process;
|
637 |
|
|
-- --------------------------------------------------------------------------
|
638 |
|
|
|
639 |
|
|
-- ____ ____ ____ _ _ _ ____ ____ ___ _ _ _ ____
|
640 |
|
|
-- |___ | | |__/ | | | |__| |__/ | \ | |\ | | __
|
641 |
|
|
-- | |__| | \ |_|_| | | | \ |__/ | | \| |__]
|
642 |
|
|
--
|
643 |
|
|
-- detect equal addresses
|
644 |
|
|
--
|
645 |
|
|
-- execution stage
|
646 |
|
|
forward_flags.ex.rd_zero <= '1' when reg_ex_rb.rd = MIPS_R_ZERO else '0';
|
647 |
|
|
forward_flags.ex.rs <= not forward_flags.ex.rd_zero when i_reg_addr.rs = reg_ex_rb.rd else '0';
|
648 |
|
|
forward_flags.ex.rt <= not forward_flags.ex.rd_zero when i_reg_addr.rt = reg_ex_rb.rd else '0';
|
649 |
|
|
|
650 |
|
|
-- memory stage
|
651 |
|
|
forward_flags.mem.rd_zero <= '1' when reg_mem_rb.rd = MIPS_R_ZERO else '0';
|
652 |
|
|
forward_flags.mem.rs <= not forward_flags.mem.rd_zero when i_reg_addr.rs = reg_mem_rb.rd else '0';
|
653 |
|
|
forward_flags.mem.rt <= not forward_flags.mem.rd_zero when i_reg_addr.rt = reg_mem_rb.rd else '0';
|
654 |
|
|
|
655 |
|
|
-- write back stage
|
656 |
|
|
forward_flags.wb.rd_zero <= '1' when reg_wb_rb.rd = MIPS_R_ZERO else '0';
|
657 |
|
|
forward_flags.wb.rs <= not forward_flags.wb.rd_zero when i_reg_addr.rs = reg_wb_rb.rd else '0';
|
658 |
|
|
forward_flags.wb.rt <= not forward_flags.wb.rd_zero when i_reg_addr.rt = reg_wb_rb.rd else '0';
|
659 |
|
|
|
660 |
|
|
--
|
661 |
|
|
-- set forwarded register bank addresses
|
662 |
|
|
--
|
663 |
|
|
forward_process:
|
664 |
|
|
process( forward_flags )
|
665 |
|
|
begin
|
666 |
|
|
--
|
667 |
|
|
-- -------- A SOURCE FORWARDING -----------------
|
668 |
|
|
--
|
669 |
|
|
if forward_flags.ex.rs = '1' then mux_ctrl.src_a <= SRC_OP_OUT;
|
670 |
|
|
elsif forward_flags.mem.rs = '1' then mux_ctrl.src_a <= SRC_MEM_OUT;
|
671 |
|
|
elsif forward_flags.wb.rs = '1' then mux_ctrl.src_a <= SRC_WB_OUT;
|
672 |
|
|
else mux_ctrl.src_a <= SRC_REG;
|
673 |
|
|
end if;
|
674 |
|
|
|
675 |
|
|
--
|
676 |
|
|
-- -------- B SOURCE FORWARDING ------------------
|
677 |
|
|
--
|
678 |
|
|
if forward_flags.ex.rt = '1' then mux_ctrl.src_b <= SRC_OP_OUT;
|
679 |
|
|
elsif forward_flags.mem.rt = '1' then mux_ctrl.src_b <= SRC_MEM_OUT;
|
680 |
|
|
elsif forward_flags.wb.rt = '1' then mux_ctrl.src_b <= SRC_WB_OUT;
|
681 |
|
|
else mux_ctrl.src_b <= SRC_REG;
|
682 |
|
|
end if;
|
683 |
|
|
end process;
|
684 |
|
|
|
685 |
|
|
-- ____ ___ ____ _ _ _ ____ ____ _ ____
|
686 |
|
|
-- [__ | |__| | | | | | | __ | |
|
687 |
|
|
-- ___] | | | |___ |___ |___ |__| |__] | |___
|
688 |
|
|
--
|
689 |
|
|
-- 4. ID EX MEM WB
|
690 |
|
|
-- 3. ID EX MEM WB
|
691 |
|
|
-- 2. ID EX MEM WB
|
692 |
|
|
-- 1. ID EX MEM WB
|
693 |
|
|
-- /\
|
694 |
|
|
-- ||
|
695 |
|
|
--
|
696 |
|
|
-- data_stall: 1 + 2 + 3 remain in the corresponding stages
|
697 |
|
|
-- unit_stall: 1 + 2 remain in the corresponding stages
|
698 |
|
|
-- ex_stall: 1 remain for 1 clock cycle in the ID stage
|
699 |
|
|
-- prog_stall: 1 remain in the ID stage
|
700 |
|
|
-- fpu_stall: 1 remain for 1 or 2 clock cycles in the ID stage
|
701 |
|
|
--
|
702 |
|
|
-- DETECTION:
|
703 |
|
|
--
|
704 |
|
|
-- prog_stall, data_stall: from memory
|
705 |
|
|
-- unit_stall : from subunits
|
706 |
|
|
-- ex_stall : destination address evaluation
|
707 |
|
|
-- fpu_stall : LWC1 command
|
708 |
|
|
--
|
709 |
|
|
stall_ex_possible <= '1' when reg_ex_wb_sel = WB_MEMORY else '0'; -- previous command with memory access in execute stage
|
710 |
|
|
stall_ex_detect <= stall_ex_possible and (forward_flags.ex.rs or forward_flags.ex.rt); -- fire only if stall possible
|
711 |
|
|
|
712 |
|
|
stall_unit_detect <= (flag_mult_unit and unit_busy.mult) or (flag_fpu_unit and unit_busy.fpu);-- current command accesses to busy unit
|
713 |
|
|
|
714 |
|
|
stall_fpu_detect <= flag_fpu_stall and (reg_ex_fpu_mem or reg_mem_fpu_mem); -- current command is FPU command and FPU to mem came previously
|
715 |
|
|
|
716 |
|
|
--
|
717 |
|
|
-- INTERN STALL
|
718 |
|
|
--
|
719 |
|
|
i_stall <= data_stall -- data cache stalls
|
720 |
|
|
or prog_stall -- instruction cache stalls
|
721 |
|
|
or stall_ex_detect -- data conflict with previous command
|
722 |
|
|
or stall_unit_detect -- a unit is busy
|
723 |
|
|
or stall_fpu_detect; -- fpu memory command
|
724 |
|
|
|
725 |
|
|
--
|
726 |
|
|
-- for DATAPATH stage registers control
|
727 |
|
|
--
|
728 |
|
|
stall_src.pc <= i_stall;
|
729 |
|
|
stall_src.data <= data_stall;
|
730 |
|
|
stall_src.unit <= stall_unit_detect;
|
731 |
|
|
|
732 |
|
|
-- --------------------------------------------------------------------------
|
733 |
|
|
-- ____ _____ _ _ _____ _ _
|
734 |
|
|
-- | _ \| __ \ /\ | \ | |/ ____| | | |
|
735 |
|
|
-- | |_) | |__) | / \ | \| | | | |__| |
|
736 |
|
|
-- | _ <| _ / / /\ \ | . ` | | | __ |
|
737 |
|
|
-- | |_) | | \ \ / ____ \| |\ | |____| | | |
|
738 |
|
|
-- |____/|_| \_\/_/ \_\_| \_|\_____|_| |_|
|
739 |
|
|
-- --------------------------------------------------------------------------
|
740 |
|
|
--
|
741 |
|
|
-- PROVIDE PC FUNCTION AND REGISTER BANK WRITE ADDRESS
|
742 |
|
|
--
|
743 |
|
|
--
|
744 |
|
|
-- FPU branch evaluation
|
745 |
|
|
--
|
746 |
|
|
-- tf field indicates branch reference (true or false)
|
747 |
|
|
-- this field should be equal with FPU flag cc (xor)
|
748 |
|
|
-- if yes branch should be taken for appropriate command
|
749 |
|
|
--
|
750 |
|
|
fpu_branch_true <= flag_fpu_branch and (not (fpu_cc xor i_fpu_tf_dec));
|
751 |
|
|
|
752 |
|
|
--
|
753 |
|
|
-- overall branch evaluation
|
754 |
|
|
--
|
755 |
|
|
branch_true <= reg_flag_branch and ( comp_out or reg_ex_fpu_branch );
|
756 |
|
|
|
757 |
|
|
--
|
758 |
|
|
-- branch process
|
759 |
|
|
--
|
760 |
|
|
jump_branch_process:
|
761 |
|
|
process( reg_ex_unit_ctrl.pc_func, reg_ex_rb.rd,
|
762 |
|
|
branch_true,
|
763 |
|
|
reg_ex_pc_store)
|
764 |
|
|
begin
|
765 |
|
|
|
766 |
|
|
ex_pc_func <= reg_ex_unit_ctrl.pc_func; -- DEFAULT: decoded pc function
|
767 |
|
|
i_ex_rd <= reg_ex_rb.rd; -- DEFAULT: decoded register bank address
|
768 |
|
|
|
769 |
|
|
-- ---------- COMPARATOR OUTPUT -----------------
|
770 |
|
|
if branch_true = '1' then -- if branch should be taken
|
771 |
|
|
ex_pc_func <= PLASMA_PC_BRANCH; -- PC should take calculated/immediate value
|
772 |
|
|
-- ---------- PC STORE COMMAND ------------------
|
773 |
|
|
if reg_ex_pc_store = '1' then -- if pc value should be stored
|
774 |
|
|
i_ex_rd <= MIPS_R_RA; -- set register bank write address to MIPS_RA
|
775 |
|
|
end if;
|
776 |
|
|
|
777 |
|
|
end if;
|
778 |
|
|
end process;
|
779 |
|
|
|
780 |
|
|
-- --------------------------------------------------------------------------
|
781 |
|
|
-- _____ _____ _____ ______ _ _____ _ _ ______
|
782 |
|
|
-- | __ \_ _| __ \| ____| | |_ _| \ | | ____|
|
783 |
|
|
-- | |__) || | | |__) | |__ | | | | | \| | |__
|
784 |
|
|
-- | ___/ | | | ___/| __| | | | | | . ` | __|
|
785 |
|
|
-- | | _| |_| | | |____| |____ _| |_| |\ | |____
|
786 |
|
|
-- |_| |_____|_| |______|______|_____|_| \_|______|
|
787 |
|
|
-- --------------------------------------------------------------------------
|
788 |
|
|
--
|
789 |
|
|
-- PROVIDE PIPELINE REGISTERS
|
790 |
|
|
--
|
791 |
|
|
pipeline_regs:
|
792 |
|
|
process( control.clk )
|
793 |
|
|
begin
|
794 |
|
|
if rising_edge( control.clk ) then
|
795 |
|
|
if control.rst = '1' then -- << RESET
|
796 |
|
|
-- ############ << EXECUTION STAGE >> #################################
|
797 |
|
|
reg_ex_unit_ctrl <= (PLASMA_PC_INC, FUNC_INIT, SHIFT_INIT, FUNC_INIT, COMP_INIT );
|
798 |
|
|
reg_ex_mem_func <= FUNC_INIT;
|
799 |
|
|
|
800 |
|
|
reg_ex_src_out_sel <= SRC_OUT_ALU;
|
801 |
|
|
reg_ex_wb_sel <= WB_OP_UNIT;
|
802 |
|
|
|
803 |
|
|
reg_ex_rb <= ('0', MIPS_R_ZERO);
|
804 |
|
|
reg_ex_fpu_rb <= ('0', MIPS_R_ZERO);
|
805 |
|
|
|
806 |
|
|
reg_ex_pc_store <= '0';
|
807 |
|
|
reg_flag_branch <= '0';
|
808 |
|
|
reg_ex_fpu_branch <= '0';
|
809 |
|
|
reg_ex_fpu_mem <= '0';
|
810 |
|
|
|
811 |
|
|
-- ############ << MEMORY STAGE >> ####################################
|
812 |
|
|
reg_mem_mem_func <= FUNC_INIT;
|
813 |
|
|
|
814 |
|
|
reg_mem_wb_sel <= WB_OP_UNIT;
|
815 |
|
|
|
816 |
|
|
reg_mem_rb <= ('0', MIPS_R_ZERO);
|
817 |
|
|
reg_mem_fpu_rb <= ('0', MIPS_R_ZERO);
|
818 |
|
|
|
819 |
|
|
reg_mem_fpu_mem <= '0';
|
820 |
|
|
|
821 |
|
|
-- ############ << WRITE BACK STAGE >> ################################
|
822 |
|
|
reg_wb_rb <= ('0', MIPS_R_ZERO);
|
823 |
|
|
|
824 |
|
|
else -- << RISING_EDGE( CLK )
|
825 |
|
|
-- ############ << EXECUTION STAGE >> #################################
|
826 |
|
|
if i_stall = '0' then
|
827 |
|
|
reg_ex_unit_ctrl <= i_unit_ctrl;
|
828 |
|
|
reg_ex_mem_func <= i_mem_func;
|
829 |
|
|
|
830 |
|
|
reg_ex_src_out_sel <= i_src_out_select;
|
831 |
|
|
reg_ex_wb_sel <= i_wb_select;
|
832 |
|
|
|
833 |
|
|
reg_ex_rb <= (i_reg_addr.we, i_reg_addr.rd);
|
834 |
|
|
reg_ex_fpu_rb <= (i_fpu_reg_addr.we, i_fpu_reg_addr.rd);
|
835 |
|
|
|
836 |
|
|
reg_ex_pc_store <= flag_pc_store;
|
837 |
|
|
reg_flag_branch <= flag_branch;
|
838 |
|
|
reg_ex_fpu_branch <= fpu_branch_true;
|
839 |
|
|
end if;
|
840 |
|
|
|
841 |
|
|
if data_stall = '0' then -- FPU stall should not stop this
|
842 |
|
|
reg_ex_fpu_mem <= flag_fpu_mem;
|
843 |
|
|
end if;
|
844 |
|
|
|
845 |
|
|
-- ############ << MEMORY STAGE >> ####################################
|
846 |
|
|
if (data_stall = '0') and
|
847 |
|
|
(stall_unit_detect = '0') then
|
848 |
|
|
reg_mem_mem_func <= reg_ex_mem_func;
|
849 |
|
|
reg_mem_wb_sel <= reg_ex_wb_sel;
|
850 |
|
|
|
851 |
|
|
reg_mem_rb <= (reg_ex_rb.we, i_ex_rd);
|
852 |
|
|
reg_mem_fpu_rb <= reg_ex_fpu_rb;
|
853 |
|
|
reg_mem_fpu_mem <= reg_ex_fpu_mem;
|
854 |
|
|
end if;
|
855 |
|
|
|
856 |
|
|
-- ############ << WRITE BACK STAGE >> ################################
|
857 |
|
|
if data_stall = '0' then
|
858 |
|
|
reg_wb_rb <= reg_mem_rb;
|
859 |
|
|
end if;
|
860 |
|
|
|
861 |
|
|
end if;
|
862 |
|
|
end if;
|
863 |
|
|
end process;
|
864 |
|
|
|
865 |
|
|
-- --------------------------------------------------------------------------
|
866 |
|
|
-- ____ _ _ _______ _____ _ _ _______ _____
|
867 |
|
|
-- / __ \| | | |__ __| __ \| | | |__ __/ ____|
|
868 |
|
|
-- | | | | | | | | | | |__) | | | | | | | (___
|
869 |
|
|
-- | | | | | | | | | | ___/| | | | | | \___ \
|
870 |
|
|
-- | |__| | |__| | | | | | | |__| | | | ____) |
|
871 |
|
|
-- \____/ \____/ |_| |_| \____/ |_| |_____/
|
872 |
|
|
-- --------------------------------------------------------------------------
|
873 |
|
|
-- _ ___ ____ ____ ____ ___ ____
|
874 |
|
|
-- | . | \ |___ | | | | \ |___
|
875 |
|
|
-- | . |__/ |___ |___ |__| |__/ |___
|
876 |
|
|
--
|
877 |
|
|
-- DECODE STAGE OUTPUTS
|
878 |
|
|
--
|
879 |
|
|
reg_addr.rs <= i_reg_addr.rs;
|
880 |
|
|
reg_addr.rt <= i_reg_addr.rt;
|
881 |
|
|
|
882 |
|
|
fpu_reg_addr.rs <= i_fpu_reg_addr.rs;
|
883 |
|
|
fpu_reg_addr.rt <= i_fpu_reg_addr.rt;
|
884 |
|
|
|
885 |
|
|
fpu_reg_addr.we <= i_fpu_reg_addr.we and (not i_stall)
|
886 |
|
|
when reg_mem_fpu_mem = '0' else '1';
|
887 |
|
|
fpu_reg_addr.rd <= i_fpu_reg_addr.rd when reg_mem_fpu_mem = '0' else reg_mem_fpu_rb.rd;
|
888 |
|
|
|
889 |
|
|
fpu_ctrl.mode <= i_fpu_mode when reg_mem_fpu_mem = '0' else FPU_MODE_FGR;
|
890 |
|
|
mux_fpu.fpu_mem <= FPU_DATA_INTERN when reg_mem_fpu_mem = '0' else FPU_DATA_CORE;
|
891 |
|
|
|
892 |
|
|
-- _ _ ____ _ _ ____ ____ _ _ ___ ____
|
893 |
|
|
-- | | . |___ \/ |___ | | | | |___
|
894 |
|
|
-- | | . |___ _/\_ |___ |___ |__| | |___
|
895 |
|
|
--
|
896 |
|
|
-- EXECUTE STAGE OUTPUTS
|
897 |
|
|
--
|
898 |
|
|
unit_ctrl <= (ex_pc_func, reg_ex_unit_ctrl.alu_func, reg_ex_unit_ctrl.shift_func,
|
899 |
|
|
reg_ex_unit_ctrl.mult_func, reg_ex_unit_ctrl.comp_func);
|
900 |
|
|
|
901 |
|
|
--
|
902 |
|
|
-- MUX CONTROL
|
903 |
|
|
--
|
904 |
|
|
mux_ctrl.src_out <= reg_ex_src_out_sel; -- operation unit output mux control
|
905 |
|
|
|
906 |
|
|
|
907 |
|
|
-- _ _ _ _ _ ____ _ _ ____ ____ _ _
|
908 |
|
|
-- | | | . |\/| |___ |\/| | | |__/ \_/
|
909 |
|
|
-- | | | . | | |___ | | |__| | \ |
|
910 |
|
|
--
|
911 |
|
|
-- MEMORY STAGE OUTPUTS
|
912 |
|
|
--
|
913 |
|
|
mem_func <= reg_mem_mem_func; -- memory access function
|
914 |
|
|
|
915 |
|
|
mux_ctrl.wb <= reg_mem_wb_sel; -- memory output mux control
|
916 |
|
|
|
917 |
|
|
-- _ _ _ _ _ _ ____ _ ___ ____ ___ ____ ____ _ _
|
918 |
|
|
-- | | | . | | | |__/ | | |___ |__] |__| | |_/
|
919 |
|
|
-- | \/ . |_|_| | \ | | |___ |__] | | |___ | \_
|
920 |
|
|
--
|
921 |
|
|
-- WRITE BACK STAGE OUTPUTS
|
922 |
|
|
--
|
923 |
|
|
reg_addr.rd <= reg_wb_rb.rd; -- register bank write address
|
924 |
|
|
reg_addr.we <= reg_wb_rb.we; -- register bank write enable
|
925 |
|
|
|
926 |
|
|
end architecture structure_plasma_control_MIPSI_FPU;
|