URL
https://opencores.org/ocsvn/minimips_superscalar/minimips_superscalar/trunk
Subversion Repositories minimips_superscalar
Compare Revisions
- This comparison shows the changes necessary to convert path
/minimips_superscalar/tags
- from Rev 1 to Rev 4
- ↔ Reverse comparison
Rev 1 → Rev 4
/P0/bench/bench_minimips.vhd
0,0 → 1,203
------------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : testbench -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
------------------------------------------------------------------------------- |
|
-- If you encountered any problem, please contact : |
-- |
-- lmouton@enserg.fr (2003 version) |
-- oschneid@enserg.fr (2003 version) |
-- shangoue@enserg.fr (2003 version) |
-- miguel_cafruni@hotmail.com (Superscalar version 2018) |
|
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library std; |
use std.textio.all; |
|
library work; |
use work.pack_mips.all; |
|
entity sim_minimips is |
end; |
|
architecture bench of sim_minimips is |
|
component minimips is |
port ( |
clock : in std_logic; |
clock2 : in std_logic; |
reset : in std_logic; |
|
ram_req : out std_logic; |
ram_adr : out bus32; |
ram_r_w : out std_logic; |
ram_data : inout bus32; |
ram_ack : in std_logic; |
|
ram_req2 : out std_logic; |
ram_adr2 : out bus32; |
ram_r_w2 : out std_logic; |
ram_data2 : inout bus32; |
ram_ack2 : in std_logic; |
|
it_mat : in std_logic |
); |
end component; |
|
|
component ram is |
generic (mem_size : natural := 256; |
latency : time := 10 ns); |
port( |
req : in std_logic; |
adr : in bus32; |
data_inout : inout bus32; |
r_w : in std_logic; |
ready : out std_logic; |
|
req2 : in std_logic; |
adr2 : in bus32; |
data_inout2 : inout bus32; |
r_w2 : in std_logic; |
ready2 : out std_logic |
); |
end component; |
|
component rom is |
generic (mem_size : natural := 256; |
start : natural := 0; |
latency : time := 10 ns); |
port( |
adr : in bus32; |
donnee : out bus32; |
ack : out std_logic; |
|
adr2 : in bus32; |
donnee2 : out bus32; |
ack2 : out std_logic; |
|
load : in std_logic; |
fname : in string |
); |
end component; |
|
signal clock : std_logic := '0'; |
signal clock2 : std_logic := '0'; |
signal reset : std_logic; |
|
signal it_mat : std_logic := '0'; |
|
-- Connexion with the code memory |
signal load : std_logic; |
signal fichier : string(1 to 7); |
|
-- Connexion with the Ram |
signal ram_req : std_logic; |
signal ram_adr : bus32; |
signal ram_r_w : std_logic; |
signal ram_data : bus32; |
signal ram_rdy : std_logic; |
|
signal ram_req2 : std_logic; |
signal ram_adr2 : bus32; |
signal ram_r_w2 : std_logic; |
signal ram_data2 : bus32; |
signal ram_rdy2 : std_logic; |
|
begin |
|
U_minimips : minimips port map ( |
clock => clock, |
clock2 => clock2, |
reset => reset, |
ram_req => ram_req, |
ram_adr => ram_adr, |
ram_r_w => ram_r_w, |
ram_data => ram_data, |
ram_ack => ram_rdy, |
|
ram_req2 => ram_req2, |
ram_adr2 => ram_adr2, |
ram_r_w2 => ram_r_w2, |
ram_data2 => ram_data2, |
ram_ack2 => ram_rdy2, |
|
it_mat => it_mat |
); |
|
U_ram : ram port map ( |
req => ram_req, |
adr => ram_adr, |
data_inout => ram_data, |
r_w => ram_r_w, |
ready => ram_rdy, |
|
req2 => ram_req2, |
adr2 => ram_adr2, |
data_inout2 => ram_data2, |
r_w2 => ram_r_w2, |
ready2 => ram_rdy2 |
); |
|
U_rom : rom port map ( |
adr => ram_adr, |
donnee => ram_data, |
ack => ram_rdy, |
|
adr2 => ram_adr2, |
donnee2 => ram_data2, |
ack2 => ram_rdy2, |
|
load => load, |
fname => fichier |
); |
|
clock <= not clock after 10 ns; |
clock2 <= not clock2 after 10 ns; |
reset <= '0', '1' after 5 ns, '0' after 25 ns; |
ram_data <= (others => 'L'); |
ram_data2 <= (others => 'L'); |
process |
variable command : line; |
variable nomfichier : string(1 to 3); |
begin |
--write (output, "Enter the filename : "); |
--readline(input, command); |
--read(command, nomfichier); |
|
fichier <= "msx.bin"; |
|
load <= '1'; |
--wait; |
end process; |
|
-- Memory Mapping -- |
-- 0000 - 00FF ROM |
|
process (ram_adr, ram_r_w, ram_data) |
begin -- Emulation of an I/O controller |
ram_data <= (others => 'Z'); |
|
case ram_adr is |
when X"00001000" => -- declenche une lecture avec interruption |
it_mat <= '1' after 1000 ns; |
ram_rdy <= '1' after 5 ns; |
when X"00001001" => -- fournit la donnee et lache l'it |
it_mat <= '0'; |
ram_data <= X"FFFFFFFF"; |
ram_rdy <= '1' after 5 ns; |
when others => ram_rdy <= 'L'; |
end case; |
end process; |
|
end bench; |
/P0/bench/ram.vhd
0,0 → 1,106
------------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : testbench -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
------------------------------------------------------------------------------- |
|
-- If you encountered any problem, please contact : |
-- |
-- lmouton@enserg.fr (2003 version) |
-- oschneid@enserg.fr (2003 version) |
-- shangoue@enserg.fr (2003 version) |
-- miguel_cafruni@hotmail.com (Superscalar version 2018) |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity ram is |
generic (mem_size : natural := 256; -- Size of the memory in words |
latency : time := 0 ns); |
port( |
req : in std_logic; |
adr : in bus32; |
data_inout : inout bus32; |
r_w : in std_logic; |
ready : out std_logic; |
|
req2 : in std_logic; |
adr2 : in bus32; |
data_inout2 : inout bus32; |
r_w2 : in std_logic; |
ready2 : out std_logic |
); |
end; |
|
|
architecture bench of ram is |
type storage_array is array(natural range 1024 to 1024+4*mem_size - 1) of bus8; |
signal storage : storage_array; -- The memory |
begin |
|
process(adr, data_inout, r_w, adr2, data_inout2, r_w2) |
variable inadr : integer; |
variable i : natural; |
variable inadr2 : integer; |
variable j : natural; |
begin |
inadr := to_integer(unsigned(adr)); |
|
if (inadr>=storage'low) and (inadr<=storage'high) then |
|
ready <= '0', '1' after latency; |
if req = '1' then |
if r_w /= '1' then -- Reading in memory |
for i in 0 to 3 loop |
data_inout(8*(i+1)-1 downto 8*i) <= storage(inadr+(3-i)) after latency; |
end loop; |
else |
for i in 0 to 3 loop |
storage(inadr+(3-i)) <= data_inout(8*(i+1)-1 downto 8*i) after latency; |
end loop; |
data_inout <= (others => 'Z'); |
end if; |
else |
data_inout <= (others => 'Z'); |
end if; |
else |
data_inout <= (others => 'Z'); |
ready <= 'L'; |
end if; |
|
inadr2 := to_integer(unsigned(adr2)); |
|
if (inadr2>=storage'low) and (inadr2<=storage'high) then |
|
ready2 <= '0', '1' after latency; |
if req2 = '1' then |
if r_w2 /= '1' then -- Reading in memory |
for j in 0 to 3 loop |
data_inout2(8*(j+1)-1 downto 8*j) <= storage(inadr2+(3-j)) after latency; |
end loop; |
else |
for j in 0 to 3 loop |
storage(inadr2+(3-j)) <= data_inout2(8*(j+1)-1 downto 8*j) after latency; --report "Valor j = " & integer'image(j);-- 04/09/18 |
end loop; |
data_inout2 <= (others => 'Z'); |
end if; |
else |
data_inout2 <= (others => 'Z'); |
end if; |
else |
data_inout2 <= (others => 'Z'); |
ready2 <= 'L'; |
end if; |
end process; |
|
end bench; |
/P0/bench/rom.vhd
0,0 → 1,186
------------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : testbench -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
------------------------------------------------------------------------------- |
|
-- If you encountered any problem, please contact : |
-- |
-- lmouton@enserg.fr (2003 version) |
-- oschneid@enserg.fr (2003 version) |
-- shangoue@enserg.fr (2003 version) |
-- miguel_cafruni@hotmail.com (Superscalar version 2018) |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use ieee.std_logic_textio.all; |
use std.textio.all; |
|
library work; |
use work.pack_mips.all; |
|
entity rom is |
generic (mem_size : natural := 256; -- Size of the memory in words |
start : natural := 32768; |
latency : time := 0 ns); |
port( |
adr : in bus32; |
donnee : out bus32; |
ack : out std_logic; |
adr2 : in bus32; |
donnee2 : out bus32; |
ack2 : out std_logic; |
load : in std_logic; |
fname : in string |
); |
end; |
|
|
architecture bench of rom is |
type storage_array is array(natural range start to start+4*mem_size - 1) of bus8; |
signal storage : storage_array := (others => (others => '0')); -- The memory |
signal adresse : bus16; |
signal taille : bus16; |
begin |
|
|
process (load) |
-- Variables for loading the memory |
-- The reading is done by blocks |
type bin is file of integer; -- Binary type file |
file load_file : bin; |
|
variable c : integer ; -- Integer (32 bits) read in the file |
variable index : integer range storage'range; -- Index for loading |
variable word : bus32; -- Word read in the file |
variable taille_bloc : integer; -- Current size of the block to load |
variable tmp : bus16; |
variable status : file_open_status; |
|
variable s : line; |
variable big_endian : boolean := true; -- Define if the processor (on which we work) is little or big endian |
begin |
|
if load='1' then |
|
-- Reading of the file de fill the memory at the defined address |
file_open(status, load_file, fname, read_mode); |
|
if status=open_ok then |
|
while not endfile(load_file) loop |
|
-- Read the header of the block |
read(load_file, c); -- Read a 32 bit long word |
word := bus32(to_unsigned(c, 32)); -- Conversion to a bit vector |
|
if big_endian then |
tmp := word(7 downto 0) & word(15 downto 8); |
else |
tmp := word(31 downto 16); |
end if; |
|
index := to_integer(unsigned(tmp)); |
adresse <= tmp; |
|
if big_endian then |
tmp := word(23 downto 16) & word(31 downto 24); |
else |
tmp := word(15 downto 0); |
end if; |
|
|
taille_bloc := to_integer(unsigned(tmp)) / 4; |
taille <= tmp; |
|
-- Load the block in the ROM |
for n in 1 to taille_bloc loop |
|
-- The header file is not correct (block too small, ROM to small ...) |
-- The simulation is stopped |
assert (not endfile(load_file) and (index<=storage'high)) |
report "L'image n'a pas le bon format ou ne rentre pas dans la rom." |
severity error; |
|
if not endfile(load_file) and (index<=storage'high) then |
read(load_file, c); |
word := bus32(to_unsigned(c, 32)); |
if (c < 0) then |
word := not(word); |
word := std_logic_vector(unsigned(word)+1); |
end if; |
for i in 0 to 3 loop |
|
if big_endian then |
storage(index+i) <= word(8*(i+1)-1 downto 8*i); |
else |
storage(index+(3-i)) <= word(8*(i+1)-1 downto 8*i); |
end if; |
|
end loop; |
index := index + 4; |
end if; |
end loop; |
|
end loop; |
|
file_close(load_file); |
|
else |
assert false |
report "Impossible d'ouvrir le fichier specifie." |
severity error; |
|
end if; |
|
end if; |
|
end process; |
|
|
process(adr) -- Request for reading the ROM |
variable inadr : integer; |
variable i : natural; |
begin |
inadr := to_integer(unsigned(adr)); |
|
if (inadr>=storage'low) and (inadr<=storage'high) then |
for i in 0 to 3 loop |
donnee(8*(i+1)-1 downto 8*i) <= storage(inadr+3-i) after latency; |
end loop; |
ack <= '0', '1' after latency; |
else |
donnee <= (others => 'Z'); |
ack <= 'L'; |
end if; |
end process; |
|
|
process(adr2) -- Request for reading the ROM |
variable inadr2 : integer; |
variable i2 : natural; |
begin |
inadr2 := to_integer(unsigned(adr2)); |
|
if (inadr2>=storage'low) and (inadr2<=storage'high) then |
for i2 in 0 to 3 loop |
donnee2(8*(i2+1)-1 downto 8*i2) <= storage(inadr2+3-i2) after latency; |
end loop; |
ack2 <= '0', '1' after latency; |
else |
donnee2 <= (others => 'Z'); |
ack2 <= 'L'; |
end if; |
end process; |
|
end bench; |
|
|
|
/P0/sources/alu.vhd
0,0 → 1,172
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Arithmetical and logical unit -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity alu is |
port |
( |
clock : in bus1; |
reset : in bus1; |
op1 : in bus32; -- Operand 1 |
op2 : in bus32; -- Operand 2 |
ctrl : in alu_ctrl_type; -- Opearator control |
hilo_p2 : in bus64; |
hilo_p1p2 : out bus64; |
res : out bus32; -- The result is 32 bit long |
overflow : out bus1 -- Overflow of the result |
); |
end alu; |
|
|
architecture rtl of alu is |
|
-- Signals to pre-process the operands |
signal efct_op1, efct_op2 : bus33; -- Effective operands of the adder (33 bits) |
signal comp_op2 : bus1; -- Select the opposite of operand 2 |
signal igno_op2 : bus1; -- Ignore op 2 (put zeros) |
signal sign_op1 : bus1; -- High bit of op 1 |
signal sign_op2 : bus1; -- High bit of op 2 |
signal signe : bus1; -- Signed operation (bit sign extension) |
signal shift_val : natural range 0 to 31; -- Value of the shift |
|
-- Signals for internal results |
signal res_shl, res_shr : bus32; -- Results of left and right shifter |
signal res_lui : bus32; -- Result of Load Upper Immediate |
signal res_add : bus33; -- Result of the adder |
signal res_mul : std_logic_vector(31 downto 0); -- Resultado da multiplicacao 25.05.18 |
signal carry : bus33; -- Carry for the adder |
signal nul : bus1; -- Check if the adder result is zero |
signal hilo : bus64; -- Internal registers to store the multiplication operation |
signal tmp_hilo : bus64; -- Internal registers to store the multiplication operation (synchronised) |
signal hilop2 : bus64; -- Internal registers to store the multiplication operation |
signal i_mult : bus1; |
|
begin |
|
-- Process if the operation is signed compliant |
signe <= '1' when (ctrl=OP_ADD or ctrl=OP_SUB or ctrl=OP_SLT or ctrl=OP_SNEG or ctrl=OP_SPOS or ctrl=OP_LNEG or ctrl=OP_LPOS) |
else |
'0'; |
|
sign_op1 <= signe and op1(31); |
sign_op2 <= signe and op2(31); |
|
-- Selection of the value of the second operand : op2 or -op2 (ie not op2 + 1) |
comp_op2 <= '1' when -- The opposite of op2 is used |
(ctrl=OP_SUB or ctrl=OP_SUBU) -- Opposite of the operand 2 to obtain a substraction |
or (ctrl=OP_SLT or ctrl=OP_SLTU) -- Process the difference to check the lesser than operation for the operands |
or (ctrl=OP_EQU or ctrl=OP_NEQU) -- Process the difference to check the equality of the operands |
else |
'0'; -- by default, op2 is used |
|
igno_op2 <= '1' when -- Op 2 will be zero (when comp_op2='0') |
(ctrl=OP_SPOS or ctrl=OP_LNEG) -- Process if the op1 is nul with op1+0 |
else |
'0'; |
|
-- Effective signals for the adder |
efct_op2 <= not (sign_op2 & op2) when (comp_op2='1') else -- We take the opposite of op2 to get -op2 (we will add 1 with the carry) |
(others => '0') when (igno_op2='1') else -- Op2 is zero |
(sign_op2 & op2); -- by default we use op2 (33 bits long) |
|
efct_op1 <= sign_op1 & op1; |
|
-- Execution of the addition |
carry <= X"00000000" & comp_op2; -- Carry to one when -op2 is needed |
res_add <= std_logic_vector(unsigned(efct_op1) + unsigned(efct_op2) + unsigned(carry)); -- Usado na instrucao BNE |
res_mul <= std_logic_vector(signed(efct_op1(15 downto 0))*signed(efct_op2(15 downto 0))); -- new, operandos de 16 bits por hora!!!! |
nul <= '1' when (res_add(31 downto 0)=X"00000000") else '0'; -- Check the nullity of the result |
|
-- Value of the shift for the programmable shifter |
shift_val <= to_integer(unsigned(op1(4 downto 0))); |
|
res_shl <= bus32(shift_left(unsigned(op2), shift_val)); |
res_shr <= not bus32(shift_right(unsigned(not op2) , shift_val)) when (ctrl=OP_SRA and op2(31)='1') else |
bus32(shift_right(unsigned(op2), shift_val)); |
res_lui <= op2(15 downto 0) & X"0000"; |
|
-- Affectation of the hilo register if necessary |
tmp_hilo <= std_logic_vector(signed(op1)*signed(op2)) when (ctrl=OP_MULT) else |
std_logic_vector(unsigned(op1)*unsigned(op2)) when (ctrl=OP_MULTU) else |
op1 & hilo(31 downto 0) when (ctrl=OP_MTHI) else |
hilo(63 downto 32) & op1 when (ctrl=OP_MTLO) else |
(others => '0'); |
|
hilo_p1p2 <= tmp_hilo; -- saida do resultado completo assincrona 20-12-2018 |
|
-- Check the overflows |
overflow <= '1' when ((ctrl=OP_ADD and op1(31)=efct_op2(31) and op1(31)/=res_add(31)) |
or (ctrl=OP_SUB and op1(31)/=op2(31) and op1(31)/=res_add(31))) else |
'0'; -- Only ADD and SUB can overflow |
|
-- Result affectation |
res <= |
-- Arithmetical operations |
res_add(31 downto 0) when (ctrl=OP_ADD or ctrl=OP_ADDU or ctrl=OP_SUB or ctrl=OP_SUBU) else |
res_mul(31 downto 0) when (ctrl=OP_MULT2) else -- Acrescentada por Miguel Cafruni. Operandos de modulos que facam com que o resultado correto do produto caiba nos 32 bits menos significativos |
-- Logical operations |
op1 and op2 when (ctrl=OP_AND) else |
op1 or op2 when (ctrl=OP_OR) else |
op1 nor op2 when (ctrl=OP_NOR) else |
op1 xor op2 when (ctrl=OP_XOR) else |
-- Different tests : the result is one when the test is succesful |
(0 => res_add(32), others=>'0') when (ctrl=OP_SLTU or ctrl=OP_SLT) else |
(0 => nul, others=>'0') when (ctrl=OP_EQU) else |
(0 => not nul, others=>'0') when (ctrl=OP_NEQU) else |
(0 => op1(31), others=>'0') when (ctrl=OP_SNEG) else |
(0 => not (op1(31) or nul), others=>'0') when (ctrl=OP_SPOS) else |
(0 => (op1(31) or nul), others=>'0') when (ctrl=OP_LNEG) else |
(0 => not op1(31), others=>'0') when (ctrl=OP_LPOS) else |
-- Shifts |
res_shl when (ctrl=OP_SLL) else |
res_shr when (ctrl=OP_SRL or ctrl=OP_SRA) else |
res_lui when (ctrl=OP_LUI) else |
-- Internal registers |
hilo(63 downto 32) when (ctrl=OP_MFHI and i_mult='1') else |
hilo(31 downto 0) when ((ctrl=OP_MFLO or ctrl=OP_MULT or ctrl=OP_MULTU) and i_mult='1') else |
hilop2(63 downto 32) when (ctrl=OP_MFHI and i_mult='0') else |
hilop2(31 downto 0) when (ctrl=OP_MFLO and i_mult='0') else |
op1 when (ctrl=OP_MTHI or ctrl=OP_MTLO) else |
op2 when (ctrl=OP_OP2) else -- dado para a instrucao SW salvar na RAM |
-- Always true |
X"00000001" when (ctrl=OP_OUI) else |
-- Unknown operation or nul result desired |
(others => '0'); |
|
-- Save the hilo register |
process (clock) |
begin |
if rising_edge(clock) then |
if reset = '1' then |
hilo <= (others => '0'); |
i_mult <= '0'; |
elsif (ctrl = OP_MULT) or (ctrl = OP_MULTU) or (ctrl = OP_MTLO) or (ctrl = OP_MTHI) then |
hilo <= tmp_hilo; |
i_mult <= '1'; |
else |
i_mult <= '0'; |
end if; |
end if; |
end process; |
|
process (hilo_p2) |
begin |
hilop2 <= hilo_p2; -- salva entrada assincrona do resultado da multiplicacao feita no pipe 2 |
end process; |
|
end rtl; |
/P0/sources/alu2.vhd
0,0 → 1,172
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Arithmetical and logical unit 2 -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity alu2 is |
port |
( |
clock : in bus1; |
reset : in bus1; |
op1 : in bus32; -- Operand 1 |
op2 : in bus32; -- Operand 2 |
ctrl : in alu_ctrl_type; -- Opearator control |
hilo_p1 : in bus64; |
hilo_p2p1 : out bus64; |
res : out bus32; -- The result is 32 bit long |
overflow : out bus1 -- Overflow of the result |
); |
end alu2; |
|
|
architecture rtl of alu2 is |
|
-- Signals to pre-process the operands |
signal efct_op1, efct_op2 : bus33; -- Effective operands of the adder (33 bits) |
signal comp_op2 : bus1; -- Select the opposite of operand 2 |
signal igno_op2 : bus1; -- Ignore op 2 (put zeros) |
signal sign_op1 : bus1; -- High bit of op 1 |
signal sign_op2 : bus1; -- High bit of op 2 |
signal signe : bus1; -- Signed operation (bit sign extension) |
signal shift_val : natural range 0 to 31; -- Value of the shift |
|
-- Signals for internal results |
signal res_shl, res_shr : bus32; -- Results of left and right shifter |
signal res_lui : bus32; -- Result of Load Upper Immediate |
signal res_add : bus33; -- Result of the adder |
signal res_mul : std_logic_vector(31 downto 0); -- Resultado da multiplicacao 25.05.18 |
signal carry : bus33; -- Carry for the adder |
signal nul : bus1; -- Check if the adder result is zero |
signal hilo : bus64; -- Internal registers to store the multiplication operation |
signal tmp_hilo : bus64; -- Internal registers to store the multiplication operation (synchronised) |
signal hilop1 : bus64; |
signal i_mult : bus1; |
|
begin |
|
-- Process if the operation is signed compliant |
signe <= '1' when (ctrl=OP_ADD or ctrl=OP_SUB or ctrl=OP_SLT or ctrl=OP_SNEG or ctrl=OP_SPOS or ctrl=OP_LNEG or ctrl=OP_LPOS) |
else |
'0'; |
|
sign_op1 <= signe and op1(31); |
sign_op2 <= signe and op2(31); |
|
-- Selection of the value of the second operand : op2 or -op2 (ie not op2 + 1) |
comp_op2 <= '1' when -- The opposite of op2 is used |
(ctrl=OP_SUB or ctrl=OP_SUBU) -- Opposite of the operand 2 to obtain a substraction |
or (ctrl=OP_SLT or ctrl=OP_SLTU) -- Process the difference to check the lesser than operation for the operands |
or (ctrl=OP_EQU or ctrl=OP_NEQU) -- Process the difference to check the equality of the operands |
else |
'0'; -- by default, op2 is used |
|
igno_op2 <= '1' when -- Op 2 will be zero (when comp_op2='0') |
(ctrl=OP_SPOS or ctrl=OP_LNEG) -- Process if the op1 is nul with op1+0 |
else |
'0'; |
|
-- Effective signals for the adder |
efct_op2 <= not (sign_op2 & op2) when (comp_op2='1') else -- We take the opposite of op2 to get -op2 (we will add 1 with the carry) |
(others => '0') when (igno_op2='1') else -- Op2 is zero |
(sign_op2 & op2); -- by default we use op2 (33 bits long) |
|
efct_op1 <= sign_op1 & op1; |
|
-- Execution of the addition |
carry <= X"00000000" & comp_op2; -- Carry to one when -op2 is needed |
res_add <= std_logic_vector(unsigned(efct_op1) + unsigned(efct_op2) + unsigned(carry)); |
res_mul <= std_logic_vector(signed(efct_op1(15 downto 0))*signed(efct_op2(15 downto 0))); |
|
|
-- Value of the shift for the programmable shifter |
shift_val <= to_integer(unsigned(op1(4 downto 0))); |
|
res_shl <= bus32(shift_left(unsigned(op2), shift_val)); |
res_shr <= not bus32(shift_right(unsigned(not op2) , shift_val)) when (ctrl=OP_SRA and op2(31)='1') else |
bus32(shift_right(unsigned(op2), shift_val)); |
res_lui <= op2(15 downto 0) & X"0000"; |
|
-- Affectation of the hilo register if necessary |
tmp_hilo <= std_logic_vector(signed(op1)*signed(op2)) when (ctrl=OP_MULT) else |
std_logic_vector(unsigned(op1)*unsigned(op2)) when (ctrl=OP_MULTU) else |
op1 & hilo(31 downto 0) when (ctrl=OP_MTHI) else |
hilo(63 downto 32) & op1 when (ctrl=OP_MTLO) else |
(others => '0'); |
|
hilo_p2p1 <= tmp_hilo; |
|
-- Check the overflows |
overflow <= '1' when ((ctrl=OP_ADD and op1(31)=efct_op2(31) and op1(31)/=res_add(31)) |
or (ctrl=OP_SUB and op1(31)/=op2(31) and op1(31)/=res_add(31))) else |
'0'; -- Only ADD and SUB can overflow |
|
-- Result affectation |
res <= |
-- Arithmetical operations |
res_add(31 downto 0) when (ctrl=OP_ADD or ctrl=OP_ADDU or ctrl=OP_SUB or ctrl=OP_SUBU) else |
res_mul(31 downto 0) when (ctrl=OP_MULT2) else |
-- Logical operations |
op1 and op2 when (ctrl=OP_AND) else |
op1 or op2 when (ctrl=OP_OR) else |
op1 nor op2 when (ctrl=OP_NOR) else |
op1 xor op2 when (ctrl=OP_XOR) else |
-- Different tests : the result is one when the test is succesful |
(0 => res_add(32), others=>'0') when (ctrl=OP_SLTU or ctrl=OP_SLT) else |
(0 => nul, others=>'0') when (ctrl=OP_EQU) else |
(0 => not nul, others=>'0') when (ctrl=OP_NEQU) else -- inverte o sinal nul, se nao sao iguais os valores dos registradores, entao o branch sera tomado |
(0 => op1(31), others=>'0') when (ctrl=OP_SNEG) else |
(0 => not (op1(31) or nul), others=>'0') when (ctrl=OP_SPOS) else |
(0 => (op1(31) or nul), others=>'0') when (ctrl=OP_LNEG) else |
(0 => not op1(31), others=>'0') when (ctrl=OP_LPOS) else |
-- Shifts |
res_shl when (ctrl=OP_SLL) else |
res_shr when (ctrl=OP_SRL or ctrl=OP_SRA) else |
res_lui when (ctrl=OP_LUI) else |
-- Internal registers |
hilo(63 downto 32) when (ctrl=OP_MFHI and i_mult='1') else |
hilo(31 downto 0) when ((ctrl=OP_MFLO or ctrl=OP_MULT or ctrl=OP_MULTU) and i_mult='1') else |
hilop1(63 downto 32) when (ctrl=OP_MFHI and i_mult='0') else |
hilop1(31 downto 0) when (ctrl=OP_MFLO and i_mult='0') else -- veio do pipe 1 20-12-2018 or ctrl=OP_MULT or ctrl=OP_MULTU |
op1 when (ctrl=OP_MTHI or ctrl=OP_MTLO) else |
op2 when (ctrl=OP_OP2) else |
-- Always true |
X"00000001" when (ctrl=OP_OUI) else -- J (jump) |
-- Unknown operation or nul result desired |
(others => '0'); |
|
-- Save the hilo register |
process (clock) |
begin |
if falling_edge(clock) then |
if reset = '1' then |
hilo <= (others => '0'); |
i_mult <= '0'; |
elsif (ctrl = OP_MULT) or (ctrl = OP_MULTU) or (ctrl = OP_MTLO) or (ctrl = OP_MTHI) then |
hilo <= tmp_hilo; |
i_mult <= '1'; |
else |
i_mult <= '0'; |
end if; |
end if; |
end process; |
|
process (hilo_p1) |
begin |
hilop1 <= hilo_p1; -- salva entrada assincrona do resultado da multiplicacao feita no pipe 1 20-12-2018 |
end process; |
|
end rtl; |
/P0/sources/banc.vhd
0,0 → 1,107
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Register bank -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity banc is |
port ( |
clock : in bus1; |
clock2 : in bus1; |
reset : in bus1; |
|
-- Register addresses to read |
reg_src1 : in bus5; |
reg_src2 : in bus5; |
|
-- Register address to write and its data |
reg_dest : in bus5; |
donnee : in bus32; |
|
-- Write signal |
cmd_ecr : in bus1; |
|
-- Bank outputs |
data_src1 : out bus32; |
data_src2 : out bus32; |
|
-- Register addresses to read |
reg_src3 : in bus5; |
reg_src4 : in bus5; |
|
-- Register address to write and its data |
reg_dest2 : in bus5; |
donnee2 : in bus32; |
|
-- Write signal |
cmd_ecr2 : in bus1; |
|
-- Bank outputs |
data_src3 : out bus32; |
data_src4 : out bus32 |
); |
end banc; |
|
|
architecture rtl of banc is |
|
-- The register bank |
type tab_reg is array (1 to 31) of bus32; |
signal registres : tab_reg; |
signal adr_src1 : integer range 0 to 31; |
signal adr_src2 : integer range 0 to 31; |
signal adr_dest : integer range 0 to 31; |
signal adr_src3 : integer range 0 to 31; |
signal adr_src4 : integer range 0 to 31; |
signal adr_dest2 : integer range 0 to 31; |
begin |
|
adr_src1 <= to_integer(unsigned(reg_src1)); |
adr_src2 <= to_integer(unsigned(reg_src2)); |
adr_dest <= to_integer(unsigned(reg_dest)); |
adr_src3 <= to_integer(unsigned(reg_src3)); |
adr_src4 <= to_integer(unsigned(reg_src4)); |
adr_dest2 <= to_integer(unsigned(reg_dest2)); |
|
data_src1 <= (others => '0') when adr_src1=0 else |
registres(adr_src1); |
data_src2 <= (others => '0') when adr_src2=0 else |
registres(adr_src2); |
data_src3 <= (others => '0') when adr_src3=0 else |
registres(adr_src3); |
data_src4 <= (others => '0') when adr_src4=0 else |
registres(adr_src4); |
|
|
process(clock) |
begin |
if rising_edge(clock) then |
if reset='1' then |
for i in 1 to 31 loop |
registres(i) <= (others => '0'); |
end loop; |
elsif cmd_ecr = '1' and adr_dest /= 0 then |
-- The data is saved |
registres(adr_dest) <= donnee; |
end if; |
if cmd_ecr2 = '1' and adr_dest2 /= 0 then |
-- The data is saved |
registres(adr_dest2) <= donnee2; |
end if; |
end if; |
end process; |
|
end rtl; |
/P0/sources/bus_ctrl01.vhd
0,0 → 1,166
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : bus controler 01 -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity bus_ctrl01 is |
port |
( |
clock : std_logic; |
reset : std_logic; |
|
-- Interruption in the pipeline |
interrupt : in std_logic; |
|
-- Interface for the Instruction Extraction Stage |
adr_from_ei : in bus32; -- The address of the data to read |
instr_to_ei : out bus32; -- Instruction from the memory |
|
-- Interface with the MEMory Stage |
req_from_mem : in std_logic; -- Request to access the ram |
r_w_from_mem : in std_logic; -- Read/Write request |
adr_from_mem : in bus32; -- Address in ram |
data_from_mem : in bus32; -- Data to write in ram |
data_to_mem : out bus32; -- Data from the ram to the MEMory stage |
|
-- RAM interface signals |
req_to_ram : out std_logic; -- Request to ram |
adr_to_ram : out bus32; -- Address of the data to read or write |
r_w_to_ram : out std_logic; -- Read/Write request |
ack_from_ram : in std_logic; -- Acknowledge from the memory |
data_inout_ram : inout bus32; -- Data from/to the memory |
|
-- Pipeline progress control signal |
stop_all : out std_logic |
); |
end bus_ctrl01; |
|
|
architecture rtl of bus_ctrl01 is |
|
type ctrl_state is ( ST1, ST2 ); |
signal cs, ns : ctrl_state; |
signal ei_buffer : bus32; -- Buffer storing the data for EI |
|
signal r_w : std_logic; -- Current utilisation of the tristate bus |
signal data_in : bus32; -- Data read on the tristate bus |
signal req_allowed : std_logic; |
|
begin |
|
-- Read/write on the tristate bus |
process (r_w, data_from_mem, data_inout_ram) |
begin |
r_w_to_ram <= r_w; |
if r_w='0' then -- Reads bus |
data_inout_ram <= (others => 'Z'); |
data_in <= data_inout_ram; |
else -- Writing of the data from the MEM stage |
data_inout_ram <= data_from_mem; |
data_in <= (others => '0'); |
end if; |
end process; |
|
process (clock) |
begin |
if rising_edge(clock) then |
if reset='1' then |
cs <= ST1; |
ei_buffer <= (others => '0'); |
else |
if cs=ST1 then |
-- Storing of the data to send to EI stage |
ei_buffer <= data_in; |
end if; |
|
cs <= ns; |
end if; |
end if; |
end process; |
|
process (clock, ack_from_ram) |
begin |
if ack_from_ram = '0' then |
req_allowed <= '0'; |
elsif rising_edge(clock) then |
if ack_from_ram = '1' then |
req_allowed <= '1'; |
end if; |
end if; |
end process; |
|
process (req_allowed, ack_from_ram) |
begin |
if req_allowed = '1' then |
req_to_ram <= '1'; |
elsif ack_from_ram = '0' then |
req_to_ram <= '1'; |
else |
req_to_ram <= '0'; |
end if; |
end process; |
|
process (cs, interrupt, adr_from_ei, req_from_mem, r_w_from_mem, adr_from_mem, ack_from_ram) |
begin |
if interrupt = '1' then -- An interruption is detected |
ns <= ST1; -- Get back to the reading request |
stop_all <= '0'; -- The pipeline is unlock for taking in account the interruption |
adr_to_ram <= adr_from_ei; |
r_w <= '0'; |
else |
case cs is |
|
when ST1 => -- First step the reading for EI |
adr_to_ram <= adr_from_ei; |
r_w <= '0'; |
|
if ack_from_ram='1' then |
|
if req_from_mem='1' then |
-- If request from MEM, then step 2 |
ns <= ST2; |
stop_all <= '1'; |
else |
-- else next reading for EI |
ns <= ST1; |
stop_all <= '0'; |
end if; |
else |
-- Wait the end of the reading |
ns <= ST1; |
stop_all <= '1'; |
end if; |
|
when ST2 => -- Treat the request from the MEM stage |
adr_to_ram <= adr_from_mem; |
r_w <= r_w_from_mem; |
|
-- Wait the acknowledge from the RAM |
if ack_from_ram='1' then |
ns <= ST1; |
stop_all <= '0'; |
else |
ns <= ST2; |
stop_all <= '1'; |
end if; |
end case; |
end if; |
end process; |
data_to_mem <= data_in; |
instr_to_ei <= ei_buffer when cs=ST2 else data_in; |
|
end rtl; |
/P0/sources/bus_ctrl02.vhd
0,0 → 1,168
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : bus controler 02 -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity bus_ctrl02 is |
port |
( |
clock : std_logic; |
reset : std_logic; |
|
-- Interruption in the pipeline |
interrupt : in std_logic; |
|
-- Interface for the Instruction Extraction Stage |
adr_from_ei : in bus32; -- The address of the data to read |
instr_to_ei : out bus32; -- Instruction from the memory |
|
-- Interface with the MEMory Stage |
req_from_mem : in std_logic; -- Request to access the ram |
r_w_from_mem : in std_logic; -- Read/Write request |
adr_from_mem : in bus32; -- Address in ram |
data_from_mem : in bus32; -- Data to write in ram |
data_to_mem : out bus32; -- Data from the ram to the MEMory stage |
|
-- RAM interface signals |
req_to_ram : out std_logic; -- Request to ram |
adr_to_ram : out bus32; -- Address of the data to read or write |
r_w_to_ram : out std_logic; -- Read/Write request |
ack_from_ram : in std_logic; -- Acknowledge from the memory |
data_inout_ram : inout bus32; -- Data from/to the memory |
|
-- Pipeline progress control signal |
stop_all : out std_logic |
); |
end bus_ctrl02; |
|
|
architecture rtl of bus_ctrl02 is |
|
type ctrl_state is ( ST1, ST2 ); |
signal cs, ns : ctrl_state; |
signal ei_buffer : bus32; -- Buffer storing the data for EI |
|
signal r_w : std_logic; -- Current utilisation of the tristate bus |
signal data_in : bus32; -- Data read on the tristate bus |
signal req_allowed : std_logic; |
|
begin |
|
-- Read/write on the tristate bus |
process (r_w, data_from_mem, data_inout_ram) |
begin |
r_w_to_ram <= r_w; |
if r_w='0' then -- Reads bus |
data_inout_ram <= (others => 'Z'); |
data_in <= data_inout_ram; |
else -- Writing of the data from the MEM stage |
data_inout_ram <= data_from_mem; |
data_in <= (others => '0'); |
end if; |
end process; |
|
process (clock) |
begin |
if falling_edge(clock) then |
if reset='1' then |
cs <= ST1; |
ei_buffer <= (others => '0'); |
else |
if cs=ST1 then |
-- Storing of the data to send to EI stage |
ei_buffer <= data_in; |
end if; |
|
cs <= ns; |
end if; |
end if; |
end process; |
|
process (clock, ack_from_ram) |
begin |
if ack_from_ram = '0' then |
req_allowed <= '0'; |
elsif falling_edge(clock) then |
if ack_from_ram = '1' then |
req_allowed <= '1'; |
end if; |
end if; |
end process; |
|
process (req_allowed, ack_from_ram) |
begin |
if req_allowed = '1' then |
req_to_ram <= '1'; |
elsif ack_from_ram = '0' then |
req_to_ram <= '1'; |
else |
req_to_ram <= '0'; |
end if; |
end process; |
|
process (cs, interrupt, adr_from_ei, req_from_mem, r_w_from_mem, adr_from_mem, ack_from_ram) |
begin |
if interrupt = '1' then -- An interruption is detected |
ns <= ST1; -- Get back to the reading request |
stop_all <= '0'; -- The pipeline is unlock for taking in account the interruption |
adr_to_ram <= adr_from_ei; |
r_w <= '0'; |
else |
case cs is |
|
when ST1 => -- First step the reading for EI |
adr_to_ram <= adr_from_ei; |
r_w <= '0'; |
|
if ack_from_ram='1' then |
|
if req_from_mem='1' then |
-- If request from MEM, then step 2 |
ns <= ST2; |
stop_all <= '1'; |
else |
-- else next reading for EI |
ns <= ST1; |
stop_all <= '0'; |
end if; |
else |
-- Wait the end of the reading |
ns <= ST1; |
stop_all <= '1'; |
end if; |
|
when ST2 => -- Treat the request from the MEM stage |
adr_to_ram <= adr_from_mem; |
r_w <= r_w_from_mem; |
|
-- Wait the acknowledge from the RAM |
if ack_from_ram='1' then |
ns <= ST1; |
stop_all <= '0'; |
else |
ns <= ST2; |
stop_all <= '1'; |
end if; |
|
end case; |
end if; |
end process; |
|
data_to_mem <= data_in; |
instr_to_ei <= ei_buffer when cs=ST2 else data_in; |
|
end rtl; |
/P0/sources/clock_gate.vhd
0,0 → 1,38
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Clock gating stage -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity clock_gate is |
port ( |
clock_in1 : in bus1; |
clock_in2 : in bus1; |
clock_out1 : out bus1; |
clock_out2 : out bus1; |
gate1 : in bus1; |
gate2 : in bus1 |
); |
end clock_gate; |
|
architecture rtl of clock_gate is |
|
begin |
-- chaveamento dos clocks |
clock_out1 <= clock_in1;-- when gate1 = '0' else '1'; |
clock_out2 <= clock_in2;-- when gate2 = '0' else '1'; |
|
end rtl; |
/P0/sources/delay_gate.vhd
0,0 → 1,97
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : delay gate stage -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity delay_gate is |
port ( |
clock : in bus1; |
in1 : in bus1; |
in2 : in bus1; |
in3 : in bus1; |
in4 : in bus1; |
in5 : in bus1; |
in6 : in bus1; |
in7 : in bus1; |
in8 : in bus1; |
in9 : in bus1; |
in10 : in bus1; |
in11 : in bus1; |
in12 : in bus1; |
out1 : out bus1; |
out2 : out bus1; |
out3 : out bus1; |
out4 : out bus1; |
out5 : out bus1; |
out6 : out bus1; |
out7 : out bus1; |
out8 : out bus1; |
out9 : out bus1; |
out10 : out bus1; |
out11 : out bus1; |
out12 : out bus1 |
); |
end delay_gate; |
|
architecture rtl of delay_gate is |
|
signal s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12 : bus1; |
|
begin |
s1 <= in1; |
s2 <= in2; |
s3 <= in3; |
s4 <= in4; |
s5 <= in5; |
s6 <= in6; |
s7 <= in7; |
s8 <= in8; |
s9 <= in9; |
s10 <= in10; |
s11 <= in11; |
s12 <= in12; |
-- saidas deixam passar as entradas com meio ciclo de atraso |
process (clock) |
begin |
if falling_edge(clock) then |
out1 <= s1; |
out2 <= s2; |
out3 <= s3; |
out4 <= s4; |
out5 <= s5; |
out6 <= s6; |
out7 <= s7; |
out8 <= s8; |
out9 <= s9; |
out10 <= s10; |
out11 <= s11; |
out12 <= s12; |
end if; |
out1 <= s1; |
out2 <= s2; |
out3 <= s3; |
out4 <= s4; |
out5 <= s5; |
out6 <= s6; |
out7 <= s7; |
out8 <= s8; |
out9 <= s9; |
out10 <= s10; |
out11 <= s11; |
out12 <= s12; |
end process; |
end rtl; |
/P0/sources/minimips.vhd
0,0 → 1,865
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : miniMIPS Superscalar processor -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
|
library ieee; |
use ieee.std_logic_1164.all; |
|
library work; |
use work.pack_mips.all; |
|
entity minimips is |
port ( |
clock : in std_logic; |
clock2 : in std_logic; |
reset : in std_logic; |
|
-- Ram connexion |
ram_req : out std_logic; |
ram_adr : out bus32; |
ram_r_w : out std_logic; |
ram_data : inout bus32; |
ram_ack : in std_logic; |
|
ram_req2 : out std_logic; |
ram_adr2 : out bus32; |
ram_r_w2 : out std_logic; |
ram_data2 : inout bus32; |
ram_ack2 : in std_logic; |
|
-- Hardware interruption |
it_mat : in std_logic |
); |
end minimips; |
|
architecture rtl of minimips is |
|
-- General signals |
signal stop_all : std_logic; -- Lock the pipeline evolution |
signal stop_all2 : std_logic; -- Lock the pipeline evolution |
|
signal it_mat_clk : std_logic; -- Synchronised hardware interruption |
signal stop_pf : std_logic; -- Lock the pc |
signal stop_pf2 : std_logic; -- Lock the pc |
signal genop : std_logic; -- envoi de nops |
signal genop2 : std_logic; -- envoi de nops |
signal clock_out1, clock_out2 : std_logic; -- sem uso atual |
-- interface PF - EI |
signal PF_pc : bus32; -- PC value |
signal PF_pc_4 : bus32; |
|
-- interface Controler - EI |
signal CTE_instr : bus32; -- Instruction from the memory |
signal ETC_adr : bus32; -- Address to read in memory |
|
-- interface Controler - EI2 |
signal CTE_instr2 : bus32; -- Instruction from the memory |
signal ETC_adr2 : bus32; -- Address to read in memory |
|
-- interface EI - DI |
signal EI_instr : bus32; -- Read interface |
signal EI_adr : bus32; -- Address from the read instruction |
signal EI_it_ok : std_logic; -- Allow hardware interruptions |
|
-- interface EI2 - DI2 |
signal EI_instr2 : bus32; -- Read interface |
signal EI_adr2 : bus32; -- Address from the read instruction |
signal EI_it_ok2 : std_logic; -- Allow hardware interruptions |
|
-- DI output |
signal bra_detect : std_logic; -- Branch detection in the current instruction |
|
-- DI2 output |
signal bra_detect2 : std_logic; -- Branch detection in the current instruction |
|
-- Asynchronous connexion with the bypass unit |
signal adr_reg1 : adr_reg_type; -- Operand 1 address |
signal adr_reg2 : adr_reg_type; -- Operand 2 address |
signal use1 : std_logic; -- Operand 1 utilisation |
signal use2 : std_logic; -- Operand 2 utilisation |
signal data1 : bus32; -- First register value |
signal data2 : bus32; -- Second register value |
signal alea : std_logic; -- Unresolved hazards detected |
|
-- Asynchronous connexion with the bypass unit |
signal adr_reg3 : adr_reg_type; -- Operand 1 address |
signal adr_reg4 : adr_reg_type; -- Operand 2 address |
signal use3 : std_logic; -- Operand 3 utilisation |
signal use4 : std_logic; -- Operand 4 utilisation |
signal data3 : bus32; -- 3th register value |
signal data4 : bus32; -- 4th register value |
signal alea2 : std_logic; -- Unresolved hazards detected 2nd pipe |
|
-- interface DI - EX |
signal DI_bra : std_logic; -- Branch decoded |
signal DI_link : std_logic; -- A link for that instruction |
signal DI_op1 : bus32; -- operand 1 for alu |
signal DI_op2 : bus32; -- operand 2 for alu |
signal DI_code_ual : alu_ctrl_type; -- Alu operation |
signal DI_offset : bus32; -- Offset for the address calculation |
signal DI_adr_reg_dest : adr_reg_type; -- Address of the destination register of the result |
signal DI_ecr_reg : std_logic; -- Effective writing of the result |
signal DI_mode : std_logic; -- Address mode (relative to pc or indexed to a register) |
signal DI_op_mem : std_logic; -- Memory operation request |
signal DI_r_w : std_logic; -- Type of memory operation (reading or writing) |
signal DI_adr : bus32; -- Address of the decoded instruction |
signal DI_exc_cause : bus32; -- Potential exception detected |
signal DI_level : level_type; -- Availability of the result for the data bypass |
signal DI_it_ok : std_logic; -- Allow hardware interruptions |
|
-- interface DI2 - EX2 |
signal DI_bra2 : std_logic; -- Branch decoded |
signal DI_link2 : std_logic; -- A link for that instruction |
signal DI_op3 : bus32; -- operand 1 for alu 2 |
signal DI_op4 : bus32; -- operand 2 for alu 2 |
signal DI_code_ual2 : alu_ctrl_type; -- Alu operation |
signal DI_offset2 : bus32; -- Offset for the address calculation |
signal DI_adr_reg_dest2 : adr_reg_type; -- Address of the destination register of the result |
signal DI_ecr_reg2 : std_logic; -- Effective writing of the result |
signal DI_mode2 : std_logic; -- Address mode (relative to pc or indexed to a register) |
signal DI_op_mem2 : std_logic; -- Memory operation request |
signal DI_r_w2 : std_logic; -- Type of memory operation (reading or writing) |
signal DI_adr2 : bus32; -- Address of the decoded instruction |
signal DI_exc_cause2 : bus32; -- Potential exception detected |
signal DI_level2 : level_type; -- Availability of the result for the data bypass |
signal DI_it_ok2 : std_logic; -- Allow hardware interruptions |
|
-- interface EX - MEM |
signal EX_adr : bus32; -- Instruction address |
signal EX_bra_confirm : std_logic; -- Branch execution confirmation |
signal EX_data_ual : bus32; -- Ual result |
signal EX_adresse : bus32; -- Address calculation result |
signal ex_adresse_p1p2_s : bus32; -- resultado do calculo do endereco do desvio + 4 para pipe 2 |
signal EX_adr_reg_dest : adr_reg_type; -- Destination register for the result |
signal EX_ecr_reg : std_logic; -- Effective writing of the result |
signal EX_op_mem : std_logic; -- Memory operation needed |
signal EX_r_w : std_logic; -- Type of memory operation (read or write) |
signal EX_exc_cause : bus32; -- Potential cause exception |
signal EX_level : level_type; -- Availability stage of result for bypassing |
signal EX_it_ok : std_logic; -- Allow hardware interruptions |
|
-- interface EX2 - MEM |
signal EX_adr2 : bus32; -- Instruction address |
signal EX_bra_confirm2 : std_logic; -- Branch execution confirmation |
signal EX_data_ual2 : bus32; -- Ual result |
signal EX_adresse2 : bus32; -- Address calculation result |
signal ex_adresse_p2p1_s : bus32; -- resultado do calculo do endereco do desvio + 4 para pipe 1 |
signal EX_adr_reg_dest2 : adr_reg_type; -- Destination register for the result |
signal EX_ecr_reg2 : std_logic; -- Effective writing of the result |
signal EX_op_mem2 : std_logic; -- Memory operation needed |
signal EX_r_w2 : std_logic; -- Type of memory operation (read or write) |
signal EX_exc_cause2 : bus32; -- Potential cause exception |
signal EX_level2 : level_type; -- Availability stage of result for bypassing |
signal EX_it_ok2 : std_logic; -- Allow hardware interruptions |
|
-- interface Controler - MEM |
signal MTC_data : bus32; -- Data to write in memory |
signal MTC_adr : bus32; -- Address for memory |
signal MTC_r_w : std_logic; -- Read/Write in memory |
signal MTC_req : std_logic; -- Request access to memory |
signal CTM_data : bus32; -- Data from memory |
|
-- interface Controler2 - MEM |
signal MTC_data2 : bus32; -- Data to write in memory |
signal MTC_adr2 : bus32; -- Address for memory |
signal MTC_r_w2 : std_logic; -- Read/Write in memory |
signal MTC_req2 : std_logic; -- Request access to memory |
signal CTM_data2 : bus32; -- Data from memory |
|
-- interface MEM - REG |
signal MEM_adr : bus32; -- Instruction address |
signal MEM_adr_reg_dest : adr_reg_type; -- Destination register address |
signal MEM_ecr_reg : std_logic; -- Writing of the destination register |
signal MEM_data_ecr : bus32; -- Data to write (from alu or memory) |
signal MEM_exc_cause : bus32; -- Potential exception cause |
signal MEM_level : level_type; -- Availability stage for the result for bypassing |
signal MEM_it_ok : std_logic; -- Allow hardware interruptions |
|
-- connexion to the register banks |
|
-- Writing commands in the register banks |
signal write_data : bus32; -- Data to write |
signal write_adr : bus5; -- Address of the register to write |
signal write_GPR : std_logic; -- Selection in the internal registers |
signal write_SCP : std_logic; -- Selection in the coprocessor system registers |
|
-- Reading commands for Reading in the registers |
signal read_adr1 : bus5; -- Address of the first register to read |
signal read_adr2 : bus5; -- Address of the second register to read |
signal read_data1_GPR : bus32; -- Value of operand 1 from the internal registers |
signal read_data1_SCP : bus32; -- Value of operand 2 from the internal registers |
signal read_data2_GPR : bus32; -- Value of operand 1 from the coprocessor system registers |
signal read_data2_SCP : bus32; -- Value of operand 2 from the coprocessor system registers |
|
-- interface MEM - REG duplicado as entradas e saidas do REG |
signal MEM_adr2 : bus32; -- Instruction address |
signal MEM_adr_reg_dest2 : adr_reg_type; -- Destination register address |
signal MEM_ecr_reg2 : std_logic; -- Writing of the destination register |
signal MEM_data_ecr2 : bus32; -- Data to write (from alu or memory) |
signal MEM_exc_cause2 : bus32; -- Potential exception cause |
signal MEM_level2 : level_type; -- Availability stage for the result for bypassing |
signal MEM_it_ok2 : std_logic; -- Allow hardware interruptions |
|
-- connexion to the register banks |
|
-- Writing commands in the register banks |
signal write_data2 : bus32; -- Data to write |
signal write_adr2 : bus5; -- Address of the register to write |
signal write_GPR2 : std_logic; -- Selection in the internal registers |
--signal write_SCP2 : std_logic; -- Selection in the coprocessor system registers |
|
-- Reading commands for Reading in the registers |
signal read_adr3 : bus5; -- Address of the first register to read |
signal read_adr4 : bus5; -- Address of the second register to read |
signal read_data3_GPR : bus32; -- Value of operand 1 from the internal registers |
signal read_data3_SCP : bus32; -- Value of operand 2 from the internal registers |
signal read_data4_GPR : bus32; -- Value of operand 1 from the coprocessor system registers |
signal read_data4_SCP : bus32; -- Value of operand 2 from the coprocessor system registers |
-- Interruption controls |
signal interrupt : std_logic; -- Interruption to take into account |
signal vecteur_it : bus32; -- Interruption vector |
|
-- Sinais atrasados meio ciclo |
signal DI_bra_D : std_logic; |
signal bra_detect_D : std_logic; |
signal EX_bra_confirm_D : std_logic; |
signal alea_D : std_logic; |
signal alea2_D : std_logic; |
signal EX_bra_confirm2_D : std_logic; |
signal bra_detect2_D : std_logic; |
signal DI_bra2_D : std_logic; |
signal iload_D : bus1; -- sem uso atual |
signal istore_D : bus1; |
signal istore2_D : bus1; |
-- |
signal istore : bus1; |
signal iload : bus1; -- sem uso atual |
signal istore2 : bus1; |
signal branch1 : std_logic; |
signal branch2 : std_logic; |
signal bra_adr_s : bus32; |
signal bra_adr2_s : bus32; |
signal aleaEI : bus1; |
signal aleaDI : bus1; |
signal alea2EI2 : bus1; |
signal alea2DI2 : bus1; |
signal ex2_data_hilo : bus64;--resultado da multiplicacao do pieline2 14-12-18 |
signal ex_data_hilo : bus64;--resultado da multiplicacao do pieline1 |
begin |
|
aleaEI <= alea or alea2_D; |
aleaDI <= alea or alea2_D; |
alea2EI2 <= alea2 or alea_D; |
alea2DI2 <= alea2 or alea_D; |
|
stop_pf <= DI_bra or DI_bra2_D or bra_detect or bra_detect2_D or alea or alea2_D or istore2 or istore2_D; |
genop <= bra_detect or bra_detect2_D or EX_bra_confirm or EX_bra_confirm2_D or DI_bra or DI_bra2_D or istore2 or istore2_D; |
|
stop_pf2 <= DI_bra2 or DI_bra_D or bra_detect2 or bra_detect_D or alea2 or alea_D or istore or istore_D; |
genop2 <= bra_detect2 or bra_detect_D or EX_bra_confirm2 or EX_bra_confirm_D or DI_bra2 or DI_bra_D or istore or istore_D; |
|
branch1 <= EX_bra_confirm or EX_bra_confirm2_D; |
branch2 <= EX_bra_confirm2 or EX_bra_confirm_D; |
|
-- muxes para selecionar o endereco do branh apropriado 12-08-2018 |
with EX_bra_confirm2_D select |
bra_adr_s <= ex_adresse_p2p1_s when '1', |
EX_adresse when others; |
with EX_bra_confirm_D select |
bra_adr2_s <= ex_adresse_p1p2_s when '1', |
EX_adresse2 when others; |
|
-- Take into account the hardware interruption on rising edge |
process (clock) |
begin |
if clock='1' and clock'event then |
it_mat_clk <= it_mat; |
end if; |
end process; |
|
U1_pf : pps_pf port map ( |
clock => clock, |
clock2 => clock2, |
reset => reset, |
stop_all => stop_all, -- Unconditionnal locking of the pipeline stage |
stop_all2 => stop_all2, |
-- entrees asynchrones |
bra_adr => bra_adr_s,--EX_adresse, -- Branch |
bra_cmd => branch1, -- Address to load when an effective branch |
exch_adr => vecteur_it, -- Exception branch |
exch_cmd => interrupt, -- Exception vector |
-- entrees asynchrones 24\03\18 |
bra_adr2 => bra_adr2_s,-- EX_adresse2, -- Branch |
bra_cmd2 => branch2, -- Address to load when an effective branch |
exch_adr2 => vecteur_it, -- Exception branch |
exch_cmd2 => interrupt, -- Exception vector |
-- Lock the stage |
stop_pf => stop_pf, |
stop_pf2 => stop_pf2,--estava errado 'stop_pf' corrigido em 03-04-18 |
-- Synchronous output to EI stage |
PF_pc => PF_pc, -- PC value |
PF_pc_4 => PF_pc_4 |
); |
|
|
U2_ei : pps_ei port map ( |
clock => clock, |
reset => reset, |
clear => interrupt, -- Clear the pipeline stage |
stop_all => stop_all, -- Evolution locking signal |
|
-- Asynchronous inputs |
stop_ei => aleaEI, -- Lock the EI_adr and Ei_instr registers |
genop => genop, -- Send nops |
|
-- interface Controler - EI |
CTE_instr => CTE_instr, -- Instruction from the memory |
ETC_adr => ETC_adr, -- Address to read in memory |
|
-- Synchronous inputs from PF stage |
PF_pc => PF_pc, -- Current value of the pc |
|
-- Synchronous outputs to DI stage |
EI_instr => EI_instr, -- Read interface |
EI_adr => EI_adr, -- Address from the read instruction |
EI_it_ok => EI_it_ok -- Allow hardware interruptions |
); |
|
|
U3_di : pps_di port map ( |
clock => clock, |
reset => reset, |
stop_all => stop_all, -- Unconditionnal locking of the outputs |
clear => interrupt, -- Clear the pipeline stage (nop in the outputs) |
|
-- Asynchronous outputs |
bra_detect => bra_detect, -- Branch detection in the current instruction |
|
-- Asynchronous connexion with the register management and data bypass unit |
adr_reg1 => adr_reg1, -- Address of the first register operand |
adr_reg2 => adr_reg2, -- Address of the second register operand |
use1 => use1, -- Effective use of operand 1 |
use2 => use2, -- Effective use of operand 2 |
--iload => iload, |
istore => istore, |
stop_di => aleaDI, -- Unresolved detected : send nop in the pipeline |
data1 => data1, -- Operand register 1 |
data2 => data2, -- Operand register 2 |
|
-- Datas from EI stage |
EI_adr => EI_adr, -- Address of the instruction |
EI_instr => EI_instr, -- The instruction to decode |
EI_it_ok => EI_it_ok, -- Allow hardware interruptions |
|
-- Synchronous output to EX stage |
DI_bra => DI_bra, -- Branch decoded |
DI_link => DI_link, -- A link for that instruction |
DI_op1 => DI_op1, -- operand 1 for alu |
DI_op2 => DI_op2, -- operand 2 for alu |
DI_code_ual => DI_code_ual, -- Alu operation |
DI_offset => DI_offset, -- Offset for the address calculation |
DI_adr_reg_dest => DI_adr_reg_dest, -- Address of the destination register of the result |
DI_ecr_reg => DI_ecr_reg, -- Effective writing of the result |
DI_mode => DI_mode, -- Address mode (relative to pc or indexed to a register) |
DI_op_mem => DI_op_mem, -- Memory operation request |
DI_r_w => DI_r_w, -- Type of memory operation (reading or writing) |
DI_adr => DI_adr, -- Address of the decoded instruction |
DI_exc_cause => DI_exc_cause, -- Potential exception detected |
DI_level => DI_level, -- Availability of the result for the data bypass |
DI_it_ok => DI_it_ok -- Allow hardware interruptions |
); |
|
|
U4_ex : pps_ex port map ( |
clock => clock, |
clock2 => clock, |
reset => reset, |
stop_all => stop_all, |
stop_all2 => stop_all2, -- Unconditionnal locking of outputs |
clear => interrupt, -- Clear the pipeline stage |
|
-- Datas from DI stage |
DI_bra => DI_bra, -- Branch instruction |
DI_link => DI_link, -- Branch with link |
DI_op1 => DI_op1, -- Operand 1 for alu |
DI_op2 => DI_op2, -- Operand 2 for alu |
DI_code_ual => DI_code_ual, -- Alu operation |
DI_offset => DI_offset, -- Offset for address calculation |
DI_adr_reg_dest => DI_adr_reg_dest, -- Destination register address for the result |
DI_ecr_reg => DI_ecr_reg, -- Effective writing of the result |
DI_mode => DI_mode, -- Address mode (relative to pc ou index by a register) |
DI_op_mem => DI_op_mem, -- Memory operation |
DI_r_w => DI_r_w, -- Type of memory operation (read or write) |
DI_adr => DI_adr, -- Instruction address |
DI_exc_cause => DI_exc_cause, -- Potential cause exception |
DI_level => DI_level, -- Availability stage of the result for bypassing |
DI_it_ok => DI_it_ok, -- Allow hardware interruptions |
EX2_data_hilo => ex2_data_hilo, -- entrada p resultado do hilo p2 |
EX_data_hilo => ex_data_hilo, -- saida p resultado do hilo p1 |
-- Synchronous outputs to MEM stage |
EX_adr => EX_adr, -- Instruction address |
EX_bra_confirm => EX_bra_confirm, -- Branch execution confirmation |
EX_data_ual => EX_data_ual, -- Ual result |
EX_adresse => EX_adresse, -- Address calculation result |
EX_adresse_p1p2 => ex_adresse_p1p2_s, --resultado do calculo do endereco do desvio + 4 para pipe 2. 12-08-2018 |
EX_adr_reg_dest => EX_adr_reg_dest, -- Destination register for the result |
EX_ecr_reg => EX_ecr_reg, -- Effective writing of the result |
EX_op_mem => EX_op_mem, -- Memory operation needed |
EX_r_w => EX_r_w, -- Type of memory operation (read or write) |
EX_exc_cause => EX_exc_cause, -- Potential cause exception |
EX_level => EX_level, -- Availability stage of result for bypassing |
EX_it_ok => EX_it_ok -- Allow hardware interruptions |
); |
|
|
U5_mem : pps_mem port map ( |
clock => clock, |
clock2 => clock2, |
reset => reset, |
stop_all => stop_all, -- Unconditionnal locking of the outputs |
stop_all2 => stop_all2, |
|
clear => interrupt, -- Clear the pipeline stage |
|
-- Interface with the control bus |
MTC_data => MTC_data, -- Data to write in memory |
MTC_adr => MTC_adr, -- Address for memory |
MTC_r_w => MTC_r_w, -- Read/Write in memory |
MTC_req => MTC_req, -- Request access to memory |
CTM_data => CTM_data, -- Data from memory |
|
-- Datas from Execution stage |
EX_adr => EX_adr, -- Instruction address |
EX_data_ual => EX_data_ual, -- Result of alu operation |
EX_adresse => EX_adresse, -- Result of the calculation of the address |
EX_adresse_p1p2 => ex_adresse_p1p2_s, --resultado do calculo do endereco do desvio + 4 para pipe 2. 12-08-2018 |
EX_bra_confirm => EX_bra_confirm, -- Confirmacao do branch no pipe 1 (26-07-18) |
EX_adr_reg_dest => EX_adr_reg_dest, -- Destination register address for the result |
EX_ecr_reg => EX_ecr_reg, -- Effective writing of the result |
EX_op_mem => EX_op_mem, -- Memory operation needed |
EX_r_w => EX_r_w, -- Type of memory operation (read or write) |
EX_exc_cause => EX_exc_cause, -- Potential exception cause |
EX_level => EX_level, -- Availability stage for the result for bypassing |
EX_it_ok => EX_it_ok, -- Allow hardware interruptions |
|
-- Synchronous outputs for bypass unit |
MEM_adr => MEM_adr, -- Instruction address |
MEM_adr_reg_dest=>MEM_adr_reg_dest, -- Destination register address |
MEM_ecr_reg => MEM_ecr_reg, -- Writing of the destination register |
MEM_data_ecr => MEM_data_ecr, -- Data to write (from alu or memory) |
MEM_exc_cause => MEM_exc_cause, -- Potential exception cause |
MEM_level => MEM_level, -- Availability stage for the result for bypassing |
MEM_it_ok => MEM_it_ok, -- Allow hardware interruptions |
-- duplicacao |
-- Interface with the control bus |
MTC_data2 => MTC_data2, -- Data to write in memory |
MTC_adr2 => MTC_adr2, -- Address for memory |
MTC_r_w2 => MTC_r_w2, -- Read/Write in memory |
MTC_req2 => MTC_req2, -- Request access to memory |
CTM_data2 => CTM_data2, -- Data from memory |
|
-- Datas from Execution 2 stage |
EX_adr2 => EX_adr2, -- Instruction address |
EX_data_ual2 => EX_data_ual2, -- Result of alu operation |
EX_adresse2 => EX_adresse2, -- Result of the calculation of the address |
EX_adresse_p2p1 => ex_adresse_p2p1_s, --resultado do calculo do endereco do desvio + 4 para pipe 1. 12-08-2018 |
EX_bra_confirm2 => EX_bra_confirm2, -- Confirmacao do branch no pipe 2 (26-07-18) |
EX_adr_reg_dest2 => EX_adr_reg_dest2, -- Destination register address for the result |
EX_ecr_reg2 => EX_ecr_reg2, -- Effective writing of the result |
EX_op_mem2 => EX_op_mem2, -- Memory operation needed |
EX_r_w2 => EX_r_w2, -- Type of memory operation (read or write) |
EX_exc_cause2 => EX_exc_cause2, -- Potential exception cause |
EX_level2 => EX_level2, -- Availability stage for the result for bypassing |
EX_it_ok2 => EX_it_ok2, -- Allow hardware interruptions |
|
-- Synchronous outputs for bypass unit |
MEM_adr2 => MEM_adr2, -- Instruction address |
MEM_adr_reg_dest2=>MEM_adr_reg_dest2, -- Destination register address |
MEM_ecr_reg2 => MEM_ecr_reg2, -- Writing of the destination register |
MEM_data_ecr2 => MEM_data_ecr2, -- Data to write (from alu or memory) |
MEM_exc_cause2 => MEM_exc_cause2, -- Potential exception cause |
MEM_level2 => MEM_level2, -- Availability stage for the result for bypassing |
MEM_it_ok2 => MEM_it_ok2 -- Allow hardware interruptions |
); |
|
|
U6_renvoi : renvoi port map ( |
-- Register access signals |
adr1 => adr_reg1, -- Operand 1 address |
adr2 => adr_reg2, -- Operand 2 address |
use1 => use1, -- Operand 1 utilisation |
use2 => use2, -- Operand 2 utilisation |
|
data1 => data1, -- First register value |
data2 => data2, -- Second register value |
alea => alea, -- Unresolved hazards detected |
|
-- Bypass signals of the intermediary datas |
DI_level => DI_level, -- Availability level of the data |
DI_adr => DI_adr_reg_dest, -- Register destination of the result |
DI_ecr => DI_ecr_reg, -- Writing register request |
DI_data => DI_op2, -- Data to used |
|
EX_level => EX_level, -- Availability level of the data |
EX_adr => EX_adr_reg_dest, -- Register destination of the result |
EX_ecr => EX_ecr_reg, -- Writing register request |
EX_data => EX_data_ual, -- Data to used |
|
MEM_level => MEM_level, -- Availability level of the data |
MEM_adr => MEM_adr_reg_dest, -- Register destination of the result |
MEM_ecr => MEM_ecr_reg, -- Writing register request |
MEM_data => MEM_data_ecr, -- Data to used |
|
interrupt => interrupt, -- Exceptions or interruptions |
|
-- Connexion to the differents bank of register |
|
-- Writing commands for writing in the registers |
write_data => write_data, -- Data to write |
write_adr => write_adr, -- Address of the register to write |
write_GPR => write_GPR, -- Selection in the internal registers |
write_SCP => write_SCP, -- Selection in the coprocessor system registers |
|
-- Reading commands for Reading in the registers |
read_adr1 => read_adr1, -- Address of the first register to read |
read_adr2 => read_adr2, -- Address of the second register to read |
read_data1_GPR => read_data1_GPR, -- Value of operand 1 from the internal registers |
read_data1_SCP => read_data1_SCP, -- Value of operand 2 from the internal registers |
read_data2_GPR => read_data2_GPR, -- Value of operand 1 from the coprocessor system registers |
read_data2_SCP => read_data2_SCP, -- Value of operand 2 from the coprocessor system registers |
-- duplicacao |
-- Register access signals |
adr3 => adr_reg3, -- Operand 1 address |
adr4 => adr_reg4, -- Operand 2 address |
use12 => use3, -- Operand 1 utilisation |
use22 => use4, -- Operand 2 utilisation |
|
data3 => data3, -- First register value |
data4 => data4, -- Second register value |
alea2 => alea2, -- Unresolved hazards detected |
|
-- Bypass signals of the intermediary datas |
DI_level2 => DI_level2, -- Availability level of the data |
DI_adr2 => DI_adr_reg_dest2, -- Register destination of the result |
DI_ecr2 => DI_ecr_reg2, -- Writing register request |
DI_data2 => DI_op4, -- Data to used |
|
EX_level2 => EX_level2, -- Availability level of the data |
EX_adr2 => EX_adr_reg_dest2, -- Register destination of the result |
EX_ecr2 => EX_ecr_reg2, -- Writing register request |
EX_data2 => EX_data_ual2, -- Data to used |
|
MEM_level2 => MEM_level2, -- Availability level of the data |
MEM_adr2 => MEM_adr_reg_dest2, -- Register destination of the result |
MEM_ecr2 => MEM_ecr_reg2, -- Writing register request |
MEM_data2 => MEM_data_ecr2, -- Data to used |
|
-- Connexion to the differents bank of register |
|
-- Writing commands for writing in the registers |
write_data2 => write_data2, -- Data to write |
write_adr2 => write_adr2, -- Address of the register to write |
write_GPR2 => write_GPR2, -- Selection in the internal registers |
--write_SCP2 => write_SCP, -- Selection in the coprocessor system registers |
|
-- Reading commands for Reading in the registers |
read_adr3 => read_adr3, -- Address of the first register to read |
read_adr4 => read_adr4, -- Address of the second register to read |
read_data3_GPR => read_data3_GPR, -- Value of operand 1 from the internal registers |
read_data3_SCP => read_data3_SCP, -- Value of operand 2 from the internal registers |
read_data4_GPR => read_data4_GPR, -- Value of operand 1 from the coprocessor system registers |
read_data4_SCP => read_data4_SCP -- Value of operand 2 from the coprocessor system registers |
); |
|
|
U7_banc : banc port map( |
clock => clock, |
clock2 => clock2, |
reset => reset, |
|
-- Register addresses to read |
reg_src1 => read_adr1, |
reg_src2 => read_adr2, |
|
-- Register address to write and its data |
reg_dest => write_adr, |
donnee => write_data, |
|
-- Write signal |
cmd_ecr => write_GPR, |
|
-- Bank outputs |
data_src1 => read_data1_GPR, |
data_src2 => read_data2_GPR, |
|
-- Register addresses to read |
reg_src3 => read_adr3, |
reg_src4 => read_adr4, |
|
-- Register address to write and its data |
reg_dest2 => write_adr2, |
donnee2 => write_data2, |
|
-- Write signal |
cmd_ecr2 => write_GPR2, |
|
-- Bank outputs |
data_src3 => read_data3_GPR, |
data_src4 => read_data4_GPR |
); |
|
|
U8_syscop : syscop port map ( |
clock => clock, |
reset => reset, |
|
-- Datas from the pipeline |
MEM_adr => MEM_adr, -- Address (PC) of the current instruction in the pipeline end -> responsible of the exception |
MEM_exc_cause => MEM_exc_cause, -- Potential cause exception of that instruction |
MEM_it_ok => MEM_it_ok, -- Allow hardware interruptions |
|
-- Hardware interruption |
it_mat => it_mat_clk, -- Hardware interruption detected |
|
-- Interruption controls |
interrupt => interrupt, -- Interruption to take into account |
vecteur_it => vecteur_it, -- Interruption vector |
|
-- Writing request in register bank |
write_data => write_data, -- Data to write |
write_adr => write_adr, -- Address of the register to write |
write_SCP => write_SCP, -- Writing request |
|
-- Reading request in register bank |
read_adr1 => read_adr1, -- Address of the first register |
read_adr2 => read_adr2, -- Address of the second register |
read_data1 => read_data1_SCP, -- Value of register 1 |
read_data2 => read_data2_SCP, -- Value of register 2 |
--mod |
MEM_adr2 => MEM_adr2, |
MEM_exc_cause2 => MEM_exc_cause2, |
MEM_it_ok2 => MEM_it_ok2, |
|
write_data2 => write_data2, |
write_adr2 => write_adr2, |
write_SCP2 => zero, |
|
read_adr3 => read_adr3, |
read_adr4 => read_adr4, |
read_data3 => read_data3_SCP, |
read_data4 => read_data4_SCP |
); |
|
|
U9_bus_ctrl01 : bus_ctrl01 port map ( |
clock => clock, |
reset => reset, |
|
-- Interruption in the pipeline |
interrupt => interrupt, |
|
-- Interface for the Instruction Extraction Stage |
adr_from_ei => ETC_adr, -- The address of the data to read |
instr_to_ei => CTE_instr, -- Instruction from the memory |
-- Interface with the MEMory Stage |
req_from_mem => MTC_req, -- Request to access the ram |
r_w_from_mem => MTC_r_w, -- Read/Write request |
adr_from_mem => MTC_adr, -- Address in ram |
data_from_mem => MTC_data, -- Data to write in ram |
data_to_mem => CTM_data, -- Data from the ram to the MEMory stage |
|
-- RAM interface signals |
req_to_ram => ram_req, -- Request to ram |
adr_to_ram => ram_adr, -- Address of the data to read or write |
r_w_to_ram => ram_r_w, -- Read/Write request |
ack_from_ram => ram_ack, -- Acknowledge from the memory |
data_inout_ram => ram_data, -- Data from/to the memory |
|
-- Pipeline progress control signal |
stop_all => stop_all |
); |
|
|
U10_ei_2 : pps_ei_2 port map ( |
clock => clock2, |
reset => reset, |
clear => interrupt, -- Clear the pipeline stage |
stop_all2 => stop_all2, -- Evolution locking signal |
|
-- Asynchronous inputs |
stop_ei => alea2EI2, -- Lock the EI_adr and Ei_instr registers |
genop => genop2, -- Send nops |
|
-- interface Controler - EI |
CTE_instr => CTE_instr2, -- Instruction from the memory |
ETC_adr => ETC_adr2, -- Address to read in memory (ja feito pelo EI) |
|
-- Synchronous inputs from PF stage |
PF_pc => PF_pc_4, -- Current value of the pc + 4 |
|
-- Synchronous outputs to DI stage |
EI_instr => EI_instr2, -- Read interface |
EI_adr => EI_adr2, -- Address from the read instruction |
EI_it_ok => EI_it_ok2 -- Allow hardware interruptions |
); |
|
|
U11_di2 : pps_di_2 port map ( |
clock => clock2, |
reset => reset, |
stop_all2 => stop_all2, -- Unconditionnal locking of the outputs |
clear => interrupt, -- Clear the pipeline stage (nop in the outputs) |
|
-- Asynchronous outputs |
bra_detect => bra_detect2, -- Branch detection in the current instruction |
|
-- Asynchronous connexion with the register management and data bypass unit |
adr_reg1 => adr_reg3, -- Address of the first register operand |
adr_reg2 => adr_reg4, -- Address of the second register operand |
use1 => use3, -- Effective use of operand 1 |
use2 => use4, -- Effective use of operand 2 |
--iload2 => iload2, |
istore2 => istore2, |
stop_di => alea2DI2, -- Unresolved detected : send nop in the pipeline |
data1 => data3, -- Operand register 1 |
data2 => data4, -- Operand register 2 |
|
-- Datas from EI stage |
EI_adr => EI_adr2, -- Address of the instruction |
EI_instr => EI_instr2, -- The instruction to decode |
EI_it_ok => EI_it_ok2, -- Allow hardware interruptions |
|
-- Synchronous output to EX2 stage |
DI_bra => DI_bra2, -- Branch decoded |
DI_link => DI_link2, -- A link for that instruction |
DI_op1 => DI_op3, -- operand 1 for alu |
DI_op2 => DI_op4, -- operand 2 for alu |
DI_code_ual => DI_code_ual2, -- Alu operation |
DI_offset => DI_offset2, -- Offset for the address calculation |
DI_adr_reg_dest => DI_adr_reg_dest2, -- Address of the destination register of the result |
DI_ecr_reg => DI_ecr_reg2, -- Effective writing of the result |
DI_mode => DI_mode2, -- Address mode (relative to pc or indexed to a register) |
DI_op_mem => DI_op_mem2, -- Memory operation request |
DI_r_w => DI_r_w2, -- Type of memory operation (reading or writing) |
DI_adr => DI_adr2, -- Address of the decoded instruction |
DI_exc_cause => DI_exc_cause2, -- Potential exception detected |
DI_level => DI_level2, -- Availability of the result for the data bypass |
DI_it_ok => DI_it_ok2 -- Allow hardware interruptions |
); |
|
|
U12_ex2 : pps_ex_2 port map ( |
clock => clock, |
clock2 => clock2, |
reset => reset, |
stop_all => stop_all, |
stop_all2 => stop_all2, -- Unconditionnal locking of outputs |
clear => interrupt, -- Clear the pipeline stage |
|
-- Datas from DI2 stage |
DI_bra => DI_bra2, -- Branch instruction |
DI_link => DI_link2, -- Branch with link |
DI_op1 => DI_op3, -- Operand 1 for alu |
DI_op2 => DI_op4, -- Operand 2 for alu |
DI_code_ual => DI_code_ual2, -- Alu operation |
DI_offset => DI_offset2, -- Offset for address calculation |
DI_adr_reg_dest => DI_adr_reg_dest2, -- Destination register address for the result |
DI_ecr_reg => DI_ecr_reg2, -- Effective writing of the result |
DI_mode => DI_mode2, -- Address mode (relative to pc ou index by a register) |
DI_op_mem => DI_op_mem2, -- Memory operation |
DI_r_w => DI_r_w2, -- Type of memory operation (read or write) |
DI_adr => DI_adr2, -- Instruction address |
DI_exc_cause => DI_exc_cause2, -- Potential cause exception |
DI_level => DI_level2, -- Availability stage of the result for bypassing |
DI_it_ok => DI_it_ok2, -- Allow hardware interruptions |
EX2_data_hilo => ex2_data_hilo, -- saida p resultado do hilo p2 |
EX_data_hilo => ex_data_hilo, -- entrada p resultado do hilo p1 |
-- Synchronous outputs to MEM stage |
EX_adr => EX_adr2, -- Instruction address |
EX_bra_confirm => EX_bra_confirm2, -- Branch execution confirmation |
EX_data_ual => EX_data_ual2, -- Ual result |
EX_adresse => EX_adresse2, -- Address calculation result |
EX_adresse_p2p1 => ex_adresse_p2p1_s, --resultado do calculo do endereco do desvio + 4 para pipe 1. 12-08-2018 |
EX_adr_reg_dest => EX_adr_reg_dest2, -- Destination register for the result |
EX_ecr_reg => EX_ecr_reg2, -- Effective writing of the result |
EX_op_mem => EX_op_mem2, -- Memory operation needed |
EX_r_w => EX_r_w2, -- Type of memory operation (read or write) |
EX_exc_cause => EX_exc_cause2, -- Potential cause exception |
EX_level => EX_level2, -- Availability stage of result for bypassing |
EX_it_ok => EX_it_ok2 -- Allow hardware interruptions |
); |
|
U13_bus_ctrl02 : bus_ctrl02 port map ( |
clock => clock2, |
reset => reset, |
|
-- Interruption in the pipeline |
interrupt => interrupt, |
|
-- Interface for the Instruction Extraction Stage |
adr_from_ei => ETC_adr2, -- The address of the data to read |
instr_to_ei => CTE_instr2, -- Instruction from the memory |
-- Interface with the MEMory Stage |
req_from_mem => MTC_req2, -- Request to access the ram |
r_w_from_mem => MTC_r_w2, -- Read/Write request |
adr_from_mem => MTC_adr2, -- Address in ram |
data_from_mem => MTC_data2, -- Data to write in ram |
data_to_mem => CTM_data2, -- Data from the ram to the MEMory stage |
|
-- RAM interface signals |
req_to_ram => ram_req2, -- Request to ram |
adr_to_ram => ram_adr2, -- Address of the data to read or write |
r_w_to_ram => ram_r_w2, -- Read/Write request |
ack_from_ram => ram_ack2, -- Acknowledge from the memory |
data_inout_ram => ram_data2, -- Data from/to the memory |
|
-- Pipeline progress control signal |
stop_all => stop_all2 |
); |
|
U14_clock_gate : clock_gate port map ( |
clock_in1 => clock, |
clock_in2 => clock2, |
clock_out1 => clock_out1, |
clock_out2 => clock_out2, |
gate1 => zero, |
gate2 => zero |
); |
|
U15_delay_gate : delay_gate port map ( |
clock => clock, |
in1 => DI_bra, |
in2 => bra_detect, |
in3 => EX_bra_confirm, |
in4 => alea, |
in5 => alea2, |
in6 => EX_bra_confirm2, |
in7 => bra_detect2, |
in8 => DI_bra2, |
in9 => istore, |
in10 => istore2, |
in11 => zero, |
in12 => zero, |
out1 => DI_bra_D, |
out2 => bra_detect_D, |
out3 => EX_bra_confirm_D, |
out4 => alea_D, |
out5 => alea2_D, |
out6 => EX_bra_confirm2_D, |
out7 => bra_detect2_D, |
out8 => DI_bra2_D, |
out9 => istore_D, |
out10 => istore2_D, |
out11 => iload, |
out12 => iload_D |
); |
end rtl; |
/P0/sources/pack_mips.vhd
0,0 → 1,718
------------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Enumerations and components declarations -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
------------------------------------------------------------------------------- |
|
|
library ieee; |
use ieee.std_logic_1164.all; |
|
package pack_mips is |
|
-- Type signal on n bits |
subtype bus64 is std_logic_vector(63 downto 0); |
subtype bus33 is std_logic_vector(32 downto 0); |
subtype bus32 is std_logic_vector(31 downto 0); |
subtype bus31 is std_logic_vector(30 downto 0); |
subtype bus26 is std_logic_vector(25 downto 0); |
subtype bus24 is std_logic_vector(23 downto 0); |
subtype bus16 is std_logic_vector(15 downto 0); |
subtype bus8 is std_logic_vector(7 downto 0); |
subtype bus7 is std_logic_vector(6 downto 0); |
subtype bus6 is std_logic_vector(5 downto 0); |
subtype bus5 is std_logic_vector(4 downto 0); |
subtype bus4 is std_logic_vector(3 downto 0); |
subtype bus2 is std_logic_vector(1 downto 0); |
subtype bus1 is std_logic; |
|
-- Address of a register type |
subtype adr_reg_type is std_logic_vector(5 downto 0); |
|
-- Coding of the level of data availability for UR |
subtype level_type is std_logic_vector(2 downto 0); |
constant LVL_DI2 : level_type := "110"; -- Data available from the op2 of DI2 stage |
constant LVL_EX2 : level_type := "101"; -- Data available from the data_ual register of EX2 stage |
constant LVL_MEM2 : level_type := "100"; -- Data available from the data_ecr register of MEM2 stage |
constant LVL_DI : level_type := "011"; -- Data available from the op2 of DI stage |
constant LVL_EX : level_type := "010"; -- Data available from the data_ual register of EX stage |
constant LVL_MEM : level_type := "001"; -- Data available from the data_ecr register of MEM stage |
constant LVL_REG : level_type := "000"; -- Data available only in the register bank |
|
-- Different values of cause exceptions |
constant IT_NOEXC : bus32 := X"00000000"; |
constant IT_ITMAT : bus32 := X"00000001"; |
constant IT_OVERF : bus32 := X"00000002"; |
constant IT_ERINS : bus32 := X"00000004"; |
constant IT_BREAK : bus32 := X"00000008"; |
constant IT_SCALL : bus32 := X"00000010"; |
|
|
-- Operation type of the coprocessor system (only the low 16 bits are valid) |
constant SYS_NOP : bus32 := X"0000_0000"; |
constant SYS_MASK : bus32 := X"0000_0001"; |
constant SYS_UNMASK : bus32 := X"0000_0002"; |
constant SYS_ITRET : bus32 := X"0000_0004"; |
|
-- Type for the alu control |
subtype alu_ctrl_type is std_logic_vector(27 downto 0); |
|
-- Arithmetical operations |
|
|
|
|
-- Logical operations |
constant OP_AND : alu_ctrl_type := "0000100000000000000000000000"; -- et logique |
constant OP_OR : alu_ctrl_type := "0000010000000000000000000000"; -- ou logique |
constant OP_XOR : alu_ctrl_type := "0000001000000000000000000000"; -- ou exclusif logique |
constant OP_NOR : alu_ctrl_type := "0000000100000000000000000000"; -- non ou logique |
-- Tests : result to one if ok |
|
|
constant OP_EQU : alu_ctrl_type := "0000000000100000000000000000"; -- op1 = op2 |
constant OP_NEQU : alu_ctrl_type := "0000000000010000000000000000"; -- op1 /= op2 |
constant OP_SNEG : alu_ctrl_type := "0000000000001000000000000000"; -- op1 < 0 |
constant OP_SPOS : alu_ctrl_type := "0000000000000100000000000000"; -- op1 > 0 |
constant OP_LNEG : alu_ctrl_type := "0000000000000010000000000000"; -- op1 <= 0 |
constant OP_LPOS : alu_ctrl_type := "0000000000000001000000000000"; -- op1 >= 0 |
-- Multiplications |
|
constant OP_MULT2 : alu_ctrl_type := "0000000000000000000000000000"; -- op1 * op2 sign - MULT2 25.05.18 - Miguel |
|
-- Shifts |
constant OP_SLL : alu_ctrl_type := "0000000000000000001000000000"; -- decallage logique a gauche |
constant OP_SRL : alu_ctrl_type := "0000000000000000000100000000"; -- decallage logique a droite |
constant OP_SRA : alu_ctrl_type := "0000000000000000000010000000"; -- decallage arithmetique a droite |
constant OP_LUI : alu_ctrl_type := "0000000000000000000001000000"; -- met en poids fort la valeur immediate |
-- Access to internal registers |
constant OP_MFHI : alu_ctrl_type := "0000000000000000000000100000"; -- lecture des poids forts |
constant OP_MFLO : alu_ctrl_type := "0000000000000000000000010000"; -- lecture des poids faibles |
constant OP_MTHI : alu_ctrl_type := "0000000000000000000000001000"; -- ecriture des poids forts |
constant OP_MTLO : alu_ctrl_type := "0000000000000000000000000100"; -- ecriture des poids faibles |
-- Operations which do nothing but are useful |
constant OP_OUI : alu_ctrl_type := "0000000000000000000000000010"; -- met a 1 le bit de poids faible en sortie |
constant OP_OP2 : alu_ctrl_type := "0000000000000000000000000001"; -- recopie l'operande 2 en sortie |
|
|
|
-- Starting boot address (after reset) |
constant ADR_INIT : bus32 := X"00000000"; |
constant ADR_INIT4 : bus32 := X"00000004"; |
constant INS_NOP : bus32 := X"00000000"; |
|
constant zero : bus1 := '0'; |
-- Internal component of the pipeline stage |
|
component alu |
port ( |
clock : in bus1; |
reset : in bus1; |
op1 : in bus32; |
op2 : in bus32; |
ctrl : in alu_ctrl_type; |
hilo_p2 : in bus64; |
hilo_p1p2 : out bus64; |
res : out bus32; |
overflow : out bus1 |
); |
end component; |
|
component alu2 |
port ( |
clock : in bus1; |
reset : in bus1; |
op1 : in bus32; |
op2 : in bus32; |
ctrl : in alu_ctrl_type; |
hilo_p1 : in bus64; |
hilo_p2p1 : out bus64; |
res : out bus32; |
overflow : out bus1 |
); |
end component; |
|
-- Pipeline stage components |
|
component pps_pf |
port ( |
clock : in bus1; |
clock2 : in bus1; |
reset : in bus1; |
stop_all : in bus1; |
stop_all2: in bus1; |
|
bra_cmd : in bus1; |
bra_adr : in bus32; |
exch_cmd : in bus1; |
exch_adr : in bus32; |
|
bra_cmd2 : in bus1; |
bra_adr2 : in bus32; |
exch_cmd2 : in bus1; |
exch_adr2 : in bus32; |
|
stop_pf : in bus1; |
stop_pf2 : in bus1; |
PF_pc : out bus32; |
PF_pc_4 : out bus32 |
); |
end component; |
|
component clock_gate |
port ( |
clock_in1 : in bus1; |
clock_in2 : in bus1; |
clock_out1 : out bus1; |
clock_out2 : out bus1; |
gate1 : in bus1; |
gate2 : in bus1 |
); |
end component; |
|
component delay_gate |
port ( |
clock : in bus1; |
in1 : in bus1; |
in2 : in bus1; |
in3 : in bus1; |
in4 : in bus1; |
in5 : in bus1; |
in6 : in bus1; |
in7 : in bus1; |
in8 : in bus1; |
in9 : in bus1; |
in10 : in bus1; |
in11 : in bus1; |
in12 : in bus1; |
out1 : out bus1; |
out2 : out bus1; |
out3 : out bus1; |
out4 : out bus1; |
out5 : out bus1; |
out6 : out bus1; |
out7 : out bus1; |
out8 : out bus1; |
out9 : out bus1; |
out10 : out bus1; |
out11 : out bus1; |
out12 : out bus1 |
); |
end component; |
|
component pps_ei |
port ( |
clock : in bus1; |
reset : in bus1; |
clear : in bus1; |
stop_all : in bus1; |
|
stop_ei : in bus1; |
genop : in bus1; |
|
CTE_instr : in bus32; |
ETC_adr : out bus32; |
|
PF_pc : in bus32; |
|
EI_instr : out bus32; |
EI_adr : out bus32; |
EI_it_ok : out bus1 |
); |
end component; |
|
component pps_ei_2 |
port ( |
clock : in bus1; |
reset : in bus1; |
clear : in bus1; |
stop_all2 : in bus1; |
|
stop_ei : in bus1; |
genop : in bus1; |
|
CTE_instr : in bus32; |
ETC_adr : out bus32; |
|
PF_pc : in bus32; |
|
EI_instr : out bus32; |
EI_adr : out bus32; |
EI_it_ok : out bus1 |
); |
end component; |
|
component pps_di |
port ( |
clock : in bus1; |
reset : in bus1; |
stop_all : in bus1; |
clear : in bus1; |
|
bra_detect : out bus1; |
|
adr_reg1 : out adr_reg_type; |
adr_reg2 : out adr_reg_type; |
use1 : out bus1; |
use2 : out bus1; |
--iload : out bus1; |
istore : out bus1; |
stop_di : in bus1; |
data1 : in bus32; |
data2 : in bus32; |
|
EI_adr : in bus32; |
EI_instr : in bus32; |
EI_it_ok : in bus1; |
|
DI_bra : out bus1; |
DI_link : out bus1; |
DI_op1 : out bus32; |
DI_op2 : out bus32; |
DI_code_ual : out alu_ctrl_type; |
DI_offset : out bus32; |
DI_adr_reg_dest : out adr_reg_type; |
DI_ecr_reg : out bus1; |
DI_mode : out bus1; |
DI_op_mem : out bus1; |
DI_r_w : out bus1; |
DI_adr : out bus32; |
DI_exc_cause : out bus32; |
DI_level : out level_type; |
DI_it_ok : out bus1 |
--DI_SRC1 : out adr_reg_type; |
--DI_SRC2 : out adr_reg_type |
); |
end component; |
|
component pps_di_2 |
port ( |
clock : in bus1; |
reset : in bus1; |
stop_all2 : in bus1; |
clear : in bus1; |
|
bra_detect : out bus1; |
|
adr_reg1 : out adr_reg_type; |
adr_reg2 : out adr_reg_type; |
use1 : out bus1; |
use2 : out bus1; |
--iload2 : out bus1; |
istore2 : out bus1; |
stop_di : in bus1; |
data1 : in bus32; |
data2 : in bus32; |
|
EI_adr : in bus32; |
EI_instr : in bus32; |
EI_it_ok : in bus1; |
|
DI_bra : out bus1; |
DI_link : out bus1; |
DI_op1 : out bus32; |
DI_op2 : out bus32; |
DI_code_ual : out alu_ctrl_type; |
DI_offset : out bus32; |
DI_adr_reg_dest : out adr_reg_type; |
DI_ecr_reg : out bus1; |
DI_mode : out bus1; |
DI_op_mem : out bus1; |
DI_r_w : out bus1; |
DI_adr : out bus32; |
DI_exc_cause : out bus32; |
DI_level : out level_type; |
DI_it_ok : out bus1 |
--DI2_SRC3 : out adr_reg_type; |
--DI2_SRC4 : out adr_reg_type |
); |
end component; |
|
component pps_ex |
port ( |
clock : in bus1; |
clock2 : in bus1; |
reset : in bus1; |
stop_all : in bus1; |
stop_all2 : in bus1; |
clear : in bus1; |
|
DI_bra : in bus1; |
DI_link : in bus1; |
DI_op1 : in bus32; |
DI_op2 : in bus32; |
DI_code_ual : in alu_ctrl_type; |
DI_offset : in bus32; |
DI_adr_reg_dest : in adr_reg_type; |
DI_ecr_reg : in bus1; |
DI_mode : in bus1; |
DI_op_mem : in bus1; |
DI_r_w : in bus1; |
DI_adr : in bus32; |
DI_exc_cause : in bus32; |
DI_level : in level_type; |
DI_it_ok : in bus1; |
EX2_data_hilo : in bus64; |
EX_data_hilo : out bus64; |
EX_adr : out bus32; |
EX_bra_confirm : out bus1; |
EX_data_ual : out bus32; |
EX_adresse : out bus32; |
EX_adresse_p1p2 : out bus32; |
EX_adr_reg_dest : out adr_reg_type; |
EX_ecr_reg : out bus1; |
EX_op_mem : out bus1; |
EX_r_w : out bus1; |
EX_exc_cause : out bus32; |
EX_level : out level_type; |
EX_it_ok : out bus1 |
-- EX_SRC1 : out adr_reg_type; |
-- EX_SRC2 : out adr_reg_type |
|
); |
end component; |
|
component pps_ex_2 |
port( |
clock : in bus1; |
clock2 : in bus1; |
reset : in bus1; |
stop_all : in bus1; |
stop_all2 : in bus1; -- Unconditionnal locking of outputs |
clear : in bus1; -- Clear the pipeline stage |
|
-- Datas from DI stage |
DI_bra : in bus1; -- Branch instruction |
DI_link : in bus1; -- Branch with link |
DI_op1 : in bus32; -- Operand 1 for alu |
DI_op2 : in bus32; -- Operand 2 for alu |
DI_code_ual : in alu_ctrl_type; -- Alu operation |
DI_offset : in bus32; -- Offset for address calculation |
DI_adr_reg_dest : in adr_reg_type; -- Destination register address for the result |
DI_ecr_reg : in bus1; -- Effective writing of the result |
DI_mode : in bus1; -- Address mode (relative to pc ou index by a register) |
DI_op_mem : in bus1; -- Memory operation |
DI_r_w : in bus1; -- Type of memory operation (read or write) |
DI_adr : in bus32; -- Instruction address |
DI_exc_cause : in bus32; -- Potential cause exception |
DI_level : in level_type; -- Availability stage of the result for bypassing |
DI_it_ok : in bus1; -- Allow hardware interruptions |
|
EX_data_hilo : in bus64;--resultado da multiplicacao do pieline 1 |
EX2_data_hilo : out bus64; |
-- Synchronous outputs to MEM stage |
EX_adr : out bus32; -- Instruction address |
EX_bra_confirm : out bus1; -- Branch execution confirmation |
EX_data_ual : out bus32; -- Ual result |
EX_adresse : out bus32; -- Address calculation result |
EX_adresse_p2p1 : out bus32;-- 12-08-2018 |
EX_adr_reg_dest : out adr_reg_type; -- Destination register for the result |
EX_ecr_reg : out bus1; -- Effective writing of the result |
EX_op_mem : out bus1; -- Memory operation needed |
EX_r_w : out bus1; -- Type of memory operation (read or write) |
EX_exc_cause : out bus32; -- Potential cause exception |
EX_level : out level_type; -- Availability stage of result for bypassing |
EX_it_ok : out bus1 -- Allow hardware interruptions |
); |
end component; |
|
component pps_mem |
port ( |
clock : in bus1; |
clock2 : in bus1; |
reset : in bus1; |
stop_all : in bus1; |
stop_all2 : in bus1; |
|
clear : in bus1; |
|
MTC_data : out bus32; |
MTC_adr : out bus32; |
MTC_r_w : out bus1; |
MTC_req : out bus1; |
CTM_data : in bus32; |
|
EX_adr : in bus32; |
EX_data_ual : in bus32; |
EX_adresse : in bus32; |
EX_adresse_p1p2 : in bus32;-- 12-08-2018 |
EX_bra_confirm : in bus1;-- Confirmacao do branch no pipe 1 (26-07-18) |
EX_adr_reg_dest : in adr_reg_type; |
EX_ecr_reg : in bus1; |
EX_op_mem : in bus1; |
EX_r_w : in bus1; |
EX_exc_cause : in bus32; |
EX_level : in level_type; |
EX_it_ok : in bus1; |
|
MEM_adr : out bus32; |
MEM_adr_reg_dest : out adr_reg_type; |
MEM_ecr_reg : out bus1; |
MEM_data_ecr : out bus32; |
MEM_exc_cause : out bus32; |
MEM_level : out level_type; |
MEM_it_ok : out bus1; |
|
-- duplicacao |
MTC_data2 : out bus32; |
MTC_adr2 : out bus32; |
MTC_r_w2 : out bus1; |
MTC_req2 : out bus1; |
CTM_data2 : in bus32; |
|
EX_adr2 : in bus32; |
EX_data_ual2 : in bus32; |
EX_adresse2 : in bus32; |
EX_adresse_p2p1 : in bus32;-- 12-08-2018 |
EX_bra_confirm2 : in bus1;-- Confirmacao do branch no pipe 2 (26-07-18) |
EX_adr_reg_dest2 : in adr_reg_type; |
EX_ecr_reg2 : in bus1; |
EX_op_mem2 : in bus1; |
EX_r_w2 : in bus1; |
EX_exc_cause2 : in bus32; |
EX_level2 : in level_type; |
EX_it_ok2 : in bus1; |
|
MEM_adr2 : out bus32; |
MEM_adr_reg_dest2 : out adr_reg_type; |
MEM_ecr_reg2 : out bus1; |
MEM_data_ecr2 : out bus32; |
MEM_exc_cause2 : out bus32; |
MEM_level2 : out level_type; |
MEM_it_ok2 : out bus1 |
); |
end component; |
|
|
component renvoi |
port ( |
adr1 : in adr_reg_type; |
adr2 : in adr_reg_type; |
use1 : in bus1; |
use2 : in bus1; |
|
data1 : out bus32; |
data2 : out bus32; |
alea : out bus1; |
|
DI_level : in level_type; |
DI_adr : in adr_reg_type; |
DI_ecr : in bus1; |
DI_data : in bus32; |
|
EX_level : in level_type; |
EX_adr : in adr_reg_type; |
EX_ecr : in bus1; |
EX_data : in bus32; |
|
MEM_level : in level_type; |
MEM_adr : in adr_reg_type; |
MEM_ecr : in bus1; |
MEM_data : in bus32; |
|
interrupt : in bus1; |
|
write_data : out bus32; |
write_adr : out bus5; |
write_GPR : out bus1; |
write_SCP : out bus1; |
|
read_adr1 : out bus5; |
read_adr2 : out bus5; |
read_data1_GPR : in bus32; |
read_data1_SCP : in bus32; |
read_data2_GPR : in bus32; |
read_data2_SCP : in bus32; |
|
--duplicacao |
adr3 : in adr_reg_type; |
adr4 : in adr_reg_type; |
use12 : in bus1; |
use22 : in bus1; |
|
data3 : out bus32; |
data4 : out bus32; |
alea2 : out bus1; |
|
DI_level2 : in level_type; |
DI_adr2 : in adr_reg_type; |
DI_ecr2 : in bus1; |
DI_data2 : in bus32; |
|
EX_level2 : in level_type; |
EX_adr2 : in adr_reg_type; |
EX_ecr2 : in bus1; |
EX_data2 : in bus32; |
|
MEM_level2 : in level_type; |
MEM_adr2 : in adr_reg_type; |
MEM_ecr2 : in bus1; |
MEM_data2 : in bus32; |
|
write_data2 : out bus32; |
write_adr2 : out bus5; |
write_GPR2 : out bus1; |
--write_SCP2 : out bus1; |
|
read_adr3 : out bus5; |
read_adr4 : out bus5; |
read_data3_GPR : in bus32; |
read_data3_SCP : in bus32; |
read_data4_GPR : in bus32; |
read_data4_SCP : in bus32 |
); |
end component; |
|
|
component banc |
port ( |
clock : in bus1; |
clock2 : in bus1; |
reset : bus1; |
|
reg_src1 : in bus5; |
reg_src2 : in bus5; |
|
reg_dest : in bus5; |
donnee : in bus32; |
|
cmd_ecr : in bus1; |
|
data_src1 : out bus32; |
data_src2 : out bus32; |
|
reg_src3 : in bus5; |
reg_src4 : in bus5; |
|
reg_dest2 : in bus5; |
donnee2 : in bus32; |
|
cmd_ecr2 : in bus1; |
|
data_src3 : out bus32; |
data_src4 : out bus32 |
); |
end component; |
|
|
component bus_ctrl01 |
port |
( |
clock : bus1; |
reset : bus1; |
|
interrupt : in std_logic; |
|
adr_from_ei : in bus32; |
instr_to_ei : out bus32; |
req_from_mem : in bus1; |
r_w_from_mem : in bus1; |
adr_from_mem : in bus32; |
data_from_mem : in bus32; |
data_to_mem : out bus32; |
|
req_to_ram : out std_logic; |
adr_to_ram : out bus32; |
r_w_to_ram : out bus1; |
ack_from_ram : in bus1; |
data_inout_ram : inout bus32; |
|
stop_all : out bus1 |
); |
end component; |
|
component bus_ctrl02 |
port |
( |
clock : bus1; |
reset : bus1; |
|
interrupt : in std_logic; |
|
adr_from_ei : in bus32; |
instr_to_ei : out bus32; |
req_from_mem : in bus1; |
r_w_from_mem : in bus1; |
adr_from_mem : in bus32; |
data_from_mem : in bus32; |
data_to_mem : out bus32; |
|
req_to_ram : out std_logic; |
adr_to_ram : out bus32; |
r_w_to_ram : out bus1; |
ack_from_ram : in bus1; |
data_inout_ram : inout bus32; |
|
stop_all : out bus1 |
); |
end component; |
|
component syscop |
port |
( |
clock : in bus1; |
reset : in bus1; |
|
MEM_adr : in bus32; |
MEM_exc_cause : in bus32; |
MEM_it_ok : in bus1; |
|
it_mat : in bus1; |
|
interrupt : out bus1; |
vecteur_it : out bus32; |
|
write_data : in bus32; |
write_adr : in bus5; |
write_SCP : in bus1; |
|
read_adr1 : in bus5; |
read_adr2 : in bus5; |
read_data1 : out bus32; |
read_data2 : out bus32; |
--mod |
MEM_adr2 : in bus32; |
MEM_exc_cause2 : in bus32; |
MEM_it_ok2 : in bus1; |
|
write_data2 : in bus32; |
write_adr2 : in bus5; |
write_SCP2 : in bus1; |
|
read_adr3 : in bus5; |
read_adr4 : in bus5; |
read_data3 : out bus32; |
read_data4 : out bus32 |
); |
end component; |
|
|
component minimips |
port ( |
clock : in bus1; |
clock2 : in bus1; |
reset : in bus1; |
|
ram_req : out bus1; |
ram_adr : out bus32; |
ram_r_w : out bus1; |
ram_data : inout bus32; |
ram_ack : in bus1; |
|
ram_req2 : out bus1; |
ram_adr2 : out bus32; |
ram_r_w2 : out bus1; |
ram_data2 : inout bus32; |
ram_ack2 : in bus1; |
|
it_mat : in bus1 |
); |
end component; |
|
end pack_mips; |
/P0/sources/pps_di.vhd
0,0 → 1,395
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Instruction decoding stage -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity pps_di is |
port ( |
clock : in std_logic; |
reset : in std_logic; |
stop_all : in std_logic; -- Unconditionnal locking of the outputs |
clear : in std_logic; -- Clear the pipeline stage (nop in the outputs) |
|
-- Asynchronous outputs |
bra_detect : out std_logic; -- Branch detection in the current instruction |
istore : out std_logic; |
--iload : out std_logic; |
-- Asynchronous connexion with the register management and data bypass unit |
adr_reg1 : out adr_reg_type; -- Address of the first register operand |
adr_reg2 : out adr_reg_type; -- Address of the second register operand |
use1 : out std_logic; -- Effective use of operand 1 |
use2 : out std_logic; -- Effective use of operand 2 |
|
stop_di : in std_logic; -- Unresolved detected : send nop in the pipeline |
data1 : in bus32; -- Operand register 1 |
data2 : in bus32; -- Operand register 2 |
|
-- Datas from EI stage |
EI_adr : in bus32; -- Address of the instruction |
EI_instr : in bus32; -- The instruction to decode |
EI_it_ok : in std_logic; -- Allow hardware interruptions |
|
-- Synchronous output to EX stage |
DI_bra : out std_logic; -- Branch decoded |
DI_link : out std_logic; -- A link for that instruction |
DI_op1 : out bus32; -- operand 1 for alu |
DI_op2 : out bus32; -- operand 2 for alu |
DI_code_ual : out alu_ctrl_type; -- Alu operation |
DI_offset : out bus32; -- Offset for the address calculation |
DI_adr_reg_dest : out adr_reg_type; -- Address of the destination register of the result |
DI_ecr_reg : out std_logic; -- Effective writing of the result |
DI_mode : out std_logic; -- Address mode (relative to pc or indexed to a register) |
DI_op_mem : out std_logic; -- Memory operation request |
DI_r_w : out std_logic; -- Type of memory operation (reading or writing) |
DI_adr : out bus32; -- Address of the decoded instruction |
DI_exc_cause : out bus32; -- Potential exception detected |
DI_level : out level_type; -- Availability of the result for the data bypass |
DI_it_ok : out std_logic -- Allow hardware interruptions |
); |
end entity; |
|
|
architecture rtl of pps_di is |
|
-- Enumeration type used for the micro-code of the instruction |
type op_mode_type is (OP_NORMAL, OP_SPECIAL, OP_REGIMM, OP_COP0); -- selection du mode de l'instruction |
type off_sel_type is (OFS_PCRL, OFS_NULL, OFS_SESH, OFS_SEXT); -- selection de la valeur de l'offset |
type rdest_type is ( D_RT, D_RD, D_31, D_00); -- selection du registre destination |
|
-- Record type containg the micro-code of an instruction |
type micro_instr_type is |
record |
op_mode : op_mode_type; -- Instruction codop mode |
op_code : bus6; -- Instruction codop |
bra : std_logic; -- Branch instruction |
link : std_logic; -- Branch with link : the return address is saved in a register |
code_ual : alu_ctrl_type; -- Operation code for the alu |
op_mem : std_logic; -- Memory operation needed |
r_w : std_logic; -- Read/Write selection in memory |
mode : std_logic; -- Address calculation from the current pc ('1') or the alu operand 1 ('0') |
off_sel : off_sel_type; -- Offset source : PC(31..28) & Adresse & 00 || 0 || sgn_ext(Imm) & 00 || sgn_ext(Imm) |
exc_cause : bus32; -- Unconditionnal exception cause to generate |
cop_org1 : std_logic; -- Source register 1 : general register if 0, coprocessor register if 1 |
cop_org2 : std_logic; -- Source register 2 : general register if 0, coprocessor register if 1 |
cs_imm1 : std_logic; -- Use of immediat operand 1 instead of register bank |
cs_imm2 : std_logic; -- Use of immediat operand 2 instead of register bank |
imm1_sel : std_logic; -- Origine of immediat operand 1 |
imm2_sel : std_logic; -- Origine of immediat operand 2 |
level : level_type; -- Data availability stage for the bypass |
ecr_reg : std_logic; -- Writing the result in a register |
bank_des : std_logic; -- Register bank selection : GPR if 0, coprocessor system if 1 |
des_sel : rdest_type ; -- Destination register address : Rt, Rd, $31, $0 |
end record; |
|
type micro_code_type is array (natural range <>) of micro_instr_type; |
|
constant micro_code : micro_code_type := |
( -- Instruction decoding in micro-instructions table |
(OP_SPECIAL, "100000", '0', '0', OP_ADD , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- ADD |
(OP_NORMAL , "001000", '0', '0', OP_ADD , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- ADDI |
(OP_NORMAL , "001001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ADDIU |
(OP_SPECIAL, "100001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- ADDU |
(OP_SPECIAL, "100100", '0', '0', OP_AND , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- AND |
(OP_NORMAL , "001100", '0', '0', OP_AND , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ANDI |
(OP_NORMAL , "000100", '1', '0', OP_EQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- BEQ |
(OP_REGIMM , "000001", '1', '0', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BGEZ |
(OP_REGIMM , "010001", '1', '1', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_31), -- BGEZAL |
(OP_NORMAL , "000111", '1', '0', OP_SPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BGTZ |
(OP_NORMAL , "000110", '1', '0', OP_LNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BLEZ |
(OP_REGIMM , "000000", '1', '0', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BLTZ |
(OP_REGIMM , "010000", '1', '1', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_31), -- BLTZAL |
(OP_NORMAL , "000101", '1', '0', OP_NEQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- BNE |
(OP_SPECIAL, "001101", '0', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_BREAK, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- BREAK |
(OP_COP0 , "000001", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI , '1', '1', D_00), -- COP0 |
(OP_NORMAL , "000010", '1', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- J |
(OP_NORMAL , "000011", '1', '1', OP_OUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_31), -- JAL |
(OP_SPECIAL, "001001", '1', '1', OP_OUI , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- JALR |
(OP_SPECIAL, "001000", '1', '0', OP_OUI , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- JR |
(OP_NORMAL , "001111", '0', '0', OP_LUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- LUI |
(OP_NORMAL , "100011", '0', '0', OP_OUI , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM, '1', '0', D_RT), -- LW |
(OP_NORMAL , "110000", '0', '0', OP_OUI , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM, '1', '1', D_RT), -- LWC0 |
(OP_COP0 , "000000", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '1', '1', '0', '0', '0', LVL_DI , '1', '0', D_RD), -- MFC0 |
(OP_SPECIAL, "010000", '0', '0', OP_MFHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- MFHI |
(OP_SPECIAL, "010010", '0', '0', OP_MFLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX , '1', '0', D_RD), -- MFLO |
(OP_COP0 , "000100", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '0', '0', LVL_DI , '1', '1', D_RD), -- MTC0 |
(OP_SPECIAL, "010001", '0', '0', OP_MTHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- MTHI |
(OP_SPECIAL, "010011", '0', '0', OP_MTLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- MTLO |
(OP_SPECIAL, "011000", '0', '0', OP_MULT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '0', '0', D_RT), -- MULT |
(OP_SPECIAL, "011100", '0', '0', OP_MULT2, '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- MULT2 [RD = RS * RT] |
(OP_SPECIAL, "011001", '0', '0', OP_MULTU, '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '0', '0', D_RT), -- MULT |
(OP_SPECIAL, "100111", '0', '0', OP_NOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- NOR |
(OP_SPECIAL, "100101", '0', '0', OP_OR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- OR |
(OP_NORMAL , "001101", '0', '0', OP_OR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT), -- ORI |
(OP_SPECIAL, "000000", '0', '0', OP_SLL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SLL |
(OP_SPECIAL, "000100", '0', '0', OP_SLL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLLV |
(OP_SPECIAL, "101010", '0', '0', OP_SLT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLT |
(OP_NORMAL , "001010", '0', '0', OP_SLT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- SLTI |
(OP_NORMAL , "001011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX , '1', '0', D_RT), -- SLTIU |
(OP_SPECIAL, "101011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SLTU |
(OP_SPECIAL, "000011", '0', '0', OP_SRA , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SRA |
(OP_SPECIAL, "000111", '0', '0', OP_SRA , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SRAV |
(OP_SPECIAL, "000010", '0', '0', OP_SRL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX , '1', '0', D_RD), -- SRL |
(OP_SPECIAL, "000110", '0', '0', OP_SRL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SRLV |
(OP_SPECIAL, "100010", '0', '0', OP_SUB , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SUB |
(OP_SPECIAL, "100011", '0', '0', OP_SUBU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- SUBU |
(OP_NORMAL , "101011", '0', '0', OP_OP2 , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- SW |
(OP_NORMAL , "111000", '0', '0', OP_OP2 , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '1', '0', '0', '0', '0', LVL_DI , '0', '0', D_RT), -- SWC0 |
(OP_SPECIAL, "001100", '0', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_SCALL, '0', '0', '1', '1', '0', '0', LVL_DI , '0', '0', D_RT), -- SYSC |
(OP_SPECIAL, "100110", '0', '0', OP_XOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX , '1', '0', D_RD), -- XOR |
(OP_NORMAL , "001110", '0', '0', OP_XOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX , '1', '0', D_RT) -- XORI |
); |
|
-- Preparation of the synchronous outputs |
signal PRE_bra : std_logic; -- Branch operation |
signal PRE_link : std_logic; -- Branch with link |
signal PRE_op1 : bus32; -- operand 1 of the ual |
signal PRE_op2 : bus32; -- operand 2 of the ual |
signal PRE_code_ual : alu_ctrl_type; -- Alu operation |
signal PRE_offset : bus32; -- Address offset for calculation |
signal PRE_adr_reg_dest : adr_reg_type; -- Destination register adress for result |
signal PRE_ecr_reg : std_logic; -- Writing of result in the bank register |
signal PRE_mode : std_logic; -- Address calculation with current pc |
signal PRE_op_mem : std_logic; -- Memory access operation instruction |
signal PRE_r_w : std_logic; -- Read/write selection in memory |
signal PRE_exc_cause : bus32; -- Potential exception cause |
signal PRE_level : level_type; -- Result availability stage for bypass |
|
begin |
-- Instruction decoding |
process (EI_instr, EI_adr, data1, data2) |
variable op_code : bus6; -- Effective codop of the instruction |
variable op_mode : op_mode_type; -- Instruction mode |
variable flag : boolean; -- Is true if valid instruction |
variable instr : integer; -- Current micro-instruction adress |
|
-- Instruction fields |
variable rs : bus5; |
variable rt : bus5; |
variable rd : bus5; |
variable shamt : bus5; |
variable imm : bus16; |
variable address : bus26; |
begin |
|
-- Selection of the instruction codop and its mode |
case EI_instr(31 downto 26) is |
when "000000" => -- special mode |
op_mode := OP_SPECIAL; |
op_code := EI_instr(5 downto 0); -- JR, JALR, ... |
when "000001" => -- regimm mode |
op_mode := OP_REGIMM; |
op_code := '0' & EI_instr(20 downto 16); |
when "010000" => -- cop0 mode |
op_mode := OP_COP0; |
op_code := '0' & EI_instr(25 downto 21); |
when others => -- normal mode |
op_mode := OP_NORMAL; |
op_code := EI_instr(31 downto 26); |
end case; |
|
|
-- Search the current instruction in the micro-code table |
flag := false; |
instr := 0; |
for i in micro_code'range loop |
if micro_code(i).op_mode=op_mode and micro_code(i).op_code=op_code then |
flag := true; -- The instruction exists |
instr := i; -- Index memorisation |
end if; |
end loop; |
|
-- Read the instruction field |
rs := EI_instr(25 downto 21); |
rt := EI_instr(20 downto 16); |
rd := EI_instr(15 downto 11); |
shamt := EI_instr(10 downto 6); |
imm := EI_instr(15 downto 0); |
address := EI_instr(25 downto 0); |
|
if not flag then -- Unknown instruction |
|
-- Synchronous output preparation |
PRE_bra <= '0'; -- Branch operation |
PRE_link <= '0'; -- Branch with link |
PRE_op1 <= (others => '0'); -- operand 1 of the ual |
PRE_op2 <= (others => '0'); -- operand 2 of the ual |
PRE_code_ual <= OP_OUI; -- Alu operation |
PRE_offset <= (others => '0'); -- Address offset for calculation |
PRE_adr_reg_dest <= (others => '0'); -- Destination register adress for result |
PRE_ecr_reg <= '0'; -- Writing of result in the bank register |
PRE_mode <= '0'; -- Address calculation with current pc |
PRE_op_mem <= '0'; -- Memory access operation instruction |
PRE_r_w <= '0'; -- Read/write selection in memory |
PRE_exc_cause <= IT_ERINS; -- Potential exception cause |
PRE_level <= LVL_DI; -- Result availability stage for bypass |
|
-- Set asynchronous outputs |
adr_reg1 <= (others => '0'); -- First operand register |
adr_reg2 <= (others => '0'); -- Second operand register |
bra_detect <= '0'; -- Detection of a branch in current instruction |
use1 <= '0'; -- Effective use of operand 1 |
use2 <= '0'; -- Effective use of operand 2 |
istore <= '0'; |
|
else -- Valid instruction |
|
-- Offset signal preparation |
case micro_code(instr).off_sel is |
when OFS_PCRL => -- PC(31..28) & Adresse & 00 |
PRE_offset <= EI_adr(31 downto 28) & address & "00"; -- J, JAL |
when OFS_NULL => -- 0 |
PRE_offset <= (others => '0'); -- JR |
when OFS_SESH => -- sgn_ext(Imm) & 00 |
if imm(15)='1' then |
PRE_offset <= "11111111111111" & imm & "00"; |
else |
PRE_offset <= "00000000000000" & imm & "00"; |
end if; |
when OFS_SEXT => -- sgn_ext(Imm) |
if imm(15)='1' then |
PRE_offset <= "1111111111111111" & imm; |
else |
PRE_offset <= "0000000000000000" & imm; |
end if; |
end case; |
|
|
-- Alu operand preparation |
if micro_code(instr).cs_imm1='0' then |
-- Datas from register banks |
PRE_op1 <= data1; -- BASE_ADR na instrucao LW |
else |
-- Immediate datas |
if micro_code(instr).imm1_sel='0' then |
PRE_op1 <= (others => '0'); -- Immediate operand = 0 -- J, JAL |
else |
PRE_op1 <= X"000000" & "000" & shamt; -- Immediate operand = shamt |
end if; |
end if; |
|
|
if micro_code(instr).cs_imm2='0' then |
-- Datas from register banks |
PRE_op2 <= data2; |
else |
-- Immediate datas |
if micro_code(instr).imm2_sel='0' then |
PRE_op2 <= X"0000" & imm; -- Immediate operand = imm (OFF_SET na instrucao LW) -- J, JAL |
else |
if imm(15)='1' then -- Immediate operand = sgn_ext(imm) |
PRE_op2 <= X"FFFF" & imm; |
else |
PRE_op2 <= X"0000" & imm; |
end if; |
end if; |
end if; |
|
-- Selection of destination register address |
case micro_code(instr).des_sel is |
when D_RT => PRE_adr_reg_dest <= micro_code(instr).bank_des & rt; |
when D_RD => PRE_adr_reg_dest <= micro_code(instr).bank_des & rd; |
when D_31 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "11111"; |
when D_00 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "00000"; -- registrador zero |
end case; |
|
-- Command signal affectation |
PRE_bra <= micro_code(instr).bra; -- Branch operation |
PRE_link <= micro_code(instr).link; -- Branch with link |
PRE_code_ual <= micro_code(instr).code_ual; -- Alu operation |
PRE_ecr_reg <= micro_code(instr).ecr_reg; -- Writing the result in a bank register |
PRE_mode <= micro_code(instr).mode; -- Type of calculation for the address with current pc |
PRE_op_mem <= micro_code(instr).op_mem; -- Memory operation needed |
PRE_r_w <= micro_code(instr).r_w; -- Read/Write in memory selection |
PRE_exc_cause <= micro_code(instr).exc_cause; -- Potential cause exception |
PRE_level <= micro_code(instr).level; |
|
-- Set asynchronous outputs |
adr_reg1 <= micro_code(instr).cop_org1 & rs; -- First operand register address |
adr_reg2 <= micro_code(instr).cop_org2 & rt; -- Second operand register address |
bra_detect <= micro_code(instr).bra; -- Branch detection in current instruction |
use1 <= not micro_code(instr).cs_imm1; -- Effective use of operande 1 |
use2 <= not micro_code(instr).cs_imm2; -- Effective use of operande 2 |
istore <= micro_code(instr).r_w; -- insere nops apos SW |
end if; |
end process; |
|
-- Set the synchronous outputs |
process (clock) |
begin |
if rising_edge(clock) then |
if reset='1' then |
DI_bra <= '0'; |
DI_link <= '0'; |
DI_op1 <= (others => '0'); |
DI_op2 <= (others => '0'); |
DI_code_ual <= OP_OUI; |
DI_offset <= (others => '0'); |
DI_adr_reg_dest <= (others => '0'); |
DI_ecr_reg <= '0'; |
DI_mode <= '0'; |
DI_op_mem <= '0'; |
DI_r_w <= '0'; |
DI_adr <= (others => '0'); |
DI_exc_cause <= IT_NOEXC; |
DI_level <= LVL_DI; |
DI_it_ok <= '0'; |
elsif stop_all='0' then |
if clear='1' or stop_di='1' then |
-- Nop instruction |
DI_bra <= '0'; |
DI_link <= '0'; |
DI_op1 <= (others => '0'); |
DI_op2 <= (others => '0'); |
DI_code_ual <= OP_OUI; |
DI_offset <= (others => '0'); |
DI_adr_reg_dest <= (others => '0'); |
DI_ecr_reg <= '0'; |
DI_mode <= '0'; |
DI_op_mem <= '0'; |
DI_r_w <= '0'; |
DI_adr <= EI_adr; |
DI_exc_cause <= IT_NOEXC; |
DI_level <= LVL_DI; |
if clear='1' then |
DI_it_ok <= '0'; |
else |
DI_it_ok <= EI_it_ok; |
end if; |
else -- Noraml step |
DI_bra <= PRE_bra; |
DI_link <= PRE_link; |
DI_op1 <= PRE_op1; |
DI_op2 <= PRE_op2; |
DI_code_ual <= PRE_code_ual; |
DI_offset <= PRE_offset; |
DI_adr_reg_dest <= PRE_adr_reg_dest; |
DI_ecr_reg <= PRE_ecr_reg; |
DI_mode <= PRE_mode; |
DI_op_mem <= PRE_op_mem; |
DI_r_w <= PRE_r_w; |
DI_adr <= EI_adr; |
DI_exc_cause <= PRE_exc_cause; |
DI_level <= PRE_level; |
DI_it_ok <= EI_it_ok; |
end if; |
end if; |
end if; |
end process; |
|
end rtl; |
|
|
/P0/sources/pps_di_2.vhd
0,0 → 1,395
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Instruction decoding stage 2 -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity pps_di_2 is |
port ( |
clock : in std_logic; |
reset : in std_logic; |
stop_all2 : in std_logic; -- Unconditionnal locking of the outputs |
clear : in std_logic; -- Clear the pipeline stage (nop in the outputs) |
|
-- Asynchronous outputs |
bra_detect : out std_logic; -- Branch detection in the current instruction |
istore2 : out std_logic; |
--iload2 : out std_logic; |
-- Asynchronous connexion with the register management and data bypass unit (Conexao assincrona com a unidade de gerenciamento de registradores e desvio de dados) |
adr_reg1 : out adr_reg_type; -- Address of the first register operand |
adr_reg2 : out adr_reg_type; -- Address of the second register operand |
use1 : out std_logic; -- Effective use of operand 1 |
use2 : out std_logic; -- Effective use of operand 2 |
|
stop_di : in std_logic; -- Unresolved detected : send nop in the pipeline |
data1 : in bus32; -- Operand register 1 |
data2 : in bus32; -- Operand register 2 |
|
-- Datas from EI stage |
EI_adr : in bus32; -- Address of the instruction |
EI_instr : in bus32; -- The instruction to decode |
EI_it_ok : in std_logic; -- Allow hardware interruptions |
|
-- Synchronous output to EX2 stage |
DI_bra : out std_logic; -- Branch decoded |
DI_link : out std_logic; -- A link for that instruction |
DI_op1 : out bus32; -- operand 1 for alu |
DI_op2 : out bus32; -- operand 2 for alu |
DI_code_ual : out alu_ctrl_type; -- Alu operation |
DI_offset : out bus32; -- Offset for the address calculation |
DI_adr_reg_dest : out adr_reg_type; -- Address of the destination register of the result |
DI_ecr_reg : out std_logic; -- Effective writing of the result |
DI_mode : out std_logic; -- Address mode (relative to pc or indexed to a register) |
DI_op_mem : out std_logic; -- Memory operation request |
DI_r_w : out std_logic; -- Type of memory operation (reading or writing) |
DI_adr : out bus32; -- Address of the decoded instruction |
DI_exc_cause : out bus32; -- Potential exception detected |
DI_level : out level_type; -- Availability of the result for the data bypass |
DI_it_ok : out std_logic -- Allow hardware interruptions |
); |
end entity; |
|
|
architecture rtl of pps_di_2 is |
|
-- Enumeration type used for the micro-code of the instruction |
type op_mode_type is (OP_NORMAL, OP_SPECIAL, OP_REGIMM, OP_COP0); -- selection du mode de l'instruction |
type off_sel_type is (OFS_PCRL, OFS_NULL, OFS_SESH, OFS_SEXT); -- selection de la valeur de l'offset |
type rdest_type is ( D_RT, D_RD, D_31, D_00); -- selection du registre destination |
|
-- Record type containg the micro-code of an instruction |
type micro_instr_type is |
record |
op_mode : op_mode_type; -- Instruction codop mode |
op_code : bus6; -- Instruction codop |
bra : std_logic; -- Branch instruction |
link : std_logic; -- Branch with link : the return address is saved in a register |
code_ual : alu_ctrl_type; -- Operation code for the alu |
op_mem : std_logic; -- Memory operation needed |
r_w : std_logic; -- Read/Write selection in memory |
mode : std_logic; -- Address calculation from the current pc ('1') or the alu operand 1 ('0') |
off_sel : off_sel_type; -- Offset source : PC(31..28) & Adresse & 00 || 0 || sgn_ext(Imm) & 00 || sgn_ext(Imm) |
exc_cause : bus32; -- Unconditionnal exception cause to generate |
cop_org1 : std_logic; -- Source register 1 : general register if 0, coprocessor register if 1 |
cop_org2 : std_logic; -- Source register 2 : general register if 0, coprocessor register if 1 |
cs_imm1 : std_logic; -- Use of immediat operand 1 instead of register bank |
cs_imm2 : std_logic; -- Use of immediat operand 2 instead of register bank |
imm1_sel : std_logic; -- Origine of immediat operand 1 |
imm2_sel : std_logic; -- Origine of immediat operand 2 |
level : level_type; -- Data availability stage for the bypass (Estagio de disponibilidade dos dados para dar a volta) |
ecr_reg : std_logic; -- Writing the result in a register |
bank_des : std_logic; -- Register bank selection : GPR if 0, coprocessor system if 1 |
des_sel : rdest_type ; -- Destination register address : Rt, Rd, $31, $0 |
end record; |
|
type micro_code_type is array (natural range <>) of micro_instr_type; |
|
constant micro_code : micro_code_type := |
( -- Instruction decoding in micro-instructions table |
(OP_SPECIAL, "100000", '0', '0', OP_ADD , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- ADD |
(OP_NORMAL , "001000", '0', '0', OP_ADD , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX2 , '1', '0', D_RT), -- ADDI |
(OP_NORMAL , "001001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX2 , '1', '0', D_RT), -- ADDIU |
(OP_SPECIAL, "100001", '0', '0', OP_ADDU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- ADDU |
(OP_SPECIAL, "100100", '0', '0', OP_AND , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- AND |
(OP_NORMAL , "001100", '0', '0', OP_AND , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX2 , '1', '0', D_RT), -- ANDI |
(OP_NORMAL , "000100", '1', '0', OP_EQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI2 , '0', '0', D_RT), -- BEQ |
(OP_REGIMM , "000001", '1', '0', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- BGEZ |
(OP_REGIMM , "010001", '1', '1', OP_LPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX2 , '1', '0', D_31), -- BGEZAL |
(OP_NORMAL , "000111", '1', '0', OP_SPOS , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- BGTZ |
(OP_NORMAL , "000110", '1', '0', OP_LNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- BLEZ |
(OP_REGIMM , "000000", '1', '0', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- BLTZ |
(OP_REGIMM , "010000", '1', '1', OP_SNEG , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX2 , '1', '0', D_31), -- BLTZAL |
(OP_NORMAL , "000101", '1', '0', OP_NEQU , '0', '0', '1', OFS_SESH, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI2 , '0', '0', D_RT), -- BNE |
(OP_SPECIAL, "001101", '0', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_BREAK, '0', '0', '1', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- BREAK |
(OP_COP0 , "000001", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI2 , '1', '1', D_00), -- COP0 |
(OP_NORMAL , "000010", '1', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- J |
(OP_NORMAL , "000011", '1', '1', OP_OUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX2 , '1', '0', D_31), -- JAL |
(OP_SPECIAL, "001001", '1', '1', OP_OUI , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX2 , '1', '0', D_RD), -- JALR |
(OP_SPECIAL, "001000", '1', '0', OP_OUI , '0', '0', '0', OFS_NULL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- JR |
(OP_NORMAL , "001111", '0', '0', OP_LUI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX2 , '1', '0', D_RT), -- LUI |
(OP_NORMAL , "100011", '0', '0', OP_OUI , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM2, '1', '0', D_RT), -- LW |
(OP_NORMAL , "110000", '0', '0', OP_OUI , '1', '0', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_MEM2, '1', '1', D_RT), -- LWC0 |
(OP_COP0 , "000000", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '1', '1', '0', '0', '0', LVL_DI2 , '1', '0', D_RD), -- MFC0 |
(OP_SPECIAL, "010000", '0', '0', OP_MFHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX2 , '1', '0', D_RD), -- MFHI |
(OP_SPECIAL, "010010", '0', '0', OP_MFLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '1', '0', '0', LVL_EX2 , '1', '0', D_RD), -- MFLO |
(OP_COP0 , "000100", '0', '0', OP_OP2 , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '0', '0', LVL_DI2 , '1', '1', D_RD), -- MTC0 |
(OP_SPECIAL, "010001", '0', '0', OP_MTHI , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- MTHI |
(OP_SPECIAL, "010011", '0', '0', OP_MTLO , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- MTLO |
(OP_SPECIAL, "011000", '0', '0', OP_MULT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '0', '0', D_RT), -- MULT |
(OP_SPECIAL, "011100", '0', '0', OP_MULT2, '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- MULT2 [RD = RS * RT] |
(OP_SPECIAL, "011001", '0', '0', OP_MULTU, '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '0', '0', D_RT), -- MULT |
(OP_SPECIAL, "100111", '0', '0', OP_NOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- NOR |
(OP_SPECIAL, "100101", '0', '0', OP_OR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- OR |
(OP_NORMAL , "001101", '0', '0', OP_OR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX2 , '1', '0', D_RT), -- ORI |
(OP_SPECIAL, "000000", '0', '0', OP_SLL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX2 , '1', '0', D_RD), -- SLL |
(OP_SPECIAL, "000100", '0', '0', OP_SLL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- SLLV |
(OP_SPECIAL, "101010", '0', '0', OP_SLT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- SLT |
(OP_NORMAL , "001010", '0', '0', OP_SLT , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX2 , '1', '0', D_RT), -- SLTI |
(OP_NORMAL , "001011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '1', LVL_EX2 , '1', '0', D_RT), -- SLTIU |
(OP_SPECIAL, "101011", '0', '0', OP_SLTU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- SLTU |
(OP_SPECIAL, "000011", '0', '0', OP_SRA , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX2 , '1', '0', D_RD), -- SRA |
(OP_SPECIAL, "000111", '0', '0', OP_SRA , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- SRAV |
(OP_SPECIAL, "000010", '0', '0', OP_SRL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '1', '0', '1', '0', LVL_EX2 , '1', '0', D_RD), -- SRL |
(OP_SPECIAL, "000110", '0', '0', OP_SRL , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- SRLV |
(OP_SPECIAL, "100010", '0', '0', OP_SUB , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- SUB |
(OP_SPECIAL, "100011", '0', '0', OP_SUBU , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- SUBU |
(OP_NORMAL , "101011", '0', '0', OP_OP2 , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_DI2 , '0', '0', D_RT), -- SW |
(OP_NORMAL , "111000", '0', '0', OP_OP2 , '1', '1', '0', OFS_SEXT, IT_NOEXC, '0', '1', '0', '0', '0', '0', LVL_DI2 , '0', '0', D_RT), -- SWC0 |
(OP_SPECIAL, "001100", '0', '0', OP_OUI , '0', '0', '0', OFS_PCRL, IT_SCALL, '0', '0', '1', '1', '0', '0', LVL_DI2 , '0', '0', D_RT), -- SYSC |
(OP_SPECIAL, "100110", '0', '0', OP_XOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '0', '0', '0', LVL_EX2 , '1', '0', D_RD), -- XOR |
(OP_NORMAL , "001110", '0', '0', OP_XOR , '0', '0', '0', OFS_PCRL, IT_NOEXC, '0', '0', '0', '1', '0', '0', LVL_EX2 , '1', '0', D_RT) -- XORI |
); |
|
-- Preparation of the synchronous outputs |
signal PRE_bra : std_logic; -- Branch operation |
signal PRE_link : std_logic; -- Branch with link |
signal PRE_op1 : bus32; -- operand 1 of the ual |
signal PRE_op2 : bus32; -- operand 2 of the ual |
signal PRE_code_ual : alu_ctrl_type; -- Alu operation |
signal PRE_offset : bus32; -- Address offset for calculation |
signal PRE_adr_reg_dest : adr_reg_type; -- Destination register adress for result |
signal PRE_ecr_reg : std_logic; -- Writing of result in the bank register |
signal PRE_mode : std_logic; -- Address calculation with current pc |
signal PRE_op_mem : std_logic; -- Memory access operation instruction |
signal PRE_r_w : std_logic; -- Read/write selection in memory |
signal PRE_exc_cause : bus32; -- Potential exception cause |
signal PRE_level : level_type; -- Result availability stage for bypass |
|
begin |
|
-- Instruction decoding |
process (EI_instr, EI_adr, data1, data2) |
variable op_code : bus6; -- Effective codop of the instruction |
variable op_mode : op_mode_type; -- Instruction mode |
variable flag : boolean; -- Is true if valid instruction |
variable instr : integer; -- Current micro-instruction adress |
|
-- Instruction fields |
variable rs : bus5; |
variable rt : bus5; |
variable rd : bus5; |
variable shamt : bus5; |
variable imm : bus16; |
variable address : bus26; |
begin |
|
-- Selection of the instruction codop and its mode |
case EI_instr(31 downto 26) is |
when "000000" => -- special mode |
op_mode := OP_SPECIAL; |
op_code := EI_instr(5 downto 0); |
when "000001" => -- regimm mode |
op_mode := OP_REGIMM; |
op_code := '0' & EI_instr(20 downto 16); |
when "010000" => -- cop0 mode |
op_mode := OP_COP0; |
op_code := '0' & EI_instr(25 downto 21); |
when others => -- normal mode |
op_mode := OP_NORMAL; |
op_code := EI_instr(31 downto 26); |
end case; |
|
|
-- Search the current instruction in the micro-code table |
flag := false; |
instr := 0; |
for i in micro_code'range loop |
if micro_code(i).op_mode=op_mode and micro_code(i).op_code=op_code then |
flag := true; -- The instruction exists |
instr := i; -- Index memorisation |
end if; |
end loop; |
|
-- Read the instruction field |
rs := EI_instr(25 downto 21); |
rt := EI_instr(20 downto 16); |
rd := EI_instr(15 downto 11); |
shamt := EI_instr(10 downto 6); |
imm := EI_instr(15 downto 0); |
address := EI_instr(25 downto 0); |
|
if not flag then -- Unknown instruction |
|
-- Synchronous output preparation |
PRE_bra <= '0'; -- Branch operation |
PRE_link <= '0'; -- Branch with link |
PRE_op1 <= (others => '0'); -- operand 1 of the ual |
PRE_op2 <= (others => '0'); -- operand 2 of the ual |
PRE_code_ual <= OP_OUI; -- Alu operation |
PRE_offset <= (others => '0'); -- Address offset for calculation |
PRE_adr_reg_dest <= (others => '0'); -- Destination register adress for result |
PRE_ecr_reg <= '0'; -- Writing of result in the bank register |
PRE_mode <= '0'; -- Address calculation with current pc |
PRE_op_mem <= '0'; -- Memory access operation instruction |
PRE_r_w <= '0'; -- Read/write selection in memory |
PRE_exc_cause <= IT_ERINS; -- Potential exception cause |
PRE_level <= LVL_DI; -- Result availability stage for bypass |
|
-- Set asynchronous outputs |
adr_reg1 <= (others => '0'); -- First operand register |
adr_reg2 <= (others => '0'); -- Second operand register |
bra_detect <= '0'; -- Detection of a branch in current instruction |
use1 <= '0'; -- Effective use of operand 1 |
use2 <= '0'; -- Effective use of operand 2 |
istore2 <= '0'; |
else -- Valid instruction |
-- Offset signal preparation |
case micro_code(instr).off_sel is |
when OFS_PCRL => -- PC(31..28) & Adresse & 00 |
PRE_offset <= EI_adr(31 downto 28) & address & "00"; -- instrucao J (jump) |
when OFS_NULL => -- 0 |
PRE_offset <= (others => '0'); |
when OFS_SESH => -- sgn_ext(Imm) & 00 |
if imm(15)='1' then |
|
else |
PRE_offset <= "00000000000000" & imm & "00"; -- BNE para frente |
end if; |
when OFS_SEXT => -- sgn_ext(Imm) |
if imm(15)='1' then |
PRE_offset <= "1111111111111111" & imm; |
else |
PRE_offset <= "0000000000000000" & imm; |
end if; |
end case; |
|
|
-- Alu operand preparation |
if micro_code(instr).cs_imm1='0' then |
-- Datas from register banks |
PRE_op1 <= data1; -- BNE usa registradores para comparar op1 |
else |
-- Immediate datas |
if micro_code(instr).imm1_sel='0' then |
PRE_op1 <= (others => '0'); -- Immediate operand = 0 (J) |
else |
PRE_op1 <= X"000000" & "000" & shamt; -- Immediate operand = shamt |
end if; |
end if; |
|
|
if micro_code(instr).cs_imm2='0' then |
-- Datas from register banks |
PRE_op2 <= data2; -- BNE usa registradores para comparar op2 |
else |
-- Immediate datas |
if micro_code(instr).imm2_sel='0' then |
PRE_op2 <= X"0000" & imm; -- Immediate operand = imm |
else |
if imm(15)='1' then -- Immediate operand = sgn_ext(imm) |
PRE_op2 <= X"FFFF" & imm; |
else |
PRE_op2 <= X"0000" & imm; |
end if; |
end if; |
end if; |
|
-- Selection of destination register address |
case micro_code(instr).des_sel is |
when D_RT => PRE_adr_reg_dest <= micro_code(instr).bank_des & rt; |
when D_RD => PRE_adr_reg_dest <= micro_code(instr).bank_des & rd; |
when D_31 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "11111"; |
when D_00 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "00000"; |
end case; |
|
-- Command signal affectation |
PRE_bra <= micro_code(instr).bra; -- Branch operation |
PRE_link <= micro_code(instr).link; -- Branch with link |
PRE_code_ual <= micro_code(instr).code_ual; -- Alu operation |
PRE_ecr_reg <= micro_code(instr).ecr_reg; -- Writing the result in a bank register |
PRE_mode <= micro_code(instr).mode; -- Type of calculation for the address with current pc |
PRE_op_mem <= micro_code(instr).op_mem; -- Memory operation needed |
PRE_r_w <= micro_code(instr).r_w; -- Read/Write in memory selection |
PRE_exc_cause <= micro_code(instr).exc_cause; -- Potential cause exception |
PRE_level <= micro_code(instr).level; |
|
-- Set asynchronous outputs |
adr_reg1 <= micro_code(instr).cop_org1 & rs; -- First operand register address |
adr_reg2 <= micro_code(instr).cop_org2 & rt; -- Second operand register address |
bra_detect <= micro_code(instr).bra; -- Branch detection in current instruction |
use1 <= not micro_code(instr).cs_imm1; -- Effective use of operande 1 |
use2 <= not micro_code(instr).cs_imm2; -- Effective use of operande 2 |
istore2 <= micro_code(instr).r_w; -- insere nops apos SW |
end if; |
|
end process; |
|
-- Set the synchronous outputs |
process (clock) |
begin |
if falling_edge(clock) then |
if reset='1' then |
DI_bra <= '0'; |
DI_link <= '0'; |
DI_op1 <= (others => '0'); |
DI_op2 <= (others => '0'); |
DI_code_ual <= OP_OUI; |
DI_offset <= (others => '0'); |
DI_adr_reg_dest <= (others => '0'); |
DI_ecr_reg <= '0'; |
DI_mode <= '0'; |
DI_op_mem <= '0'; |
DI_r_w <= '0'; |
DI_adr <= (others => '0'); |
DI_exc_cause <= IT_NOEXC; |
DI_level <= LVL_DI; |
DI_it_ok <= '0'; |
elsif stop_all2='0' then |
if clear='1' or stop_di='1' then |
-- Nop instruction |
DI_bra <= '0'; |
DI_link <= '0'; |
DI_op1 <= (others => '0'); |
DI_op2 <= (others => '0'); |
DI_code_ual <= OP_OUI; |
DI_offset <= (others => '0'); |
DI_adr_reg_dest <= (others => '0'); |
DI_ecr_reg <= '0'; |
DI_mode <= '0'; |
DI_op_mem <= '0'; |
DI_r_w <= '0'; |
DI_adr <= EI_adr; |
DI_exc_cause <= IT_NOEXC; |
DI_level <= LVL_DI; |
if clear='1' then |
DI_it_ok <= '0'; |
else |
DI_it_ok <= EI_it_ok; |
end if; |
else -- Noraml step |
DI_bra <= PRE_bra; |
DI_link <= PRE_link; |
DI_op1 <= PRE_op1; |
DI_op2 <= PRE_op2; |
DI_code_ual <= PRE_code_ual; |
DI_offset <= PRE_offset; |
DI_adr_reg_dest <= PRE_adr_reg_dest; |
DI_ecr_reg <= PRE_ecr_reg; |
DI_mode <= PRE_mode; |
DI_op_mem <= PRE_op_mem; |
DI_r_w <= PRE_r_w; |
DI_adr <= EI_adr; |
DI_exc_cause <= PRE_exc_cause; |
DI_level <= PRE_level; |
DI_it_ok <= EI_it_ok; |
end if; |
end if; |
end if; |
end process; |
|
end rtl; |
|
|
/P0/sources/pps_ei.vhd
0,0 → 1,76
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Instruction extraction stage -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity pps_ei is |
port ( |
clock : in std_logic; |
reset : in std_logic; |
clear : in std_logic; -- Clear the pipeline stage |
stop_all : in std_logic; -- Evolution locking signal |
|
-- Asynchronous inputs |
stop_ei : in std_logic; -- Lock the EI_adr and Ei_instr registers |
genop : in std_logic; -- Send nops |
|
-- Bus controler interface |
CTE_instr : in bus32; -- Instruction from the memory |
ETC_adr : out bus32; -- Address to read in memory |
|
-- Synchronous inputs from PF stage |
PF_pc : in bus32; -- Current value of the pc |
|
-- Synchronous outputs to DI stage |
EI_instr : out bus32; -- Read interface |
EI_adr : out bus32; -- Address from the read instruction |
EI_it_ok : out std_logic -- Allow hardware interruptions |
); |
end pps_ei; |
|
architecture rtl of pps_ei is |
begin |
|
ETC_adr <= PF_pc; -- Connexion of the PC to the memory address bus |
|
-- Set the results |
process (clock) |
begin |
if rising_edge(clock) then |
if reset='1' then |
EI_instr <= INS_NOP; |
EI_adr <= (others => '0'); |
EI_it_ok <= '0'; |
elsif stop_all='0' then |
if clear='1' then |
-- Clear the stage |
EI_instr <= INS_NOP; |
EI_it_ok <= '0'; |
elsif genop='1' and stop_ei='0' then |
-- Send a nop |
EI_instr <= INS_NOP; |
EI_it_ok <= '1'; |
elsif stop_ei='0' then |
-- Normal evolution |
EI_adr <= PF_pc; |
EI_instr <= CTE_instr; |
EI_it_ok <= '1'; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
/P0/sources/pps_ei_2.vhd
0,0 → 1,76
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Instruction extraction stage 2 -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity pps_ei_2 is |
port ( |
clock : in std_logic; |
reset : in std_logic; |
clear : in std_logic; -- Clear the pipeline stage |
stop_all2 : in std_logic; -- Evolution locking signal |
|
-- Asynchronous inputs |
stop_ei : in std_logic; -- Lock the EI_adr and Ei_instr registers |
genop : in std_logic; -- Send nops |
|
-- Bus controler interface |
CTE_instr : in bus32; -- Instruction from the memory |
ETC_adr : out bus32; -- Address to read in memory |
|
-- Synchronous inputs from PF stage |
PF_pc : in bus32; -- Current value of the pc (desnecessario no EI2) |
|
-- Synchronous outputs to DI stage |
EI_instr : out bus32; -- Read interface |
EI_adr : out bus32; -- Address from the read instruction |
EI_it_ok : out std_logic -- Allow hardware interruptions |
); |
end pps_ei_2; |
|
architecture rtl of pps_ei_2 is |
begin |
|
ETC_adr <= PF_pc; -- Connexion of the PC to the memory address bus |
|
-- Set the results |
process (clock) |
begin |
if falling_edge(clock) then |
if reset='1' then |
EI_instr <= INS_NOP; |
EI_adr <= (others => '0'); |
EI_it_ok <= '0'; |
elsif stop_all2='0' then |
if clear='1' then |
-- Clear the stage |
EI_instr <= INS_NOP; |
EI_it_ok <= '0'; |
elsif genop='1' and stop_ei='0' then |
-- Send a nop |
EI_instr <= INS_NOP; |
EI_it_ok <= '1'; |
elsif stop_ei='0' then |
-- Normal evolution |
EI_adr <= PF_pc; |
EI_instr <= CTE_instr; |
EI_it_ok <= '1'; |
end if; |
end if; |
end if; |
end process; |
end rtl; |
/P0/sources/pps_ex.vhd
0,0 → 1,163
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Execution stage -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
use work.alu; |
|
entity pps_ex is |
port( |
clock : in std_logic; |
clock2 : in std_logic; |
reset : in std_logic; |
stop_all : in std_logic; -- Unconditionnal locking of outputs |
stop_all2 : in std_logic; -- 07-08-2018 |
clear : in std_logic; -- Clear the pipeline stage |
|
-- Datas from DI stage |
DI_bra : in std_logic; -- Branch instruction |
DI_link : in std_logic; -- Branch with link |
DI_op1 : in bus32; -- Operand 1 for alu |
DI_op2 : in bus32; -- Operand 2 for alu |
DI_code_ual : in alu_ctrl_type; -- Alu operation |
DI_offset : in bus32; -- Offset for address calculation |
DI_adr_reg_dest : in adr_reg_type; -- Destination register address for the result |
DI_ecr_reg : in std_logic; -- Effective writing of the result |
DI_mode : in std_logic; -- Address mode (relative to pc ou index by a register) |
DI_op_mem : in std_logic; -- Memory operation |
DI_r_w : in std_logic; -- Type of memory operation (read or write) |
DI_adr : in bus32; -- Instruction address |
DI_exc_cause : in bus32; -- Potential cause exception |
DI_level : in level_type; -- Availability stage of the result for bypassing |
DI_it_ok : in std_logic; -- Allow hardware interruptions |
EX2_data_hilo : in bus64;--resultado da multiplicacao do pieline2 |
EX_data_hilo : out bus64; |
-- Synchronous outputs to MEM stage |
EX_adr : out bus32; -- Instruction address |
EX_bra_confirm : out std_logic; -- Branch execution confirmation |
EX_data_ual : out bus32; -- Ual result |
EX_adresse : out bus32; -- Address calculation result |
EX_adresse_p1p2 : out bus32; -- resultado do calculo do endereco do desvio + 4 para pipe 2 |
EX_adr_reg_dest : out adr_reg_type; -- Destination register for the result |
EX_ecr_reg : out std_logic; -- Effective writing of the result |
EX_op_mem : out std_logic; -- Memory operation needed |
EX_r_w : out std_logic; -- Type of memory operation (read or write) |
EX_exc_cause : out bus32; -- Potential cause exception |
EX_level : out level_type; -- Availability stage of result for bypassing |
EX_it_ok : out std_logic -- Allow hardware interruptions |
); |
end entity; |
|
|
architecture rtl of pps_ex is |
|
component alu |
port ( |
clock : in bus1; |
reset : in bus1; |
op1 : in bus32; -- Operand 1 |
op2 : in bus32; -- Operand 2 |
ctrl : in alu_ctrl_type; -- Operation |
hilo_p2 : in bus64; |
hilo_p1p2 : out bus64; |
res : out bus32; -- Result |
overflow : out bus1 -- Overflow |
); |
end component; |
|
signal res_ual : bus32; -- Alu result output |
signal base_adr : bus32; -- Output of the address mode mux selection |
signal pre_ecr_reg : std_logic; -- Output of mux selection for writing command to register |
signal pre_data_ual : bus32; -- Mux selection of the data to write |
signal pre_bra_confirm : std_logic; -- Result of the test in alu when branch instruction |
signal pre_exc_cause : bus32; -- Preparation of the exception detection signal |
signal overflow_ual : std_logic; -- Dectection of the alu overflow |
signal ex_address_p1p2 : bus32; |
signal hilo_p1p2_s : bus64; |
begin |
|
-- Alu instantiation |
U1_alu : alu port map (clock => clock, reset => reset, op1=>DI_op1, op2=>DI_op2, ctrl=>DI_code_ual, |
res=>res_ual, overflow=>overflow_ual, hilo_p2=>EX2_data_hilo, hilo_p1p2=>hilo_p1p2_s); |
|
-- Calculation of the future outputs |
base_adr <= DI_op1 when DI_mode='0' else DI_adr; -- *** base_adr = DI_op1 = 0 na instrucao JAL *** |
pre_ecr_reg <= DI_ecr_reg when DI_link='0' else pre_bra_confirm; |
pre_data_ual <= res_ual when DI_link='0' else bus32(unsigned(DI_adr) + 8); --***Endereco de retorno (link address) gravado pela instrucao JAL no registrador D_31, que depois sera usado pela intrucao de retorno da rotina, JR.*** |
pre_bra_confirm <= DI_bra and res_ual(0); |
pre_exc_cause <= DI_exc_cause when DI_exc_cause/=IT_NOEXC else |
IT_OVERF when overflow_ual='1' else |
IT_NOEXC; |
|
-- Set the synchronous outputs |
process(clock) is |
begin |
if rising_edge(clock) then |
if reset='1' then |
EX_adr <= (others => '0'); |
EX_bra_confirm <= '0'; |
EX_data_ual <= (others => '0'); |
EX_adresse <= (others => '0'); |
EX_adr_reg_dest <= (others => '0'); |
EX_ecr_reg <= '0'; |
EX_op_mem <= '0'; |
EX_r_w <= '0'; |
EX_exc_cause <= IT_NOEXC; |
EX_level <= LVL_DI; |
EX_it_ok <= '0'; |
elsif stop_all = '0' then |
if clear = '1' then -- Clear the stage |
EX_adr <= DI_adr; |
EX_bra_confirm <= '0'; |
EX_data_ual <= (others => '0'); |
EX_adresse <= (others => '0'); |
EX_adr_reg_dest <= (others => '0'); |
EX_ecr_reg <= '0'; |
EX_op_mem <= '0'; |
EX_r_w <= '0'; |
EX_exc_cause <= IT_NOEXC; |
EX_level <= LVL_DI; |
EX_it_ok <= '0'; |
else -- Normal evolution |
EX_adr <= DI_adr; |
EX_bra_confirm <= pre_bra_confirm; |
EX_data_ual <= pre_data_ual; |
EX_adr_reg_dest <= DI_adr_reg_dest; |
EX_ecr_reg <= pre_ecr_reg; |
EX_op_mem <= DI_op_mem; |
EX_r_w <= DI_r_w; |
EX_exc_cause <= pre_exc_cause; |
EX_level <= DI_level; |
EX_it_ok <= DI_it_ok; |
EX_adresse <= bus32(unsigned(DI_offset) + unsigned(base_adr)); --*** base_adr = DI_op1 = 0 na instrucao JAL, para calcular o endereco alvo *** |
ex_address_p1p2 <= bus32(unsigned(DI_offset) + unsigned(base_adr)); |
end if; |
end if; |
end if; |
|
if falling_edge(clock2) then |
if reset = '1' then |
EX_adresse_p1p2 <= (others => '0'); |
EX_data_hilo <= (others => '0'); |
elsif stop_all2 = '0' then -- sinal stop_all do pipe 2 |
EX_data_hilo <= hilo_p1p2_s; |
EX_adresse_p1p2 <= bus32(unsigned(ex_address_p1p2) + 4); --*** endereco alvo para o pipe 2 *** |
end if; |
end if; |
|
end process; |
|
end architecture; |
/P0/sources/pps_ex_2.vhd
0,0 → 1,165
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Execution stage 2 -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
use work.alu2; |
|
entity pps_ex_2 is |
port( |
clock : in std_logic; |
clock2 : in std_logic; |
reset : in std_logic; |
stop_all : in std_logic; -- 07-08-2018 |
stop_all2 : in std_logic; -- Unconditionnal locking of outputs |
clear : in std_logic; -- Clear the pipeline stage |
|
-- Datas from DI stage |
DI_bra : in std_logic; -- Branch instruction |
DI_link : in std_logic; -- Branch with link |
DI_op1 : in bus32; -- Operand 1 for alu (vem zero quando a instrucao eh um J (jump) |
DI_op2 : in bus32; -- Operand 2 for alu |
DI_code_ual : in alu_ctrl_type; -- Alu operation |
DI_offset : in bus32; -- Offset for address calculation |
DI_adr_reg_dest : in adr_reg_type; -- Destination register address for the result |
DI_ecr_reg : in std_logic; -- Effective writing of the result |
DI_mode : in std_logic; -- Address mode (relative to pc ou index by a register) |
DI_op_mem : in std_logic; -- Memory operation |
DI_r_w : in std_logic; -- Type of memory operation (read or write) |
DI_adr : in bus32; -- Instruction address |
DI_exc_cause : in bus32; -- Potential cause exception |
DI_level : in level_type; -- Availability stage of the result for bypassing |
DI_it_ok : in std_logic; -- Allow hardware interruptions |
|
EX_data_hilo : in bus64;--resultado da multiplicacao do pieline 1 |
EX2_data_hilo : out bus64; |
-- Synchronous outputs to MEM stage |
EX_adr : out bus32; -- Instruction address |
EX_bra_confirm : out std_logic; -- Branch execution confirmation |
EX_data_ual : out bus32; -- Ual result |
EX_adresse : out bus32; -- Address calculation result |
EX_adresse_p2p1 : out bus32; -- resultado do calculo do endereco do desvio + 4 para pipe 1 |
EX_adr_reg_dest : out adr_reg_type; -- Destination register for the result |
EX_ecr_reg : out std_logic; -- Effective writing of the result |
EX_op_mem : out std_logic; -- Memory operation needed |
EX_r_w : out std_logic; -- Type of memory operation (read or write) |
EX_exc_cause : out bus32; -- Potential cause exception |
EX_level : out level_type; -- Availability stage of result for bypassing |
EX_it_ok : out std_logic -- Allow hardware interruptions |
); |
end entity; |
|
|
architecture rtl of pps_ex_2 is |
|
component alu2 |
port ( |
clock : in bus1; |
reset : in bus1; |
op1 : in bus32; -- Operand 1 |
op2 : in bus32; -- Operand 2 |
ctrl : in alu_ctrl_type; -- Operation |
hilo_p1 : in bus64; |
hilo_p2p1 : out bus64; |
res : out bus32; -- Result |
overflow : out bus1 -- Overflow |
); |
end component; |
|
signal res_ual : bus32; -- Alu result output |
signal base_adr : bus32; -- Output of the address mode mux selection |
|
signal pre_ecr_reg : std_logic; -- Output of mux selection for writing command to register |
signal pre_data_ual : bus32; -- Mux selection of the data to write |
signal pre_bra_confirm : std_logic; -- Result of the test in alu when branch instruction |
signal pre_exc_cause : bus32; -- Preparation of the exception detection signal |
signal overflow_ual : std_logic; -- Dectection of the alu overflow |
signal ex_address_p2p1 : bus32; |
signal hilo_p2p1_s : bus64; |
begin |
|
-- Alu instantiation |
U1_alu_2 : alu2 port map (clock => clock2, reset => reset, op1=>DI_op1, op2=>DI_op2, ctrl=>DI_code_ual, |
res=>res_ual, overflow=>overflow_ual, hilo_p1=>EX_data_hilo, hilo_p2p1=>hilo_p2p1_s); |
|
-- Calculation of the future outputs |
base_adr <= DI_op1 when DI_mode='0' else DI_adr; |
pre_ecr_reg <= DI_ecr_reg when DI_link='0' else pre_bra_confirm; |
pre_data_ual <= res_ual when DI_link='0' else bus32(unsigned(DI_adr) + 8); |
pre_bra_confirm <= DI_bra and res_ual(0); |
pre_exc_cause <= DI_exc_cause when DI_exc_cause/=IT_NOEXC else |
IT_OVERF when overflow_ual='1' else |
IT_NOEXC; |
|
-- Set the synchronous outputs |
process(clock2) is |
begin |
if falling_edge(clock2) then |
if reset='1' then |
EX_adr <= (others => '0'); |
EX_bra_confirm <= '0'; |
EX_data_ual <= (others => '0'); |
EX_adresse <= (others => '0'); |
EX_adr_reg_dest <= (others => '0'); |
EX_ecr_reg <= '0'; |
EX_op_mem <= '0'; |
EX_r_w <= '0'; |
EX_exc_cause <= IT_NOEXC; |
EX_level <= LVL_DI; |
EX_it_ok <= '0'; |
elsif stop_all2 = '0' then |
if clear = '1' then -- Clear the stage |
EX_adr <= DI_adr; |
EX_bra_confirm <= '0'; |
EX_data_ual <= (others => '0'); |
EX_adresse <= (others => '0'); |
EX_adr_reg_dest <= (others => '0'); |
EX_ecr_reg <= '0'; |
EX_op_mem <= '0'; |
EX_r_w <= '0'; |
EX_exc_cause <= IT_NOEXC; |
EX_level <= LVL_DI; |
EX_it_ok <= '0'; |
else -- Normal evolution |
EX_adr <= DI_adr; |
EX_bra_confirm <= pre_bra_confirm; |
EX_data_ual <= pre_data_ual; |
EX_adr_reg_dest <= DI_adr_reg_dest; |
EX_ecr_reg <= pre_ecr_reg; |
EX_op_mem <= DI_op_mem; |
EX_r_w <= DI_r_w; |
EX_exc_cause <= pre_exc_cause; |
EX_level <= DI_level; |
EX_it_ok <= DI_it_ok; |
EX_adresse <= bus32(unsigned(DI_offset) + unsigned(base_adr)); -- calculo do endereco do branch fora da ULA, [offset + pc atual] (BNE), ou [offset + 0] (J) |
ex_address_p2p1 <= bus32(unsigned(DI_offset) + unsigned(base_adr)); |
end if; |
end if; |
end if; |
|
if rising_edge(clock) then |
if reset = '1' then |
EX_adresse_p2p1 <= (others => '0'); |
EX2_data_hilo <= (others => '0'); |
elsif stop_all = '0' then -- sinal stop_all do pipe 1 |
EX2_data_hilo <= hilo_p2p1_s; |
EX_adresse_p2p1 <= bus32(unsigned(ex_address_p2p1) + 4); --*** endereco alvo para o pipe 1 *** |
end if; |
|
end if; |
end process; |
|
end architecture; |
/P0/sources/pps_mem.vhd
0,0 → 1,191
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Memory access stage -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
|
library work; |
use work.pack_mips.all; |
|
entity pps_mem is |
port |
( |
clock : in std_logic; |
clock2 : in std_logic; |
reset : in std_logic; |
stop_all : in std_logic; -- Unconditionnal locking of the outputs |
stop_all2 : in std_logic; |
clear : in std_logic; -- Clear the pipeline stage |
|
-- Interface with the control bus |
MTC_data : out bus32; -- Data to write in memory |
MTC_adr : out bus32; -- Address for memory |
MTC_r_w : out std_logic; -- Read/Write in memory |
MTC_req : out std_logic; -- Request access to memory |
CTM_data : in bus32; -- Data from memory |
|
-- Datas from Execution stage |
EX_adr : in bus32; -- Instruction address |
EX_data_ual : in bus32; -- Result of alu operation |
EX_adresse : in bus32; -- Result of the calculation of the address |
EX_adresse_p1p2 : in bus32; -- resultado do calculo do endereco do desvio + 4 para pipe 2 |
-- *** nao tinha essa entrada no original, so tinha a saida no EX *** |
EX_bra_confirm : in bus1; -- Confirmacao do branch no pipe 1 (26-07-18) |
-- ****************** |
EX_adr_reg_dest : in adr_reg_type; -- Destination register address for the result |
EX_ecr_reg : in std_logic; -- Effective writing of the result |
EX_op_mem : in std_logic; -- Memory operation needed |
EX_r_w : in std_logic; -- Type of memory operation (read or write) |
EX_exc_cause : in bus32; -- Potential exception cause |
|
EX_it_ok : in std_logic; -- Allow hardware interruptions |
|
-- Synchronous outputs for bypass unit |
MEM_adr : out bus32; -- Instruction address |
MEM_adr_reg_dest : out adr_reg_type; -- Destination register address |
MEM_ecr_reg : out std_logic; -- Writing of the destination register |
MEM_data_ecr : out bus32; -- Data to write (from alu or memory) |
MEM_exc_cause : out bus32; -- Potential exception cause |
|
MEM_it_ok : out std_logic; -- Allow hardware interruptions |
|
|
-- Interface with the control bus |
MTC_data2 : out bus32; -- Data to write in memory |
MTC_adr2 : out bus32; -- Address for memory |
MTC_r_w2 : out std_logic; -- Read/Write in memory |
MTC_req2 : out std_logic; -- Request access to memory |
CTM_data2 : in bus32; -- Data from memory |
|
-- Datas from Execution 2 stage |
EX_adr2 : in bus32; -- Instruction address |
EX_data_ual2 : in bus32; -- Result of alu operation |
EX_adresse2 : in bus32; -- Result of the calculation of the address |
EX_adresse_p2p1 : in bus32; -- resultado do calculo do endereco do desvio + 4 para pipe 1 |
-- *** nao tinha essa entrada no original, so tinha a saida no EX2 *** |
EX_bra_confirm2 : in bus1; -- Confirmacao do branch no pipe 2 (26-07-18) |
-- ****************** |
EX_adr_reg_dest2 : in adr_reg_type; -- Destination register address for the result |
EX_ecr_reg2 : in std_logic; -- Effective writing of the result |
EX_op_mem2 : in std_logic; -- Memory operation needed |
EX_r_w2 : in std_logic; -- Type of memory operation (read or write) |
EX_exc_cause2 : in bus32; -- Potential exception cause |
|
EX_it_ok2 : in std_logic; -- Allow hardware interruptions |
|
-- Synchronous outputs for bypass unit |
MEM_adr2 : out bus32; -- Instruction address |
MEM_adr_reg_dest2 : out adr_reg_type; -- Destination register address |
MEM_ecr_reg2 : out std_logic; -- Writing of the destination register |
MEM_data_ecr2 : out bus32; -- Data to write (from alu or memory) |
MEM_exc_cause2 : out bus32; -- Potential exception cause |
|
MEM_it_ok2 : out std_logic -- Allow hardware interruptions |
); |
end pps_mem; |
|
architecture rtl of pps_mem is |
|
signal tmp_data_ecr : bus32; -- Selection of the data source (memory or alu) |
signal tmp_data_ecr2 : bus32; -- Selection of the data source (memory or alu) |
signal sel_MTC : bus2; |
|
begin |
sel_MTC <= EX_bra_confirm & EX_bra_confirm2; |
|
with sel_MTC select |
MTC_adr <= EX_adresse_p2p1 when "01", |
EX_adresse when others; |
|
with sel_MTC select |
MTC_adr2 <= EX_adresse_p1p2 when "10", |
EX_adresse2 when others; |
|
-- Bus controler connexions |
MTC_r_w <= EX_r_w; -- Connexion of R/W |
MTC_data <= EX_data_ual; -- Connexion of the data bus |
MTC_req <= EX_op_mem and not clear; -- Connexion of the request (if there is no clearing of the pipeline) |
-- Bus controler connexions 2nd pipe |
MTC_r_w2 <= EX_r_w2; -- Connexion of R/W |
MTC_data2 <= EX_data_ual2; -- Connexion of the data bus |
MTC_req2 <= EX_op_mem2 and not clear; -- Connexion of the request (if there is no clearing of the pipeline) |
-- Preselection of the data source for the outputs |
tmp_data_ecr <= CTM_data when EX_op_mem = '1' else EX_data_ual; |
|
-- Set the synchronous outputs |
process (clock) |
begin |
if rising_edge(clock) then |
if reset = '1' then |
MEM_adr <= (others => '0'); |
MEM_adr_reg_dest <= (others => '0'); |
MEM_ecr_reg <= '0'; |
MEM_data_ecr <= (others => '0'); |
MEM_exc_cause <= IT_NOEXC; |
MEM_level <= LVL_DI; |
MEM_it_ok <= '0'; |
elsif stop_all = '0' then |
if clear = '1' then -- Clear the stage |
MEM_adr <= EX_adr; |
MEM_adr_reg_dest <= (others => '0'); |
MEM_ecr_reg <= '0'; |
MEM_data_ecr <= (others => '0'); |
MEM_exc_cause <= IT_NOEXC; |
MEM_level <= LVL_DI; |
MEM_it_ok <= '0'; |
else -- Normal evolution |
MEM_adr <= EX_adr; |
MEM_adr_reg_dest <= EX_adr_reg_dest; |
MEM_ecr_reg <= EX_ecr_reg; |
MEM_data_ecr <= tmp_data_ecr; |
MEM_exc_cause <= EX_exc_cause; |
MEM_level <= EX_level; |
MEM_it_ok <= EX_it_ok; |
end if; |
end if; |
end if; |
end process; |
|
process (clock2) |
begin |
if falling_edge(clock2) then |
if reset = '1' then |
MEM_adr2 <= (others => '0'); |
MEM_adr_reg_dest2 <= (others => '0'); |
MEM_ecr_reg2 <= '0'; |
MEM_data_ecr2 <= (others => '0'); |
MEM_exc_cause2 <= IT_NOEXC; |
MEM_level2 <= LVL_DI; |
MEM_it_ok2 <= '0'; |
elsif stop_all2 = '0' then |
if clear = '1' then -- Clear the stage |
MEM_adr2 <= EX_adr2; |
MEM_adr_reg_dest2 <= (others => '0'); |
MEM_ecr_reg2 <= '0'; |
MEM_data_ecr2 <= (others => '0'); |
MEM_exc_cause2 <= IT_NOEXC; |
MEM_level2 <= LVL_DI; |
MEM_it_ok2 <= '0'; |
else -- Normal evolution |
MEM_adr2 <= EX_adr2; |
MEM_adr_reg_dest2 <= EX_adr_reg_dest2; |
MEM_ecr_reg2 <= EX_ecr_reg2; |
MEM_data_ecr2 <= tmp_data_ecr2; |
MEM_exc_cause2 <= EX_exc_cause2; |
MEM_level2 <= EX_level2; |
MEM_it_ok2 <= EX_it_ok2; |
end if; |
end if; |
end if; |
end process; |
|
end rtl; |
/P0/sources/renvoi.vhd
0,0 → 1,253
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Bypass unit -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library IEEE; |
use IEEE.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
entity renvoi is |
port ( |
-- Register access signals |
adr1 : in adr_reg_type; -- Operand 1 address (end. a ser lido asssincronamente pelo DI) |
adr2 : in adr_reg_type; -- Operand 2 address (end. a ser lido asssincronamente pelo DI) |
use1 : in std_logic; -- Operand 1 utilisation |
use2 : in std_logic; -- Operand 2 utilisation |
data1 : out bus32; -- First register value (para DI OP1) |
data2 : out bus32; -- Second register value (para DI OP2) |
alea : out std_logic; -- Unresolved hazards detected |
|
|
|
DI_adr : in adr_reg_type; -- Register destination of the result |
DI_ecr : in std_logic; -- Writing register request |
DI_data : in bus32; -- Data to used (op2 do DI) |
|
EX_level : in level_type; -- Availability level of the data |
EX_adr : in adr_reg_type; -- Register destination of the result |
EX_ecr : in std_logic; -- Writing register request |
EX_data : in bus32; -- Data to used |
|
MEM_level : in level_type; -- Availability level of the data |
MEM_adr : in adr_reg_type; -- Register destination of the result |
MEM_ecr : in std_logic; -- Writing register request |
MEM_data : in bus32; -- Data to used |
|
interrupt : in std_logic; -- Exceptions or interruptions |
|
-- Connexion to the differents bank of register |
|
-- Writing commands for writing in the registers |
write_data : out bus32; -- Data to write |
write_adr : out bus5; -- Address of the register to write |
write_GPR : out std_logic; -- Selection in the internal registers |
write_SCP : out std_logic; -- Selection in the coprocessor system registers |
|
-- Reading commands for Reading in the registers |
read_adr1 : out bus5; -- Address of the first register to read |
read_adr2 : out bus5; -- Address of the second register to read |
read_data1_GPR : in bus32; -- Value of operand 1 from the internal registers |
read_data2_GPR : in bus32; -- Value of operand 2 from the internal registers |
read_data1_SCP : in bus32; -- Value of operand 1 from the coprocessor system registers |
read_data2_SCP : in bus32; -- Value of operand 2 from the coprocessor system registers |
|
--modificacao duplicacao |
-- Register access signals |
adr3 : in adr_reg_type; -- Operand 3 address (end. a ser lido asssincronamente pelo DI2) |
adr4 : in adr_reg_type; -- Operand 4 address (end. a ser lido asssincronamente pelo DI2) |
use12 : in std_logic; -- Operand 3 utilisation |
use22 : in std_logic; -- Operand 4 utilisation |
|
data3 : out bus32; -- First register value |
data4 : out bus32; -- Second register value |
alea2 : out std_logic; -- Unresolved hazards detected |
|
-- Bypass signals of the intermediary datas |
DI_level2 : in level_type; -- Availability level of the data |
DI_adr2 : in adr_reg_type; -- Register destination of the result |
DI_ecr2 : in std_logic; -- Writing register request |
DI_data2 : in bus32; -- Data to used (op2 do DI2) |
|
EX_level2 : in level_type; -- Availability level of the data |
EX_adr2 : in adr_reg_type; -- Register destination of the result |
EX_ecr2 : in std_logic; -- Writing register request |
EX_data2 : in bus32; -- Data to used |
|
MEM_level2 : in level_type; -- Availability level of the data |
MEM_adr2 : in adr_reg_type; -- Register destination of the result |
MEM_ecr2 : in std_logic; -- Writing register request |
MEM_data2 : in bus32; -- Data to used |
|
|
-- Connexion to the differents bank of register |
|
-- Writing commands for writing in the registers |
write_data2 : out bus32; -- Data to write |
write_adr2 : out bus5; -- Address of the register to write |
write_GPR2 : out std_logic; -- Selection in the internal registers |
--sem necessidade--write_SCP : out std_logic; -- Selection in the coprocessor system registers |
|
-- Reading commands for Reading in the registers |
read_adr3 : out bus5; -- Address of the first register to read |
read_adr4 : out bus5; -- Address of the second register to read |
read_data3_GPR : in bus32; -- Value of operand 1 from the internal registers |
read_data4_GPR : in bus32; -- Value of operand 2 from the internal registers |
read_data3_SCP : in bus32; -- Value of operand 1 from the coprocessor system registers |
read_data4_SCP : in bus32 -- Value of operand 2 from the coprocessor system registers |
); |
end renvoi; |
|
architecture rtl of renvoi is |
signal dep_r1 : level_type; -- Dependency level for operand 1 |
signal dep_r2 : level_type; -- Dependency level for operand 2 |
signal read_data1 : bus32; -- Data contained in the register asked by operand 1 |
signal read_data2 : bus32; -- Data contained in the register asked by operand 2 |
signal res_reg, res_mem, res_ex, res_di, res_mem2, res_ex2, res_di2 : std_logic; |
signal resolution : bus7; -- Verification of the resolved hazards |
signal idx1, idx2, idx3, idx4 : integer range 0 to 6; |
|
signal dep_r3 : level_type; -- Dependency level for operand 1 |
signal dep_r4 : level_type; -- Dependency level for operand 2 |
signal read_data3 : bus32; -- Data contained in the register asked by operand 1 |
signal read_data4 : bus32; -- Data contained in the register asked by operand 2 |
|
begin |
-- Connexion of the writing command signals |
write_data <= MEM_data; |
write_adr <= MEM_adr(4 downto 0); |
write_GPR <= not MEM_adr(5) and MEM_ecr when interrupt = '0' else -- The high bit to 0 selects the internal registers |
'0'; |
write_SCP <= MEM_adr(5) and MEM_ecr; -- The high bit to 1 selects the coprocessor system registers |
-- Connexion of the writing command signals |
read_adr1 <= adr1(4 downto 0); -- Connexion of the significative address bits (end. source 1 a ser lido no banco assincronamente pelo DI) |
read_adr2 <= adr2(4 downto 0); -- Connexion of the significative address bits (end. source 2 a ser lido no banco assincronamente PELO DI) |
-- Evaluation of the level of dependencies |
dep_r1 <= LVL_REG when adr1(4 downto 0)="00000" or use1='0' else -- No dependency with register 0, se use1 for igual a '0' aqui, significa que op1 = imm ou shamt |
LVL_DI when adr1=DI_adr and DI_ecr ='1' else -- Dependency with DI stage (reg. fonte = reg.destino no momento da escrita, (DI_ecr ='1')) |
LVL_EX when adr1=EX_adr and EX_ecr ='1' else -- Dependency with EX stage |
LVL_MEM when adr1=MEM_adr and MEM_ecr='1' else -- Dependency with MEM stage |
LVL_DI2 when adr1=DI_adr2 and DI_ecr2 = '1' else -- Dependency with DI stage (reg. fonte = reg.destino no momento da escrita, (DI_ecr ='1')) |
LVL_EX2 when adr1=EX_adr2 and EX_ecr2 = '1' else -- Dependency with EX stage |
LVL_MEM2 when adr1=MEM_adr2 and MEM_ecr2 ='1' else -- Dependency with MEM stage |
LVL_REG; -- No dependency detected |
dep_r2 <= LVL_REG when adr2(4 downto 0)="00000" or use2='0' else -- No dependency with register 0 |
LVL_DI when adr2=DI_adr and DI_ecr ='1' else -- Dependency with DI stage |
LVL_EX when adr2=EX_adr and EX_ecr ='1' else -- Dependency with EX stage |
LVL_MEM when adr2=MEM_adr and MEM_ecr='1' else -- Dependency with MEM stage |
LVL_DI2 when adr2=DI_adr2 and DI_ecr2 = '1' else -- Dependency with DI2 stage (reg. fonte = reg.destino no momento da escrita, (DI_ecr ='1')) |
LVL_EX2 when adr2=EX_adr2 and EX_ecr2 = '1' else -- Dependency with EX2 stage |
LVL_MEM2 when adr2=MEM_adr2 and MEM_ecr2 ='1' else -- Dependency with MEM stage |
LVL_REG; -- No dependency detected |
|
-- Elaboration of the signals with the datas form the bank registers |
read_data1 <= read_data1_GPR when adr1(5)='0' else -- Selection of the internal registers |
read_data1_SCP when adr1(5)='1' else -- Selection of the coprocessor registers |
(others => '0'); |
read_data2 <= read_data2_GPR when adr2(5)='0' else -- Selection of the internal registers |
read_data2_SCP when adr2(5)='1' else -- Selection of the coprocessor registers |
(others => '0'); |
-- Bypass the datas (the validity is tested later when detecting the hazards) |
data1 <= read_data1 when dep_r1=LVL_REG else -- DI recebe dado direto dos registradores |
MEM_data when dep_r1=LVL_MEM else -- DI recebe dado direto do MEM2 (MEM no original ) |
MEM_data2 when dep_r1=LVL_MEM2 else -- DI recebe dado direto do MEM2 (MEM no original ) |
EX_data when dep_r1=LVL_EX else -- DI recebe dado direto do EX2 (EX no original ) |
EX_data2 when dep_r1=LVL_EX2 else -- DI recebe dado direto do EX2 (EX no original ) |
DI_data when dep_r1=LVL_DI else |
DI_data2; -- DI recebe dado direto do DI2 (DI no original ) |
data2 <= read_data2 when dep_r2=LVL_REG else |
MEM_data when dep_r2=LVL_MEM else |
MEM_data2 when dep_r2=LVL_MEM2 else |
EX_data when dep_r2=LVL_EX else |
EX_data2 when dep_r2=LVL_EX2 else |
DI_data when dep_r2=LVL_DI else |
DI_data2; |
|
|
|
-- Connexion of the writing command signals |
write_data2 <= MEM_data2; |
write_adr2 <= MEM_adr2(4 downto 0); |
write_GPR2 <= not MEM_adr2(5) and MEM_ecr2 when interrupt = '0' else -- The high bit to 0 selects the internal registers |
'0'; |
--write_SCP <= MEM_adr(5) and MEM_ecr; -- The high bit to 1 selects the coprocessor system registers |
|
-- Connexion of the writing command signals |
read_adr3 <= adr3(4 downto 0); -- Connexion of the significative address bits (lido assincronamente pelo DI2) |
read_adr4 <= adr4(4 downto 0); -- Connexion of the significative address bits (lido assincronamente pelo DI2) |
|
-- Evaluation of the level of dependencies |
dep_r3 <= LVL_REG when adr3(4 downto 0)="00000" or use12='0' else -- No dependency with register 0, se use1 for igual a '0' aqui, significa que op1 = imm ou shamt |
LVL_DI when adr3=DI_adr and DI_ecr ='1' else -- Dependency with DI stage (reg. fonte = reg.destino no momento da escrita, (DI_ecr ='1')) |
LVL_EX when adr3=EX_adr and EX_ecr ='1' else -- Dependency with EX stage |
LVL_MEM when adr3=MEM_adr and MEM_ecr='1' else -- Dependency with MEM stage |
LVL_DI2 when adr3=DI_adr2 and DI_ecr2 = '1' else -- Dependency with DI stage (reg. fonte = reg.destino no momento da escrita, (DI_ecr ='1')) |
LVL_EX2 when adr3=EX_adr2 and EX_ecr2 = '1' else -- Dependency with EX stage |
LVL_MEM2 when adr3=MEM_adr2 and MEM_ecr2 ='1' else -- Dependency with MEM stage |
LVL_REG; -- No dependency detected |
dep_r4 <= LVL_REG when adr4(4 downto 0)="00000" or use22='0' else -- No dependency with register 0 |
LVL_DI when adr4=DI_adr and DI_ecr ='1' else -- Dependency with DI stage |
LVL_EX when adr4=EX_adr and EX_ecr ='1' else -- Dependency with EX stage |
LVL_MEM when adr4=MEM_adr and MEM_ecr='1' else -- Dependency with MEM stage |
LVL_DI2 when adr4=DI_adr2 and DI_ecr2 = '1' else -- Dependency with DI2 stage (reg. fonte = reg.destino no momento da escrita, (DI_ecr ='1')) |
LVL_EX2 when adr4=EX_adr2 and EX_ecr2 = '1' else -- Dependency with EX2 stage |
LVL_MEM2 when adr4=MEM_adr2 and MEM_ecr2 ='1' else -- Dependency with MEM stage |
LVL_REG; -- No dependency detected |
-- Elaboration of the signals with the datas form the bank registers |
read_data3 <= read_data3_GPR when adr3(5)='0' else -- Selection of the internal registers |
read_data3_SCP when adr3(5)='1' else -- Selection of the coprocessor registers |
(others => '0'); |
|
read_data4 <= read_data4_GPR when adr4(5)='0' else -- Selection of the internal registers |
read_data4_SCP when adr4(5)='1' else -- Selection of the coprocessor registers |
(others => '0'); |
|
|
data3 <= read_data3 when dep_r3=LVL_REG else -- DI recebe dado direto dos registradores |
MEM_data when dep_r3=LVL_MEM else -- DI recebe dado direto do MEM2 (MEM no original ) |
MEM_data2 when dep_r3=LVL_MEM2 else -- DI recebe dado direto do MEM2 (MEM no original ) |
EX_data when dep_r3=LVL_EX else -- DI recebe dado direto do EX2 (EX no original ) |
EX_data2 when dep_r3=LVL_EX2 else -- DI recebe dado direto do EX2 (EX no original ) |
DI_data when dep_r3=LVL_DI else |
DI_data2; -- DI recebe dado direto do DI2 (DI no original ) |
data4 <= read_data4 when dep_r4=LVL_REG else |
MEM_data when dep_r4=LVL_MEM else |
MEM_data2 when dep_r4=LVL_MEM2 else |
EX_data when dep_r4=LVL_EX else |
EX_data2 when dep_r4=LVL_EX2 else |
DI_data when dep_r4=LVL_DI else |
DI_data2; |
|
-- Detection of a potential unresolved hazard |
-- '1' significa que os dados estao atualizados, |
-- '0' nao, os dados ainda serao escritos <<< dep neste sentido nao eh hazard <<< dados repassado por forwarding ou bypassing para o DI/DI2 |
res_reg <= '1'; --This hazard is always resolved LVL_REG=0 ________ _______ _______ _______ |
res_mem <= '1' when MEM_level>=LVL_MEM else '0'; -- >= 1 | 3 | 2 | 1 | 0 | |
res_ex <= '1' when EX_level >=LVL_EX else '0'; -- >= 2 | DI | EX | MEM | REG | |
res_di <= '1' when DI_level >=LVL_DI else '0'; -- >= 3 |________|_______|_______|_______|___ |
res_mem2 <= '1' when MEM_level2>=LVL_MEM2 else '0'; -- >= 4 | 6 | 5 | 4 | 0 | |
res_ex2 <= '1' when EX_level2 >=LVL_EX2 else '0'; -- >= 5 | DI2 | EX2 | MEM2 | REG | |
res_di2 <= '1' when DI_level2 >=LVL_DI2 else '0'; -- >= 6 |________|_______|_______|_______| |
-- -- >>> dep neste sentido eh hazard >>> espera o proximo ciclo para entrar novamente no DI/DI2 |
-- Table defining the resolved hazard for each stage |
resolution <= res_di2 & res_ex2 & res_mem2 & res_di & res_ex & res_mem & res_reg; -- '1111111', se nao ocorrer hazard |
-- Verification of the validity of the transmitted datas (test the good resolution of the hazards) |
idx1 <= to_integer(unsigned(dep_r1(2 downto 0))); |
idx2 <= to_integer(unsigned(dep_r2(2 downto 0))); |
idx3 <= to_integer(unsigned(dep_r3(2 downto 0))); |
idx4 <= to_integer(unsigned(dep_r4(2 downto 0))); |
|
alea <= (not resolution(idx1) or not resolution(idx2)); |
alea2 <= (not resolution(idx3) or not resolution(idx4)); |
|
end rtl; |
/P0/sources/syscop.vhd
0,0 → 1,220
-------------------------------------------------------------------------- |
-- -- |
-- -- |
-- miniMIPS Superscalar Processor : Coprocessor system (cop0) -- |
-- based on miniMIPS Processor -- |
-- -- |
-- -- |
-- Author : Miguel Cafruni -- |
-- miguel_cafruni@hotmail.com -- |
-- December 2018 -- |
-------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.numeric_std.all; |
|
library work; |
use work.pack_mips.all; |
|
-- By convention in the commentary, the term interruption means hardware interruptions and software exceptions |
|
entity syscop is |
port |
( |
clock : in std_logic; |
reset : in std_logic; |
|
-- Datas from the pipeline |
MEM_adr : in bus32; -- Address (PC) of the current instruction in the pipeline end -> responsible of the exception |
MEM_exc_cause : in bus32; -- Potential cause exception of that instruction |
MEM_it_ok : in std_logic; -- Allow hardware interruptions |
|
-- Hardware interruption |
it_mat : in std_logic; -- Hardware interruption detected |
|
-- Interruption controls |
interrupt : out std_logic; -- Interruption to take into account |
vecteur_it : out bus32; -- Interruption vector |
|
-- Writing request in register bank |
write_data : in bus32; -- Data to write |
write_adr : in bus5; -- Address of the register to write |
write_SCP : in std_logic; -- Writing request |
|
-- Reading request in register bank |
read_adr1 : in bus5; -- Address of the first register |
read_adr2 : in bus5; -- Address of the second register |
read_data1 : out bus32; -- Value of register 1 |
read_data2 : out bus32; -- Value of register 2 |
|
-- Datas from the pipeline |
MEM_adr2 : in bus32; -- Address of the current instruction in the pipeline end -> responsible of the exception |
MEM_exc_cause2 : in bus32; -- Potential cause exception of that instruction |
MEM_it_ok2 : in std_logic; -- Allow hardware interruptions |
|
-- Hardware interruption |
--it_mat2 : in std_logic; -- Hardware interruption detected |
|
-- Interruption controls |
--interrupt : out std_logic; -- Interruption to take into account |
--vecteur_it : out bus32; -- Interruption vector |
|
-- Writing request in register bank |
write_data2 : in bus32; -- Data to write |
write_adr2 : in bus5; -- Address of the register to write |
write_SCP2 : in std_logic; -- Writing request |
|
-- Reading request in register bank |
read_adr3 : in bus5; -- Address of the 3th register |
read_adr4 : in bus5; -- Address of the 4th register |
read_data3 : out bus32; -- Value of register 3 |
read_data4 : out bus32 -- Value of register 4 |
); |
end syscop; |
|
|
architecture rtl of syscop is |
|
subtype adr_scp_reg is integer range 12 to 15; |
|
type scp_reg_type is array (integer range adr_scp_reg'low to adr_scp_reg'high) of bus32; |
|
-- Constants to define the coprocessor registers |
constant COMMAND : integer := 0; -- False register to command the coprocessor system |
constant STATUS : adr_scp_reg := 12; -- Registre 12 of the coprocessor system |
constant CAUSE : adr_scp_reg := 13; -- Registre 13 of the coprocessor system |
constant ADRESSE : adr_scp_reg := 14; -- Registre 14 of the coprocessor system |
constant VECTIT : adr_scp_reg := 15; -- Registre 15 of the coprocessor system |
|
signal scp_reg : scp_reg_type; -- Internal register bank |
signal pre_reg : scp_reg_type; -- Register bank preparation |
|
signal adr_src1 : integer range 0 to 31; |
signal adr_src2 : integer range 0 to 31; |
signal adr_dest : integer range 0 to 31; |
--mod |
signal adr_src3 : integer range 0 to 31; |
signal adr_src4 : integer range 0 to 31; |
signal adr_dest2 : integer range 0 to 31; |
--fim mod |
signal exception, exception2 : std_logic; -- Set to '1' when exception detected *** quando MEM_exc_cause for diferente de IT_NOEXC |
signal interruption, interruption2 : std_logic; -- Set to '1' when interruption detected |
signal cmd_itret : std_logic; -- Set to '1' when interruption return command is detected |
|
signal save_msk : std_logic; -- Save the mask state when an interruption occurs |
|
begin |
|
-- Detection of the interruptions |
exception <= '1' when MEM_exc_cause/=IT_NOEXC else '0'; -- *** chegou uma instrucao ilegal ou break ou syscall *** |
exception2 <= '1' when MEM_exc_cause2/=IT_NOEXC else '0'; -- *** chegou uma instrucao ilegal ou break ou syscall *** |
interruption <= '1' when it_mat='1' and scp_reg(STATUS)(0)='1' and MEM_it_ok='1' else '0'; |
interruption2 <= '1' when it_mat='1' and scp_reg(STATUS)(0)='1' and MEM_it_ok2='1' else '0'; |
-- Update asynchronous outputs |
interrupt <= exception or exception2 or interruption or interruption2; -- Detection of interruptions |
vecteur_it <= scp_reg(ADRESSE) when cmd_itret = '1' else -- Send the return adress when a return instruction appears -- *** retorno de uma instrucao ilegal ou break ou syscall *** |
scp_reg(VECTIT); -- Send the interruption vector in other cases |
|
|
-- Decode the address of the registers |
adr_src1 <= to_integer(unsigned(read_adr1)); |
adr_src2 <= to_integer(unsigned(read_adr2)); |
adr_dest <= to_integer(unsigned(write_adr)); |
--mod |
adr_src3 <= to_integer(unsigned(read_adr3)); |
adr_src4 <= to_integer(unsigned(read_adr4)); |
adr_dest2 <= to_integer(unsigned(write_adr2)); |
--fim mod |
-- Read the two registers |
read_data1 <= (others => '0') when (adr_src1<scp_reg'low or adr_src1>scp_reg'high) else |
scp_reg(adr_src1); |
read_data2 <= (others => '0') when (adr_src2<scp_reg'low or adr_src2>scp_reg'high) else |
scp_reg(adr_src2); |
--mod |
-- Read the two registers |
read_data3 <= (others => '0') when (adr_src3<scp_reg'low or adr_src3>scp_reg'high) else |
scp_reg(adr_src3); |
read_data4 <= (others => '0') when (adr_src4<scp_reg'low or adr_src4>scp_reg'high) else -- erro de copia e cola |
scp_reg(adr_src4); -- arrumado em 04\12\17 |
--fim mod |
|
-- Define the pre_reg signal, next value for the registers |
process (scp_reg, adr_dest, write_SCP, write_data, interruption, interruption2,--process (scp_reg, adr_dest, write_SCP, write_data, interruption, |
exception, exception2, MEM_exc_cause, MEM_adr, reset, adr_dest2, write_SCP2, write_data2, MEM_exc_cause2, MEM_adr2)--exception, MEM_exc_cause, MEM_adr, reset) |
begin -- *** exception eh um sinal interno e tambem pode ser tratado em um processo *** -- |
pre_reg <= scp_reg; |
cmd_itret <= '0'; -- No IT return in most cases |
|
-- Potential writing in a register |
if (write_SCP='1' and adr_dest>=pre_reg'low and adr_dest<=pre_reg'high) then |
pre_reg(adr_dest) <= write_data; |
end if; |
--mod |
-- Potential writing in a register from 2nd pipe |
if (write_SCP2='1' and adr_dest2>=pre_reg'low and adr_dest2<=pre_reg'high) then |
pre_reg(adr_dest2) <= write_data2; |
end if; |
--fim mod |
|
-- Command from the core |
if write_SCP='1' and adr_dest=COMMAND then |
case write_data is -- Different operations |
when SYS_UNMASK => pre_reg(STATUS)(0) <= '1'; -- Unamsk command |
when SYS_MASK => pre_reg(STATUS)(0) <= '0'; -- Mask command |
when SYS_ITRET => -- Interruption return command |
pre_reg(STATUS)(0) <= save_msk; -- Restore the mask before the interruption |
cmd_itret <= '1'; -- False interruption request (to clear the pipeline) |
when others => null; |
end case; |
end if; |
|
-- Modifications from the interruptions |
if interruption='1' then |
pre_reg(STATUS)(0) <= '0'; -- Mask the interruptions |
pre_reg(CAUSE) <= IT_ITMAT; -- Save the interruption cause |
pre_reg(ADRESSE) <= MEM_adr; -- Save the return address |
end if; |
|
-- Modifications from the interruptions |
if interruption2='1' then |
pre_reg(STATUS)(0) <= '0'; -- Mask the interruptions |
pre_reg(CAUSE) <= IT_ITMAT; -- Save the interruption cause |
pre_reg(ADRESSE) <= MEM_adr2; -- Save the return address |
end if; |
|
-- Modifications from the exceptions |
if exception='1' then -- *** chegou uma instrucao ilegal ou break ou syscall *** |
pre_reg(STATUS)(0) <= '0'; -- Mask the interruptions |
pre_reg(CAUSE) <= MEM_exc_cause; -- Save the exception cause |
pre_reg(ADRESSE) <= MEM_adr; -- Save the return address |
end if; |
|
-- Modifications from the exceptions |
if exception2='1' then -- *** chegou uma instrucao ilegal ou break ou syscall *** |
pre_reg(STATUS)(0) <= '0'; -- Mask the interruptions |
pre_reg(CAUSE) <= MEM_exc_cause2; -- Save the exception cause |
pre_reg(ADRESSE) <= MEM_adr2; -- Save the return address |
end if; |
-- The reset has the priority on the other cuases |
if reset='1' then |
pre_reg <= (others => (others => '0')); |
|
-- NB : The processor is masked after a reset |
-- The exception handler is set at address 0 |
end if; |
end process; |
|
-- Memorisation of the modifications in the register bank |
process(clock) |
begin |
if clock='1' and clock'event then |
-- Save the mask when an interruption appears |
if (exception='1') or (interruption='1') or (exception2='1') or (interruption2='1') then |
save_msk <= scp_reg(STATUS)(0); |
end if; |
scp_reg <= pre_reg; |
end if; |
end process; |
|
end rtl; |