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 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 |
|
|
unit_busy : in t_unit_busy; -- busy flags of units
|
59 |
|
|
-- register bank control
|
60 |
|
|
reg_addr : out t_reg_addr; -- register bank
|
61 |
|
|
mux_ctrl : out t_plasma_mux_ctrl; -- datapath muxes
|
62 |
|
|
stall_src : out t_stall_source; -- control registers of datapath
|
63 |
|
|
unit_ctrl : out t_plasma_subunits_ctrl;
|
64 |
|
|
-- memory access control
|
65 |
|
|
mem_func : out t_mips_opcode
|
66 |
|
|
);
|
67 |
|
|
end entity plasma_control_MIPSI;
|
68 |
|
|
--
|
69 |
|
|
architecture structure_plasma_control_MIPSI of plasma_control_MIPSI is
|
70 |
|
|
|
71 |
|
|
-- -----------------------------------------------------
|
72 |
|
|
-- ___ ____ ____ ____ ___ ____ ____
|
73 |
|
|
-- | \ |___ | | | | \ |___ |__/
|
74 |
|
|
-- |__/ |___ |___ |__| |__/ |___ | \
|
75 |
|
|
-- -----------------------------------------------------
|
76 |
|
|
-- ---------- 1. STAGE: FETCH AND DECODE ---------------
|
77 |
|
|
signal instr_dec : t_plasma_word;
|
78 |
|
|
|
79 |
|
|
--
|
80 |
|
|
-- operation decode
|
81 |
|
|
--
|
82 |
|
|
alias i_opcode_dec : t_mips_opcode is instr_dec(31 downto 26);
|
83 |
|
|
alias i_format_dec : t_mips_format is instr_dec(20 downto 16);
|
84 |
|
|
alias i_func_dec : t_mips_function is instr_dec( 5 downto 0);
|
85 |
|
|
|
86 |
|
|
--
|
87 |
|
|
-- register addresses
|
88 |
|
|
--
|
89 |
|
|
alias i_rs_dec : t_mips_reg_addr is instr_dec(25 downto 21);
|
90 |
|
|
alias i_rt_dec : t_mips_reg_addr is instr_dec(20 downto 16);
|
91 |
|
|
alias i_rd_dec : t_mips_reg_addr is instr_dec(15 downto 11);
|
92 |
|
|
|
93 |
|
|
--
|
94 |
|
|
-- operation units control
|
95 |
|
|
--
|
96 |
|
|
signal i_unit_ctrl : t_plasma_subunits_ctrl;
|
97 |
|
|
signal i_mem_func : t_mips_opcode;
|
98 |
|
|
|
99 |
|
|
constant FUNC_INIT : t_mips_opcode := (others => '0'); -- do nothing
|
100 |
|
|
constant SHIFT_INIT : t_mips_opcode := b"10_0000";
|
101 |
|
|
constant COMP_INIT : t_mips_opcode := b"01_1000";
|
102 |
|
|
|
103 |
|
|
--
|
104 |
|
|
-- pipelined mux control
|
105 |
|
|
--
|
106 |
|
|
signal i_src_out_select : t_src_out_select;
|
107 |
|
|
signal i_wb_select : t_wb_select;
|
108 |
|
|
|
109 |
|
|
--
|
110 |
|
|
-- register bank access
|
111 |
|
|
--
|
112 |
|
|
signal i_reg_addr : t_reg_addr;
|
113 |
|
|
|
114 |
|
|
--
|
115 |
|
|
-- intern flags
|
116 |
|
|
--
|
117 |
|
|
signal flag_pc_store : std_logic; -- store pc value
|
118 |
|
|
signal flag_branch : std_logic; -- branch command
|
119 |
|
|
|
120 |
|
|
signal flag_unit_stall : std_logic; -- indicates unit stall
|
121 |
|
|
|
122 |
|
|
-- ---------- 2. STAGE: EXECUTE ------------------------
|
123 |
|
|
--
|
124 |
|
|
-- pipelined register bank access type
|
125 |
|
|
--
|
126 |
|
|
type t_reg_bank_access is
|
127 |
|
|
record
|
128 |
|
|
we : std_logic;
|
129 |
|
|
rd : t_mips_reg_addr;
|
130 |
|
|
end record;
|
131 |
|
|
|
132 |
|
|
--
|
133 |
|
|
-- unit control
|
134 |
|
|
--
|
135 |
|
|
signal ex_pc_func : t_pc_function; -- pc after branch evaluation
|
136 |
|
|
signal i_ex_rd : t_mips_reg_addr; -- rd after branch evaluation
|
137 |
|
|
|
138 |
|
|
signal reg_ex_unit_ctrl : t_plasma_subunits_ctrl;
|
139 |
|
|
signal reg_ex_mem_func : t_mips_opcode;
|
140 |
|
|
|
141 |
|
|
--
|
142 |
|
|
-- mux control
|
143 |
|
|
--
|
144 |
|
|
signal reg_ex_src_out_sel : t_src_out_select;
|
145 |
|
|
signal reg_ex_wb_sel : t_wb_select;
|
146 |
|
|
|
147 |
|
|
--
|
148 |
|
|
-- register bank access
|
149 |
|
|
--
|
150 |
|
|
signal reg_ex_rb : t_reg_bank_access;
|
151 |
|
|
|
152 |
|
|
--
|
153 |
|
|
-- intern flags
|
154 |
|
|
--
|
155 |
|
|
signal reg_ex_pc_store : std_logic;
|
156 |
|
|
signal reg_flag_branch : std_logic;
|
157 |
|
|
|
158 |
|
|
-- ---------- 3. STAGE: MEMORY ACCESS ------------------
|
159 |
|
|
--
|
160 |
|
|
-- unit control
|
161 |
|
|
--
|
162 |
|
|
signal reg_mem_mem_func : t_mips_opcode;
|
163 |
|
|
|
164 |
|
|
--
|
165 |
|
|
-- mux control
|
166 |
|
|
--
|
167 |
|
|
signal reg_mem_wb_sel : t_wb_select;
|
168 |
|
|
|
169 |
|
|
--
|
170 |
|
|
-- register bank access
|
171 |
|
|
--
|
172 |
|
|
signal reg_mem_rb : t_reg_bank_access;
|
173 |
|
|
|
174 |
|
|
-- ---------- 4. STAGE: WRITE BACK ---------------------
|
175 |
|
|
--
|
176 |
|
|
-- register bank access
|
177 |
|
|
--
|
178 |
|
|
signal reg_wb_rb : t_reg_bank_access;
|
179 |
|
|
|
180 |
|
|
-- ---------- FORWARDING -------------------------------
|
181 |
|
|
type t_forward_stage_flag is
|
182 |
|
|
record
|
183 |
|
|
rd_zero : std_logic;
|
184 |
|
|
rs : std_logic;
|
185 |
|
|
rt : std_logic;
|
186 |
|
|
end record;
|
187 |
|
|
|
188 |
|
|
type t_forward_flag is
|
189 |
|
|
record
|
190 |
|
|
ex : t_forward_stage_flag;
|
191 |
|
|
mem : t_forward_stage_flag;
|
192 |
|
|
wb : t_forward_stage_flag;
|
193 |
|
|
end record;
|
194 |
|
|
|
195 |
|
|
signal forward_flags : t_forward_flag;
|
196 |
|
|
|
197 |
|
|
-- ---------- STALL LOGIC ------------------------------
|
198 |
|
|
signal stall_ex_possible : std_logic; -- memory access in the previous command
|
199 |
|
|
signal stall_ex_detect : std_logic; -- stall detection
|
200 |
|
|
signal stall_unit_detect : std_logic; -- a unit causes stall
|
201 |
|
|
|
202 |
|
|
signal i_stall : std_logic; -- intern stall flag
|
203 |
|
|
|
204 |
|
|
-- ---------- BRANCH -----------------------------------
|
205 |
|
|
signal branch_true : std_logic; -- branch should be taken
|
206 |
|
|
|
207 |
|
|
-- ---------- DEBUGGING --------------------------------
|
208 |
|
|
--
|
209 |
|
|
begin
|
210 |
|
|
|
211 |
|
|
-- --------------------------------------------------------------------------
|
212 |
|
|
-- _____ ______ _____ ____ _____ ______ _____
|
213 |
|
|
-- | __ \| ____/ ____/ __ \| __ \| ____| __ \
|
214 |
|
|
-- | | | | |__ | | | | | | | | | |__ | |__) |
|
215 |
|
|
-- | | | | __|| | | | | | | | | __| | _ /
|
216 |
|
|
-- | |__| | |___| |___| |__| | |__| | |____| | \ \
|
217 |
|
|
-- |_____/|______\_____\____/|_____/|______|_| \_\
|
218 |
|
|
-- --------------------------------------------------------------------------
|
219 |
|
|
instr_dec <= instr_in;
|
220 |
|
|
|
221 |
|
|
-- _ ____ ____ ___ ____ _ _ ____ _ _ ___ ___ ____ ____ ____ ___ ____
|
222 |
|
|
-- | . |___ |___ | | |__| |__| |\ | | \ | \ |___ | | | | \ |___
|
223 |
|
|
-- | . | |___ | |___ | | | | | \| |__/ |__/ |___ |___ |__| |__/ |___
|
224 |
|
|
-- --------------------------------------------------------------------------
|
225 |
|
|
--
|
226 |
|
|
-- UNIT and MUX control
|
227 |
|
|
-- REGISTER BANK REGULAR ADDRESSES
|
228 |
|
|
--
|
229 |
|
|
-- ___ ____ ____ ____ ___ ____
|
230 |
|
|
-- | \ |___ | | | | \ |___
|
231 |
|
|
-- |__/ |___ |___ |__| |__/ |___
|
232 |
|
|
decode_process:
|
233 |
|
|
process( instr_dec )
|
234 |
|
|
variable clear_rb_access : boolean := FALSE;
|
235 |
|
|
begin
|
236 |
|
|
-- -------------------------------------------------------------------
|
237 |
|
|
-- ___ ____ ____ ____ _ _ _ ___ _ _ ____ _ _ _ ____ ____
|
238 |
|
|
-- | \ |___ |___ |__| | | | | | | |__| | | | |___ [__
|
239 |
|
|
-- |__/ |___ | | | |__| |___ | \/ | | |___ |__| |___ ___]
|
240 |
|
|
-- -------------------------------------------------------------------
|
241 |
|
|
--
|
242 |
|
|
-- SUBCOMPONENTS CONTROL
|
243 |
|
|
--
|
244 |
|
|
i_unit_ctrl <= (pc_func => PLASMA_PC_INC,
|
245 |
|
|
alu_func => i_opcode_dec,
|
246 |
|
|
shift_func => SHIFT_INIT,
|
247 |
|
|
mult_func => FUNC_INIT,
|
248 |
|
|
comp_func => COMP_INIT);
|
249 |
|
|
|
250 |
|
|
-- memory control
|
251 |
|
|
i_mem_func <= i_opcode_dec; -- pass opcode
|
252 |
|
|
|
253 |
|
|
--
|
254 |
|
|
-- MUX CONTROL
|
255 |
|
|
--
|
256 |
|
|
-- source mux control:
|
257 |
|
|
mux_ctrl.src_imm <= IMM_SIGN; -- IMMEDIATE = SIGN EXTENDED
|
258 |
|
|
mux_ctrl.src_b_imm <= B_IMM_ON; -- PASS IMMEDIATE VALUE FOR 2. source
|
259 |
|
|
|
260 |
|
|
-- units mux control
|
261 |
|
|
i_src_out_select <= SRC_OUT_ALU; -- ALU output
|
262 |
|
|
|
263 |
|
|
-- write back control
|
264 |
|
|
i_wb_select <= WB_OP_UNIT; -- unit output
|
265 |
|
|
|
266 |
|
|
--
|
267 |
|
|
-- REBULAR REGISTER BANK
|
268 |
|
|
--
|
269 |
|
|
i_reg_addr <= (we => '1', -- write access enable
|
270 |
|
|
rs => i_rs_dec, -- 1. source
|
271 |
|
|
rt => i_rt_dec, -- target
|
272 |
|
|
rd => i_rt_dec); -- destination
|
273 |
|
|
|
274 |
|
|
clear_rb_access := FALSE; -- access to regular register bank
|
275 |
|
|
|
276 |
|
|
--
|
277 |
|
|
-- INTERN FLAGS
|
278 |
|
|
--
|
279 |
|
|
flag_pc_store <= '0'; -- store next pc value by linked jumps, disabled
|
280 |
|
|
flag_branch <= '0'; -- no branch command
|
281 |
|
|
|
282 |
|
|
flag_unit_stall <= '0'; -- unit stall (mult or FPU)
|
283 |
|
|
|
284 |
|
|
--
|
285 |
|
|
-- DEBUGGING
|
286 |
|
|
--
|
287 |
|
|
--synthesis translate_off
|
288 |
|
|
i_sim_control.sim_message(core_idx) <= '0';
|
289 |
|
|
i_sim_control.sim_stop <= '0';
|
290 |
|
|
i_sim_control.print_message <= '0';
|
291 |
|
|
i_sim_control.sim_finish <= '0';
|
292 |
|
|
i_sim_control.track_en(core_idx) <= '0';
|
293 |
|
|
i_sim_control.track_mark <= '0';
|
294 |
|
|
--synthesis translate_on
|
295 |
|
|
|
296 |
|
|
-- ------------ OPERATION DECODE -------------------------------------------------------------------
|
297 |
|
|
case i_opcode_dec is
|
298 |
|
|
-- ----------- REGISTER FORMAT -------------------------------------------------------------------
|
299 |
|
|
when MIPS_OPCODE_REG =>
|
300 |
|
|
|
301 |
|
|
mux_ctrl.src_b_imm <= B_IMM_OF; -- DEFAULT: cut immediate value passing
|
302 |
|
|
i_reg_addr.rd <= i_rd_dec; -- DEFAULT: destination is on rd field
|
303 |
|
|
|
304 |
|
|
case i_func_dec is
|
305 |
|
|
-- ------------------------------------ SHIFTER ----------------------------------------------
|
306 |
|
|
when MIPS_FUNC_SLL |
|
307 |
|
|
MIPS_FUNC_SRL |
|
308 |
|
|
MIPS_FUNC_SRA => i_unit_ctrl.shift_func <= i_func_dec; -- pass function
|
309 |
|
|
|
310 |
|
|
mux_ctrl.src_imm <= IMM_SHAMT; -- shift amount for immediate mux
|
311 |
|
|
mux_ctrl.src_b_imm <= B_IMM_ON; -- pass immediate value
|
312 |
|
|
|
313 |
|
|
i_src_out_select <= SRC_OUT_SHIFT; -- output from shifter
|
314 |
|
|
|
315 |
|
|
i_reg_addr.rs <= i_rt_dec; -- source is on rt field
|
316 |
|
|
|
317 |
|
|
when MIPS_FUNC_SLLV |
|
318 |
|
|
MIPS_FUNC_SRLV |
|
319 |
|
|
MIPS_FUNC_SRAV => i_unit_ctrl.shift_func <= i_func_dec; -- pass function
|
320 |
|
|
|
321 |
|
|
i_src_out_select <= SRC_OUT_SHIFT; -- output from shifter
|
322 |
|
|
|
323 |
|
|
i_reg_addr.rs <= i_rt_dec; -- 1. and 2. source are switched
|
324 |
|
|
i_reg_addr.rt <= i_rs_dec;
|
325 |
|
|
|
326 |
|
|
-- ------------------------------------ JUMP REGISTER ----------------------------------------
|
327 |
|
|
when MIPS_FUNC_JR => i_unit_ctrl.pc_func <= PLASMA_PC_REG; -- pc operation code
|
328 |
|
|
|
329 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
330 |
|
|
|
331 |
|
|
when MIPS_FUNC_JALR => i_unit_ctrl.pc_func <= PLASMA_PC_REG; -- pc operation code
|
332 |
|
|
i_src_out_select <= SRC_OUT_PC; -- output source select
|
333 |
|
|
|
334 |
|
|
i_reg_addr.rd <= MIPS_R_RA; -- return address
|
335 |
|
|
|
336 |
|
|
-- ------------------------------------ INTERRUPTS -------------------------------------------
|
337 |
|
|
--synthesis translate_off
|
338 |
|
|
when MIPS_FUNC_SYSCALL =>
|
339 |
|
|
case( instr_dec(10 downto 6) ) is
|
340 |
|
|
when b"00000" => i_sim_control.sim_message(core_idx) <= '1';
|
341 |
|
|
when b"00001" => i_sim_control.sim_stop <= '1';
|
342 |
|
|
when b"00010" => i_sim_control.print_message <= '1';
|
343 |
|
|
when b"00011" => i_sim_control.sim_finish <= '1';
|
344 |
|
|
when b"00100" => i_sim_control.track_en(core_idx) <= '1';
|
345 |
|
|
when b"00101" => i_sim_control.track_mark <= '1';
|
346 |
|
|
when others =>
|
347 |
|
|
end case;
|
348 |
|
|
--synthesis translate_on
|
349 |
|
|
-- when MIPS_FUNC_BREAK =>
|
350 |
|
|
|
351 |
|
|
-- ------------------------------------ MULTIPLICATOR ----------------------------------------
|
352 |
|
|
when MIPS_FUNC_MFHI |
|
353 |
|
|
MIPS_FUNC_MFLO => i_unit_ctrl.mult_func <= i_func_dec; -- pass function
|
354 |
|
|
|
355 |
|
|
i_src_out_select <= SRC_OUT_MULT; -- output from mult
|
356 |
|
|
|
357 |
|
|
flag_unit_stall <= '1'; -- possible unit stall
|
358 |
|
|
|
359 |
|
|
when MIPS_FUNC_MTHI |
|
360 |
|
|
MIPS_FUNC_MTLO |
|
361 |
|
|
MIPS_FUNC_MULT |
|
362 |
|
|
MIPS_FUNC_MULTU |
|
363 |
|
|
MIPS_FUNC_DIV |
|
364 |
|
|
MIPS_FUNC_DIVU => i_unit_ctrl.mult_func <= i_func_dec; -- pass function
|
365 |
|
|
|
366 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
367 |
|
|
|
368 |
|
|
flag_unit_stall <= '1'; -- possible unit stall
|
369 |
|
|
|
370 |
|
|
-- ------------------------------------ ALU --------------------------------------------------
|
371 |
|
|
when MIPS_FUNC_ADD |
|
372 |
|
|
MIPS_FUNC_ADDU |
|
373 |
|
|
MIPS_FUNC_SUB |
|
374 |
|
|
MIPS_FUNC_SUBU |
|
375 |
|
|
MIPS_FUNC_AND |
|
376 |
|
|
MIPS_FUNC_OR |
|
377 |
|
|
MIPS_FUNC_XOR |
|
378 |
|
|
MIPS_FUNC_NOR |
|
379 |
|
|
MIPS_FUNC_SLT |
|
380 |
|
|
MIPS_FUNC_SLTU => i_unit_ctrl.alu_func <= i_func_dec; -- pass function to ALU -- pass command to ALU
|
381 |
|
|
|
382 |
|
|
when others =>
|
383 |
|
|
--synthesis translate_off
|
384 |
|
|
report "WARNING:Unknown function code " & sv2string( i_func_dec );
|
385 |
|
|
--synthesis translate_on
|
386 |
|
|
end case;
|
387 |
|
|
|
388 |
|
|
-- ------------------------------------ REGIMM ---------------------------------------------------
|
389 |
|
|
when MIPS_OPCODE_REGIMM =>
|
390 |
|
|
|
391 |
|
|
i_unit_ctrl.comp_func <= '0' & i_format_dec; -- pass format
|
392 |
|
|
|
393 |
|
|
mux_ctrl.src_imm <= IMM_BRANCH; -- pass branch immediate value
|
394 |
|
|
|
395 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
396 |
|
|
|
397 |
|
|
flag_branch <= '1'; -- set branch command
|
398 |
|
|
|
399 |
|
|
case i_format_dec is
|
400 |
|
|
when MIPS_OPCODE_BLTZ |
|
401 |
|
|
MIPS_OPCODE_BGEZ => -- pass opcode
|
402 |
|
|
|
403 |
|
|
when MIPS_OPCODE_BLTZAL |
|
404 |
|
|
MIPS_OPCODE_BGEZAL => i_src_out_select <= SRC_OUT_PC; -- pc value as output source
|
405 |
|
|
|
406 |
|
|
flag_pc_store <= '1'; -- set pc store flag
|
407 |
|
|
|
408 |
|
|
when others =>
|
409 |
|
|
-- synthesis translate_off
|
410 |
|
|
report "WARNING:Unknown format code " & sv2string( i_format_dec );
|
411 |
|
|
-- synthesis translate_on
|
412 |
|
|
end case;
|
413 |
|
|
|
414 |
|
|
when MIPS_OPCODE_BEQ |
|
415 |
|
|
MIPS_OPCODE_BNE => i_unit_ctrl.comp_func <= i_opcode_dec; -- pass function
|
416 |
|
|
|
417 |
|
|
mux_ctrl.src_b_imm <= B_IMM_OF; -- disable immediate pass
|
418 |
|
|
mux_ctrl.src_imm <= IMM_BRANCH; -- pass branch immediate
|
419 |
|
|
|
420 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
421 |
|
|
|
422 |
|
|
flag_branch <= '1'; -- set branch command
|
423 |
|
|
|
424 |
|
|
when MIPS_OPCODE_BLEZ |
|
425 |
|
|
MIPS_OPCODE_BGTZ => i_unit_ctrl.comp_func <= i_opcode_dec; -- pass function
|
426 |
|
|
|
427 |
|
|
mux_ctrl.src_imm <= IMM_BRANCH; -- pass branch immediate
|
428 |
|
|
|
429 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
430 |
|
|
|
431 |
|
|
flag_branch <= '1'; -- set branch command
|
432 |
|
|
|
433 |
|
|
-- ------------------------------------ ALU ------------------------------------------------------
|
434 |
|
|
when MIPS_OPCODE_ADDI |
|
435 |
|
|
MIPS_OPCODE_ADDIU |
|
436 |
|
|
MIPS_OPCODE_SLTI |
|
437 |
|
|
MIPS_OPCODE_SLTIU => -- pass operation code
|
438 |
|
|
|
439 |
|
|
when MIPS_OPCODE_ANDI |
|
440 |
|
|
MIPS_OPCODE_ORI |
|
441 |
|
|
MIPS_OPCODE_XORI => mux_ctrl.src_imm <= IMM_UNSIGN; -- pass unsigned immediate
|
442 |
|
|
|
443 |
|
|
when MIPS_OPCODE_LUI => mux_ctrl.src_imm <= IMM_HIGH; -- pass shifted immediate
|
444 |
|
|
|
445 |
|
|
-- ------------------------------------ LOAD MEMORY ----------------------------------------------
|
446 |
|
|
when MIPS_OPCODE_LB |
|
447 |
|
|
MIPS_OPCODE_LH |
|
448 |
|
|
MIPS_OPCODE_LWL |
|
449 |
|
|
MIPS_OPCODE_LW |
|
450 |
|
|
-- MIPS_OPCODE_LWR | -- COMPILER BUG !!
|
451 |
|
|
MIPS_OPCODE_LBU |
|
452 |
|
|
MIPS_OPCODE_LHU => i_unit_ctrl.alu_func <= MIPS_FUNC_ADD; -- switch ALU to addition -> address calcultion
|
453 |
|
|
|
454 |
|
|
i_wb_select <= WB_MEMORY; -- pass memory data
|
455 |
|
|
|
456 |
|
|
when MIPS_OPCODE_LWR => -- DO NOTHING !!
|
457 |
|
|
|
458 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
459 |
|
|
|
460 |
|
|
-- ------------------------------------ STORE MEMORY ---------------------------------------------
|
461 |
|
|
when MIPS_OPCODE_SB |
|
462 |
|
|
MIPS_OPCODE_SH |
|
463 |
|
|
MIPS_OPCODE_SWL |
|
464 |
|
|
MIPS_OPCODE_SW |
|
465 |
|
|
MIPS_OPCODE_SWR => i_unit_ctrl.alu_func <= MIPS_FUNC_ADD; -- switch ALU to addition -> address calcultion
|
466 |
|
|
|
467 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
468 |
|
|
|
469 |
|
|
-- ------------------------------------ JUMP -----------------------------------------------------
|
470 |
|
|
when MIPS_OPCODE_J => i_unit_ctrl.pc_func <= PLASMA_PC_IMM; -- pc = long immedate
|
471 |
|
|
|
472 |
|
|
mux_ctrl.src_imm <= IMM_JUMP; -- pass long immediate
|
473 |
|
|
|
474 |
|
|
clear_rb_access := TRUE; -- no register bank access
|
475 |
|
|
|
476 |
|
|
when MIPS_OPCODE_JAL => i_unit_ctrl.pc_func <= PLASMA_PC_IMM; -- pc = long immedate
|
477 |
|
|
|
478 |
|
|
mux_ctrl.src_imm <= IMM_JUMP; -- pass long immediate
|
479 |
|
|
i_src_out_select <= SRC_OUT_PC; -- pass pc value
|
480 |
|
|
|
481 |
|
|
i_reg_addr.rd <= MIPS_R_RA; -- return address
|
482 |
|
|
|
483 |
|
|
when others =>
|
484 |
|
|
--synthesis translate_off
|
485 |
|
|
report "Unknown opcode " & sv2string( i_opcode_dec );
|
486 |
|
|
--synthesis translate_on
|
487 |
|
|
end case;
|
488 |
|
|
|
489 |
|
|
--
|
490 |
|
|
-- clear register bank access
|
491 |
|
|
--
|
492 |
|
|
if clear_rb_access then
|
493 |
|
|
i_reg_addr.we <= '0'; -- no write enable
|
494 |
|
|
i_reg_addr.rd <= MIPS_R_ZERO; -- for forward logic
|
495 |
|
|
end if;
|
496 |
|
|
end process;
|
497 |
|
|
-- --------------------------------------------------------------------------
|
498 |
|
|
|
499 |
|
|
-- ____ ____ ____ _ _ _ ____ ____ ___ _ _ _ ____
|
500 |
|
|
-- |___ | | |__/ | | | |__| |__/ | \ | |\ | | __
|
501 |
|
|
-- | |__| | \ |_|_| | | | \ |__/ | | \| |__]
|
502 |
|
|
--
|
503 |
|
|
-- detect equal addresses
|
504 |
|
|
--
|
505 |
|
|
-- execution stage
|
506 |
|
|
forward_flags.ex.rd_zero <= '1' when reg_ex_rb.rd = MIPS_R_ZERO else '0';
|
507 |
|
|
forward_flags.ex.rs <= not forward_flags.ex.rd_zero when i_reg_addr.rs = reg_ex_rb.rd else '0';
|
508 |
|
|
forward_flags.ex.rt <= not forward_flags.ex.rd_zero when i_reg_addr.rt = reg_ex_rb.rd else '0';
|
509 |
|
|
|
510 |
|
|
-- memory stage
|
511 |
|
|
forward_flags.mem.rd_zero <= '1' when reg_mem_rb.rd = MIPS_R_ZERO else '0';
|
512 |
|
|
forward_flags.mem.rs <= not forward_flags.mem.rd_zero when i_reg_addr.rs = reg_mem_rb.rd else '0';
|
513 |
|
|
forward_flags.mem.rt <= not forward_flags.mem.rd_zero when i_reg_addr.rt = reg_mem_rb.rd else '0';
|
514 |
|
|
|
515 |
|
|
-- write back stage
|
516 |
|
|
forward_flags.wb.rd_zero <= '1' when reg_wb_rb.rd = MIPS_R_ZERO else '0';
|
517 |
|
|
forward_flags.wb.rs <= not forward_flags.wb.rd_zero when i_reg_addr.rs = reg_wb_rb.rd else '0';
|
518 |
|
|
forward_flags.wb.rt <= not forward_flags.wb.rd_zero when i_reg_addr.rt = reg_wb_rb.rd else '0';
|
519 |
|
|
|
520 |
|
|
--
|
521 |
|
|
-- set forwarded register bank addresses
|
522 |
|
|
--
|
523 |
|
|
forward_process:
|
524 |
|
|
process( forward_flags )
|
525 |
|
|
begin
|
526 |
|
|
--
|
527 |
|
|
-- -------- A SOURCE FORWARDING -----------------
|
528 |
|
|
--
|
529 |
|
|
if forward_flags.ex.rs = '1' then mux_ctrl.src_a <= SRC_OP_OUT;
|
530 |
|
|
elsif forward_flags.mem.rs = '1' then mux_ctrl.src_a <= SRC_MEM_OUT;
|
531 |
|
|
elsif forward_flags.wb.rs = '1' then mux_ctrl.src_a <= SRC_WB_OUT;
|
532 |
|
|
else mux_ctrl.src_a <= SRC_REG;
|
533 |
|
|
end if;
|
534 |
|
|
|
535 |
|
|
--
|
536 |
|
|
-- -------- B SOURCE FORWARDING ------------------
|
537 |
|
|
--
|
538 |
|
|
if forward_flags.ex.rt = '1' then mux_ctrl.src_b <= SRC_OP_OUT;
|
539 |
|
|
elsif forward_flags.mem.rt = '1' then mux_ctrl.src_b <= SRC_MEM_OUT;
|
540 |
|
|
elsif forward_flags.wb.rt = '1' then mux_ctrl.src_b <= SRC_WB_OUT;
|
541 |
|
|
else mux_ctrl.src_b <= SRC_REG;
|
542 |
|
|
end if;
|
543 |
|
|
end process;
|
544 |
|
|
|
545 |
|
|
-- ____ ___ ____ _ _ _ ____ ____ _ ____
|
546 |
|
|
-- [__ | |__| | | | | | | __ | |
|
547 |
|
|
-- ___] | | | |___ |___ |___ |__| |__] | |___
|
548 |
|
|
--
|
549 |
|
|
-- 4. ID EX MEM WB
|
550 |
|
|
-- 3. ID EX MEM WB
|
551 |
|
|
-- 2. ID EX MEM WB
|
552 |
|
|
-- 1. ID EX MEM WB
|
553 |
|
|
-- /\
|
554 |
|
|
-- ||
|
555 |
|
|
--
|
556 |
|
|
-- data_stall: 1 + 2 + 3 remain in the corresponding stages
|
557 |
|
|
-- unit_stall: 1 + 2 remain in the corresponding stages
|
558 |
|
|
-- ex_stall: 1 remain for 1 clock cycle in the ID stage
|
559 |
|
|
-- prog_stall: 1 remain in the ID stage
|
560 |
|
|
--
|
561 |
|
|
|
562 |
|
|
-- DETECTION:
|
563 |
|
|
--
|
564 |
|
|
-- prog_stall, data_stall: from memory
|
565 |
|
|
-- unit_stall : from subunits
|
566 |
|
|
-- ex_stall : destination address evaluation
|
567 |
|
|
--
|
568 |
|
|
stall_ex_possible <= '1' when reg_ex_wb_sel = WB_MEMORY else '0'; -- previous command with memory access in execute stage
|
569 |
|
|
stall_ex_detect <= stall_ex_possible and (forward_flags.ex.rs or forward_flags.ex.rt); -- fire only if stall possible
|
570 |
|
|
|
571 |
|
|
stall_unit_detect <= flag_unit_stall and (unit_busy.mult or unit_busy.fpu); -- current command accesses to busy unit
|
572 |
|
|
|
573 |
|
|
--
|
574 |
|
|
-- INTERN STALL
|
575 |
|
|
--
|
576 |
|
|
i_stall <= data_stall -- data cache stalls
|
577 |
|
|
or prog_stall -- instruction cache stalls
|
578 |
|
|
or stall_ex_detect -- data conflict with previous command
|
579 |
|
|
or stall_unit_detect; -- a unit is busy
|
580 |
|
|
|
581 |
|
|
--
|
582 |
|
|
-- for DATAPATH stage registers control
|
583 |
|
|
--
|
584 |
|
|
stall_src.pc <= i_stall;
|
585 |
|
|
stall_src.data <= data_stall;
|
586 |
|
|
stall_src.unit <= stall_unit_detect;
|
587 |
|
|
|
588 |
|
|
-- --------------------------------------------------------------------------
|
589 |
|
|
-- ____ _____ _ _ _____ _ _
|
590 |
|
|
-- | _ \| __ \ /\ | \ | |/ ____| | | |
|
591 |
|
|
-- | |_) | |__) | / \ | \| | | | |__| |
|
592 |
|
|
-- | _ <| _ / / /\ \ | . ` | | | __ |
|
593 |
|
|
-- | |_) | | \ \ / ____ \| |\ | |____| | | |
|
594 |
|
|
-- |____/|_| \_\/_/ \_\_| \_|\_____|_| |_|
|
595 |
|
|
-- --------------------------------------------------------------------------
|
596 |
|
|
--
|
597 |
|
|
-- PROVIDE PC FUNCTION AND REGISTER BANK WRITE ADDRESS
|
598 |
|
|
--
|
599 |
|
|
--
|
600 |
|
|
-- overall branch evaluation
|
601 |
|
|
--
|
602 |
|
|
branch_true <= reg_flag_branch and comp_out;
|
603 |
|
|
|
604 |
|
|
--
|
605 |
|
|
-- branch process
|
606 |
|
|
--
|
607 |
|
|
jump_branch_process:
|
608 |
|
|
process( reg_ex_unit_ctrl.pc_func, reg_ex_rb.rd,
|
609 |
|
|
branch_true,
|
610 |
|
|
reg_ex_pc_store)
|
611 |
|
|
begin
|
612 |
|
|
|
613 |
|
|
ex_pc_func <= reg_ex_unit_ctrl.pc_func; -- DEFAULT: decoded pc function
|
614 |
|
|
i_ex_rd <= reg_ex_rb.rd; -- DEFAULT: decoded register bank address
|
615 |
|
|
|
616 |
|
|
-- ---------- COMPARATOR OUTPUT -----------------
|
617 |
|
|
if branch_true = '1' then -- if branch should be taken
|
618 |
|
|
ex_pc_func <= PLASMA_PC_BRANCH; -- PC should take calculated/immediate value
|
619 |
|
|
-- ---------- PC STORE COMMAND ------------------
|
620 |
|
|
if reg_ex_pc_store = '1' then -- if pc value should be stored
|
621 |
|
|
i_ex_rd <= MIPS_R_RA; -- set register bank write address to MIPS_RA
|
622 |
|
|
end if;
|
623 |
|
|
|
624 |
|
|
end if;
|
625 |
|
|
end process;
|
626 |
|
|
|
627 |
|
|
-- --------------------------------------------------------------------------
|
628 |
|
|
-- _____ _____ _____ ______ _ _____ _ _ ______
|
629 |
|
|
-- | __ \_ _| __ \| ____| | |_ _| \ | | ____|
|
630 |
|
|
-- | |__) || | | |__) | |__ | | | | | \| | |__
|
631 |
|
|
-- | ___/ | | | ___/| __| | | | | | . ` | __|
|
632 |
|
|
-- | | _| |_| | | |____| |____ _| |_| |\ | |____
|
633 |
|
|
-- |_| |_____|_| |______|______|_____|_| \_|______|
|
634 |
|
|
-- --------------------------------------------------------------------------
|
635 |
|
|
--
|
636 |
|
|
-- PROVIDE PIPELINE REGISTERS
|
637 |
|
|
--
|
638 |
|
|
pipeline_regs:
|
639 |
|
|
process( control.clk )
|
640 |
|
|
begin
|
641 |
|
|
if rising_edge( control.clk ) then
|
642 |
|
|
if control.rst = '1' then -- << RESET
|
643 |
|
|
-- ############ << EXECUTION STAGE >> #################################
|
644 |
|
|
reg_ex_unit_ctrl <= (PLASMA_PC_INC, FUNC_INIT, SHIFT_INIT, FUNC_INIT, COMP_INIT );
|
645 |
|
|
reg_ex_mem_func <= FUNC_INIT;
|
646 |
|
|
|
647 |
|
|
reg_ex_src_out_sel <= SRC_OUT_ALU;
|
648 |
|
|
reg_ex_wb_sel <= WB_OP_UNIT;
|
649 |
|
|
|
650 |
|
|
reg_ex_rb <= ('0', MIPS_R_ZERO);
|
651 |
|
|
|
652 |
|
|
reg_ex_pc_store <= '0';
|
653 |
|
|
reg_flag_branch <= '0';
|
654 |
|
|
|
655 |
|
|
-- ############ << MEMORY STAGE >> ####################################
|
656 |
|
|
reg_mem_mem_func <= FUNC_INIT;
|
657 |
|
|
|
658 |
|
|
reg_mem_wb_sel <= WB_OP_UNIT;
|
659 |
|
|
|
660 |
|
|
reg_mem_rb <= ('0', MIPS_R_ZERO);
|
661 |
|
|
|
662 |
|
|
-- ############ << WRITE BACK STAGE >> ################################
|
663 |
|
|
reg_wb_rb <= ('0', MIPS_R_ZERO);
|
664 |
|
|
|
665 |
|
|
else -- << RISING_EDGE( CLK )
|
666 |
|
|
-- ############ << EXECUTION STAGE >> #################################
|
667 |
|
|
if i_stall = '0' then
|
668 |
|
|
reg_ex_unit_ctrl <= i_unit_ctrl;
|
669 |
|
|
reg_ex_mem_func <= i_mem_func;
|
670 |
|
|
|
671 |
|
|
reg_ex_src_out_sel <= i_src_out_select;
|
672 |
|
|
reg_ex_wb_sel <= i_wb_select;
|
673 |
|
|
|
674 |
|
|
reg_ex_rb <= (i_reg_addr.we, i_reg_addr.rd);
|
675 |
|
|
|
676 |
|
|
reg_ex_pc_store <= flag_pc_store;
|
677 |
|
|
reg_flag_branch <= flag_branch;
|
678 |
|
|
end if;
|
679 |
|
|
|
680 |
|
|
-- ############ << MEMORY STAGE >> ####################################
|
681 |
|
|
if (data_stall = '0') and
|
682 |
|
|
(stall_unit_detect = '0') then
|
683 |
|
|
reg_mem_mem_func <= reg_ex_mem_func;
|
684 |
|
|
reg_mem_wb_sel <= reg_ex_wb_sel;
|
685 |
|
|
|
686 |
|
|
reg_mem_rb <= (reg_ex_rb.we, i_ex_rd);
|
687 |
|
|
end if;
|
688 |
|
|
|
689 |
|
|
-- ############ << WRITE BACK STAGE >> ################################
|
690 |
|
|
if data_stall = '0' then
|
691 |
|
|
reg_wb_rb <= reg_mem_rb;
|
692 |
|
|
end if;
|
693 |
|
|
|
694 |
|
|
end if;
|
695 |
|
|
end if;
|
696 |
|
|
end process;
|
697 |
|
|
|
698 |
|
|
-- --------------------------------------------------------------------------
|
699 |
|
|
-- ____ _ _ _______ _____ _ _ _______ _____
|
700 |
|
|
-- / __ \| | | |__ __| __ \| | | |__ __/ ____|
|
701 |
|
|
-- | | | | | | | | | | |__) | | | | | | | (___
|
702 |
|
|
-- | | | | | | | | | | ___/| | | | | | \___ \
|
703 |
|
|
-- | |__| | |__| | | | | | | |__| | | | ____) |
|
704 |
|
|
-- \____/ \____/ |_| |_| \____/ |_| |_____/
|
705 |
|
|
-- --------------------------------------------------------------------------
|
706 |
|
|
-- _ ___ ____ ____ ____ ___ ____
|
707 |
|
|
-- | . | \ |___ | | | | \ |___
|
708 |
|
|
-- | . |__/ |___ |___ |__| |__/ |___
|
709 |
|
|
--
|
710 |
|
|
-- DECODE STAGE OUTPUTS
|
711 |
|
|
--
|
712 |
|
|
reg_addr.rs <= i_reg_addr.rs;
|
713 |
|
|
reg_addr.rt <= i_reg_addr.rt;
|
714 |
|
|
|
715 |
|
|
-- _ _ ____ _ _ ____ ____ _ _ ___ ____
|
716 |
|
|
-- | | . |___ \/ |___ | | | | |___
|
717 |
|
|
-- | | . |___ _/\_ |___ |___ |__| | |___
|
718 |
|
|
--
|
719 |
|
|
-- EXECUTE STAGE OUTPUTS
|
720 |
|
|
--
|
721 |
|
|
unit_ctrl <= (ex_pc_func, reg_ex_unit_ctrl.alu_func, reg_ex_unit_ctrl.shift_func,
|
722 |
|
|
reg_ex_unit_ctrl.mult_func, reg_ex_unit_ctrl.comp_func);
|
723 |
|
|
|
724 |
|
|
--
|
725 |
|
|
-- MUX CONTROL
|
726 |
|
|
--
|
727 |
|
|
mux_ctrl.src_out <= reg_ex_src_out_sel; -- operation unit output mux control
|
728 |
|
|
|
729 |
|
|
|
730 |
|
|
-- _ _ _ _ _ ____ _ _ ____ ____ _ _
|
731 |
|
|
-- | | | . |\/| |___ |\/| | | |__/ \_/
|
732 |
|
|
-- | | | . | | |___ | | |__| | \ |
|
733 |
|
|
--
|
734 |
|
|
-- MEMORY STAGE OUTPUTS
|
735 |
|
|
--
|
736 |
|
|
mem_func <= reg_mem_mem_func; -- memory access function
|
737 |
|
|
|
738 |
|
|
mux_ctrl.wb <= reg_mem_wb_sel; -- memory output mux control
|
739 |
|
|
|
740 |
|
|
-- _ _ _ _ _ _ ____ _ ___ ____ ___ ____ ____ _ _
|
741 |
|
|
-- | | | . | | | |__/ | | |___ |__] |__| | |_/
|
742 |
|
|
-- | \/ . |_|_| | \ | | |___ |__] | | |___ | \_
|
743 |
|
|
--
|
744 |
|
|
-- WRITE BACK STAGE OUTPUTS
|
745 |
|
|
--
|
746 |
|
|
reg_addr.rd <= reg_wb_rb.rd; -- register bank write address
|
747 |
|
|
reg_addr.we <= reg_wb_rb.we; -- register bank write enable
|
748 |
|
|
|
749 |
|
|
end architecture structure_plasma_control_MIPSI;
|