OpenCores
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/trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/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;
/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;
/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;
/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;
/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;
/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;
/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;
/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;
/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;
/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;
 
 
/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;
 
 
/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;
/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;
/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;
/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;
/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;
/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;
/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;

powered by: WebSVN 2.1.0

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