Line 17... |
Line 17... |
clk_i: in std_logic;
|
clk_i: in std_logic;
|
rst_i: in std_logic;
|
rst_i: in std_logic;
|
|
|
word_i: in std_logic_vector(31 downto 0);
|
word_i: in std_logic_vector(31 downto 0);
|
next_ip_i: in std_logic_vector(29 downto 0);
|
next_ip_i: in std_logic_vector(29 downto 0);
|
|
current_ip_i: in std_logic_vector(29 downto 0);
|
valid_i: in std_logic;
|
valid_i: in std_logic;
|
jump_valid_i: in std_logic;
|
jump_valid_i: in std_logic;
|
ready_o: out std_logic;
|
ready_o: out std_logic;
|
|
|
interrupt_valid_i: in std_logic;
|
interrupt_valid_i: in std_logic;
|
Line 46... |
Line 47... |
cmd_div_mod_o: out std_logic;
|
cmd_div_mod_o: out std_logic;
|
cmd_cmp_o: out std_logic;
|
cmd_cmp_o: out std_logic;
|
cmd_jump_o: out std_logic;
|
cmd_jump_o: out std_logic;
|
cmd_negate_op2_o: out std_logic;
|
cmd_negate_op2_o: out std_logic;
|
cmd_and_o: out std_logic;
|
cmd_and_o: out std_logic;
|
cmd_or_o: out std_logic;
|
|
cmd_xor_o: out std_logic;
|
cmd_xor_o: out std_logic;
|
cmd_shift_o: out std_logic;
|
cmd_shift_o: out std_logic;
|
cmd_shift_right_o: out std_logic;
|
cmd_shift_right_o: out std_logic;
|
|
|
jump_type_o: out std_logic_vector(3 downto 0);
|
jump_type_o: out std_logic_vector(3 downto 0);
|
Line 76... |
Line 76... |
signal t2: std_logic;
|
signal t2: std_logic;
|
signal destination: std_logic_vector(7 downto 0);
|
signal destination: std_logic_vector(7 downto 0);
|
signal rd1: std_logic_vector(7 downto 0);
|
signal rd1: std_logic_vector(7 downto 0);
|
signal rd2: std_logic_vector(7 downto 0);
|
signal rd2: std_logic_vector(7 downto 0);
|
|
|
signal current_ip: unsigned(next_ip_i'range);
|
|
|
|
-- Signals related to pipeline control
|
-- Signals related to pipeline control
|
|
|
signal downstream_busy: std_logic;
|
signal downstream_busy: std_logic;
|
signal self_busy: std_logic:='0';
|
signal self_busy: std_logic:='0';
|
signal busy: std_logic;
|
signal busy: std_logic;
|
Line 117... |
Line 115... |
-- Pipeline control
|
-- Pipeline control
|
|
|
downstream_busy<=valid_out and not ready_i;
|
downstream_busy<=valid_out and not ready_i;
|
busy<=downstream_busy or self_busy;
|
busy<=downstream_busy or self_busy;
|
|
|
current_ip<=unsigned(next_ip_i)-1;
|
|
|
|
process (clk_i) is
|
process (clk_i) is
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if rising_edge(clk_i) then
|
if rst_i='1' then
|
if rst_i='1' then
|
valid_out<='0';
|
valid_out<='0';
|
self_busy<='0';
|
self_busy<='0';
|
state<=Regular;
|
state<=Regular;
|
interrupt_ready<='0';
|
interrupt_ready<='0';
|
|
cmd_loadop3_o<='-';
|
|
cmd_signed_o<='-';
|
|
cmd_dbus_o<='-';
|
|
cmd_dbus_store_o<='-';
|
|
cmd_dbus_byte_o<='-';
|
|
cmd_addsub_o<='-';
|
|
cmd_negate_op2_o<='-';
|
|
cmd_mul_o<='-';
|
|
cmd_div_o<='-';
|
|
cmd_div_mod_o<='-';
|
|
cmd_cmp_o<='-';
|
|
cmd_jump_o<='-';
|
|
cmd_and_o<='-';
|
|
cmd_xor_o<='-';
|
|
cmd_shift_o<='-';
|
|
cmd_shift_right_o<='-';
|
|
rd1_select<='-';
|
|
rd1_direct<=(others=>'-');
|
|
rd2_select<='-';
|
|
rd2_direct<=(others=>'-');
|
|
op3_o<=(others=>'-');
|
|
jump_type_o<=(others=>'-');
|
|
dst_out<=(others=>'-');
|
else
|
else
|
interrupt_ready<='0';
|
interrupt_ready<='0';
|
if jump_valid_i='1' then
|
if jump_valid_i='1' then
|
valid_out<='0';
|
valid_out<='0';
|
self_busy<='0';
|
self_busy<='0';
|
state<=Regular;
|
state<=Regular;
|
elsif downstream_busy='0' then
|
elsif downstream_busy='0' then
|
|
op3_o<=(others=>'-');
|
|
rd1_direct<=std_logic_vector(resize(signed(rd1),rd1_direct'length));
|
|
rd2_direct<=std_logic_vector(resize(signed(rd2),rd2_direct'length));
|
|
|
|
cmd_signed_o<=opcode(0);
|
|
cmd_div_mod_o<=opcode(1);
|
|
cmd_shift_right_o<=opcode(1);
|
|
cmd_dbus_byte_o<=opcode(1);
|
|
cmd_dbus_store_o<=opcode(2);
|
|
|
case state is
|
case state is
|
when Regular =>
|
when Regular =>
|
cmd_loadop3_o<='0';
|
cmd_loadop3_o<='0';
|
cmd_signed_o<='0';
|
|
cmd_dbus_o<='0';
|
cmd_dbus_o<='0';
|
cmd_dbus_store_o<='0';
|
|
cmd_dbus_byte_o<='0';
|
|
cmd_addsub_o<='0';
|
cmd_addsub_o<='0';
|
cmd_negate_op2_o<='0';
|
cmd_negate_op2_o<='0';
|
cmd_mul_o<='0';
|
cmd_mul_o<='0';
|
cmd_div_o<='0';
|
cmd_div_o<='0';
|
cmd_div_mod_o<='0';
|
|
cmd_cmp_o<='0';
|
cmd_cmp_o<='0';
|
cmd_jump_o<='0';
|
cmd_jump_o<='0';
|
cmd_and_o<='0';
|
cmd_and_o<='0';
|
cmd_or_o<='0';
|
|
cmd_xor_o<='0';
|
cmd_xor_o<='0';
|
cmd_shift_o<='0';
|
cmd_shift_o<='0';
|
cmd_shift_right_o<='0';
|
|
|
|
op3_o<=(others=>'-');
|
|
|
|
jump_type_o<=opcode(3 downto 0);
|
jump_type_o<=opcode(3 downto 0);
|
|
|
if interrupt_valid_i='1' and valid_i='1' then
|
if interrupt_valid_i='1' and valid_i='1' then
|
cmd_jump_o<='1';
|
cmd_jump_o<='1';
|
cmd_loadop3_o<='1';
|
cmd_loadop3_o<='1';
|
op3_o<=std_logic_vector(current_ip)&"01"; -- LSB indicates interrupt return
|
op3_o<=current_ip_i&"01"; -- LSB indicates interrupt return
|
dst_out<=X"FD"; -- interrupt return pointer
|
dst_out<=X"FD"; -- interrupt return pointer
|
rd1_select<='1';
|
rd1_select<='1';
|
rd2_select<='0';
|
rd2_select<='0';
|
valid_out<='1';
|
valid_out<='1';
|
interrupt_ready<='1';
|
interrupt_ready<='1';
|
self_busy<='1';
|
self_busy<='1';
|
state<=ContinueInterrupt;
|
state<=ContinueInterrupt;
|
else
|
else
|
if opcode="000001" then
|
if opcode(5 downto 3)="101" or opcode="000001" then -- lc or lcs
|
cmd_loadop3_o<='1';
|
cmd_loadop3_o<='1';
|
|
-- Setting op3_o here only affects the lcs instruction
|
|
op3_o<=std_logic_vector(resize(signed(opcode(2 downto 0)&
|
|
t1&t2&rd1&rd2),op3_o'length));
|
end if;
|
end if;
|
|
|
cmd_signed_o<=opcode(0);
|
|
|
|
if opcode(5 downto 3)="001" then
|
if opcode(5 downto 3)="001" then
|
cmd_dbus_o<='1';
|
cmd_dbus_o<='1';
|
end if;
|
end if;
|
|
|
cmd_dbus_store_o<=opcode(2);
|
|
cmd_dbus_byte_o<=opcode(1);
|
|
|
|
if opcode(5 downto 1)="01000" then
|
if opcode(5 downto 1)="01000" then
|
cmd_addsub_o<='1';
|
cmd_addsub_o<='1';
|
end if;
|
end if;
|
|
|
cmd_negate_op2_o<=opcode(0);
|
cmd_negate_op2_o<=opcode(0);
|
Line 197... |
Line 216... |
|
|
if opcode(5 downto 2)="0101" then
|
if opcode(5 downto 2)="0101" then
|
cmd_div_o<='1';
|
cmd_div_o<='1';
|
end if;
|
end if;
|
|
|
cmd_div_mod_o<=opcode(1);
|
if opcode(5 downto 3)="100" then -- jump or call
|
|
|
if opcode="100000" then
|
|
cmd_jump_o<='1';
|
|
end if;
|
|
|
|
if opcode="100001" then
|
|
cmd_jump_o<='1';
|
cmd_jump_o<='1';
|
cmd_loadop3_o<='1';
|
cmd_loadop3_o<=opcode(0);
|
|
-- Setting op3_o here only affects the call instruction
|
op3_o<=next_ip_i&"00";
|
op3_o<=next_ip_i&"00";
|
end if;
|
end if;
|
|
|
if opcode="011000" then
|
-- Note: (a or b) = (a and b) or (a xor b)
|
cmd_and_o<='1';
|
|
end if;
|
|
|
|
if opcode="011001" then
|
if opcode(5 downto 1)="01100" then
|
cmd_or_o<='1';
|
cmd_and_o<='1';
|
end if;
|
end if;
|
|
|
if opcode="011010" then
|
if opcode="011010" or opcode="011001" then
|
cmd_xor_o<='1';
|
cmd_xor_o<='1';
|
end if;
|
end if;
|
|
|
if opcode(5 downto 2)="0111" then
|
if opcode(5 downto 2)="0111" then
|
cmd_shift_o<='1';
|
cmd_shift_o<='1';
|
end if;
|
end if;
|
|
|
cmd_shift_right_o<=opcode(1);
|
|
|
|
if opcode(5 downto 4)="11" then
|
if opcode(5 downto 4)="11" then
|
cmd_cmp_o<='1';
|
cmd_cmp_o<='1';
|
cmd_negate_op2_o<='1';
|
cmd_negate_op2_o<='1';
|
end if;
|
end if;
|
|
|
rd1_select<=t1;
|
rd1_select<=t1;
|
rd1_direct<=std_logic_vector(resize(signed(rd1),rd1_direct'length));
|
|
rd2_select<=t2;
|
rd2_select<=t2;
|
rd2_direct<=std_logic_vector(resize(signed(rd2),rd2_direct'length));
|
|
|
|
dst_out<=destination;
|
dst_out<=destination;
|
|
|
if valid_i='1' then
|
if valid_i='1' then
|
if opcode="000001" then
|
if opcode="000001" then
|