Line 71... |
Line 71... |
-- :
|
-- :
|
-- Revision History
|
-- Revision History
|
-- Author Date Change
|
-- Author Date Change
|
------------------ -------- ---------------------------------------------------
|
------------------ -------- ---------------------------------------------------
|
-- Seth Henry 07/19/06 Design Start
|
-- Seth Henry 07/19/06 Design Start
|
|
-- Seth Henry 01/18/11 Fixed BTT instruction to match V8
|
|
|
library ieee;
|
library ieee;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_arith.all;
|
use ieee.std_logic_arith.all;
|
Line 91... |
Line 92... |
Default_Interrupt_Mask : DATA_TYPE := x"FF"; -- Enable all Ints
|
Default_Interrupt_Mask : DATA_TYPE := x"FF"; -- Enable all Ints
|
Enable_CPU_Halt : std_logic := '0'; -- Disable HALT pin
|
Enable_CPU_Halt : std_logic := '0'; -- Disable HALT pin
|
Enable_Auto_Increment : std_logic := '0' ); -- Modify indexed instr
|
Enable_Auto_Increment : std_logic := '0' ); -- Modify indexed instr
|
port(
|
port(
|
Clock : in std_logic;
|
Clock : in std_logic;
|
Reset_n : in std_logic;
|
Reset : in std_logic;
|
CPU_Halt : in std_logic;
|
CPU_Halt : in std_logic;
|
Interrupts : in INTERRUPT_BUNDLE;
|
Interrupts : in INTERRUPT_BUNDLE;
|
--
|
--
|
Address : out ADDRESS_TYPE;
|
Address : out ADDRESS_TYPE;
|
Rd_Data : in DATA_TYPE;
|
Rd_Data : in DATA_TYPE;
|
Line 131... |
Line 132... |
constant ALU_UPP : OPCODE_TYPE := "11000"; -- x"18"
|
constant ALU_UPP : OPCODE_TYPE := "11000"; -- x"18"
|
constant ALU_LDI : OPCODE_TYPE := "11100"; -- x"1C"
|
constant ALU_LDI : OPCODE_TYPE := "11100"; -- x"1C"
|
constant ALU_LDX : OPCODE_TYPE := "11110"; -- x"1E"
|
constant ALU_LDX : OPCODE_TYPE := "11110"; -- x"1E"
|
|
|
constant ALU_IDLE : OPCODE_TYPE := "10000"; -- x"10"
|
constant ALU_IDLE : OPCODE_TYPE := "10000"; -- x"10"
|
constant ALU_UPP2 : OPCODE_TYPE := "10010"; -- x"11"
|
constant ALU_UPP2 : OPCODE_TYPE := "10010"; -- x"12"
|
constant ALU_RFLG : OPCODE_TYPE := "10011"; -- x"12"
|
constant ALU_RFLG : OPCODE_TYPE := "10011"; -- x"13"
|
|
|
constant FL_ZERO : integer := 0;
|
constant FL_ZERO : integer := 0;
|
constant FL_CARRY : integer := 1;
|
constant FL_CARRY : integer := 1;
|
constant FL_NEG : integer := 2;
|
constant FL_NEG : integer := 2;
|
constant FL_INT_EN : integer := 3;
|
constant FL_INT_EN : integer := 3;
|
Line 384... |
Line 385... |
Flags_D(FL_NEG) <= Sum(7);
|
Flags_D(FL_NEG) <= Sum(7);
|
|
|
when ALU_STP => -- Sets bit(n) in the Flags register
|
when ALU_STP => -- Sets bit(n) in the Flags register
|
Flags_D(Index) <= '1';
|
Flags_D(Index) <= '1';
|
|
|
when ALU_BTT => -- Tests if R0 is negative or zero. No change to R0
|
when ALU_BTT => -- Z = !R0(N), N = R0(7)
|
Temp := "0" & Regfile(Index);
|
Flags_D(FL_ZERO) <= not Regfile(0)(Index);
|
Flags_D(FL_ZERO) <= '0';
|
Flags_D(FL_NEG) <= Regfile(0)(7);
|
if( Temp(7 downto 0) = 0 )then
|
-- Temp := "0" & Regfile(Index);
|
Flags_D(FL_ZERO) <= '1';
|
-- Flags_D(FL_ZERO) <= '0';
|
end if;
|
-- if( Temp(7 downto 0) = 0 )then
|
Flags_D(FL_NEG) <= Temp(7);
|
-- Flags_D(FL_ZERO) <= '1';
|
|
-- end if;
|
|
-- Flags_D(FL_NEG) <= Temp(7);
|
|
|
when ALU_CLP => -- Clears bit(n) in the Flags register
|
when ALU_CLP => -- Clears bit(n) in the Flags register
|
Flags_D(Index) <= '0';
|
Flags_D(Index) <= '0';
|
|
|
when ALU_T0X => -- Rn = R0 : Flags N,Z
|
when ALU_T0X => -- Rn = R0 : Flags N,Z
|
Line 415... |
Line 418... |
Flags_D(FL_ZERO) <= '1';
|
Flags_D(FL_ZERO) <= '1';
|
end if;
|
end if;
|
Flags_D(FL_CARRY) <= Sum(8);
|
Flags_D(FL_CARRY) <= Sum(8);
|
Flags_D(FL_NEG) <= Sum(7);
|
Flags_D(FL_NEG) <= Sum(7);
|
|
|
when ALU_MUL => -- Stage 1 of 2 {R1:R0} = R0 * Rn : Flags N,Z
|
when ALU_MUL => -- Stage 1 of 2 {R1:R0} = R0 * Rn : Flags Z
|
Regfile_D(0) <= Mult(7 downto 0);
|
Regfile_D(0) <= Mult(7 downto 0);
|
Regfile_D(1) <= Mult(15 downto 8);
|
Regfile_D(1) <= Mult(15 downto 8);
|
Flags_D(FL_ZERO) <= '0';
|
Flags_D(FL_ZERO) <= '0';
|
if( Mult = 0 )then
|
if( Mult = 0 )then
|
Flags_D(FL_ZERO) <= '1';
|
Flags_D(FL_ZERO) <= '1';
|
Line 462... |
Line 465... |
Mult <= Regfile(0) *
|
Mult <= Regfile(0) *
|
Regfile(conv_integer(ALU_Ctrl.Reg));
|
Regfile(conv_integer(ALU_Ctrl.Reg));
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
S_Regs: process( Reset_n, Clock )
|
S_Regs: process( Reset, Clock )
|
begin
|
begin
|
if( Reset_n = '0' )then
|
if( Reset = '1' )then
|
for i in 0 to 7 loop
|
for i in 0 to 7 loop
|
Regfile(i) <= (others => '0');
|
Regfile(i) <= (others => '0');
|
end loop;
|
end loop;
|
Flags <= x"00";
|
Flags <= x"00";
|
elsif( rising_edge(Clock) )then
|
elsif( rising_edge(Clock) )then
|
Line 501... |
Line 504... |
if( PC_Ctrl.Oper = PC_REV2 )then
|
if( PC_Ctrl.Oper = PC_REV2 )then
|
Rewind_1_2n <= '0';
|
Rewind_1_2n <= '0';
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
Program_Counter: process( Reset_n, Clock, Halt, PC_Ctrl, PC_Q, Rewind_1_2n )
|
Program_Counter: process( Reset, Clock, Halt, PC_Ctrl, PC_Q, Rewind_1_2n )
|
variable PC_Offset_SX : ADDRESS_TYPE := x"0000";
|
variable PC_Offset_SX : ADDRESS_TYPE := x"0000";
|
begin
|
begin
|
PC_Offset_SX(15 downto 8):= (others => PC_Ctrl.Offset(7));
|
PC_Offset_SX(15 downto 8):= (others => PC_Ctrl.Offset(7));
|
PC_Offset_SX(7 downto 0) := PC_Ctrl.Offset;
|
PC_Offset_SX(7 downto 0) := PC_Ctrl.Offset;
|
if( Reset_n = '0' )then
|
if( Reset = '1' )then
|
PC_Q <= Program_Start_Addr;
|
PC_Q <= Program_Start_Addr;
|
elsif( rising_edge(Clock) )then
|
elsif( rising_edge(Clock) )then
|
if( Halt = '0' )then
|
if( Halt = '0' )then
|
case PC_Ctrl.Oper is
|
case PC_Ctrl.Oper is
|
when PC_IDLE =>
|
when PC_IDLE =>
|
Line 537... |
Line 540... |
signal SP_Q : ADDRESS_TYPE := (others => '0');
|
signal SP_Q : ADDRESS_TYPE := (others => '0');
|
begin
|
begin
|
|
|
SP <= SP_Q;
|
SP <= SP_Q;
|
|
|
Stack_Pointer: process( Reset_n, Clock )
|
Stack_Pointer: process( Reset, Clock )
|
begin
|
begin
|
if( Reset_n = '0' )then
|
if( Reset = '1' )then
|
SP_Q <= Stack_Start_Addr;
|
SP_Q <= Stack_Start_Addr;
|
elsif( rising_edge(Clock) )then
|
elsif( rising_edge(Clock) )then
|
if( Halt = '0' )then
|
if( Halt = '0' )then
|
case SP_Ctrl.Oper is
|
case SP_Ctrl.Oper is
|
when SP_IDLE => null;
|
when SP_IDLE => null;
|
Line 664... |
Line 667... |
Int_Trig <= '1';
|
Int_Trig <= '1';
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
S_Regs: process( Reset_n, Clock )
|
S_Regs: process( Reset, Clock )
|
begin
|
begin
|
if( Reset_n = '0' )then
|
if( Reset = '1' )then
|
Int_Req <= '0';
|
Int_Req <= '0';
|
Pending <= x"00";
|
Pending <= x"00";
|
Wait_for_FSM <= '0';
|
Wait_for_FSM <= '0';
|
Mask <= Default_Interrupt_Mask(7 downto 1);
|
Mask <= Default_Interrupt_Mask(7 downto 1);
|
ISR_Q <= INT_VECTOR_0;
|
ISR_Q <= INT_VECTOR_0;
|
Line 1323... |
Line 1326... |
end if;
|
end if;
|
end if;
|
end if;
|
|
|
end process;
|
end process;
|
|
|
S_Regs: process( Reset_n, Clock )
|
S_Regs: process( Reset, Clock )
|
begin
|
begin
|
if( Reset_n = '0' )then
|
if( Reset = '1' )then
|
CPU_State <= PIPE_FILL_0;
|
CPU_State <= PIPE_FILL_0;
|
Opcode <= OP_INC;
|
Opcode <= OP_INC;
|
SubOp <= ACCUM;
|
SubOp <= ACCUM;
|
SubOp_p1 <= ACCUM;
|
SubOp_p1 <= ACCUM;
|
Operand1 <= x"00";
|
Operand1 <= x"00";
|
Line 1473... |
Line 1476... |
for i in 0 to 7 loop
|
for i in 0 to 7 loop
|
Wr_Data_D(i) <= Reg_Mux(i) or Flag_Mux(i) or PC_Mux(i);
|
Wr_Data_D(i) <= Reg_Mux(i) or Flag_Mux(i) or PC_Mux(i);
|
end loop;
|
end loop;
|
end process;
|
end process;
|
|
|
S_Regs: process( Reset_n, Clock )
|
S_Regs: process( Reset, Clock )
|
begin
|
begin
|
if( Reset_n = '0' )then
|
if( Reset = '1' )then
|
Wr_Data <= (others => '0');
|
Wr_Data <= (others => '0');
|
Wr_Enable <= '0';
|
Wr_Enable <= '0';
|
Rd_Enable <= '1';
|
Rd_Enable <= '1';
|
elsif( rising_edge(Clock) )then
|
elsif( rising_edge(Clock) )then
|
if( Halt = '0' )then
|
if( Halt = '0' )then
|
Line 1492... |
Line 1495... |
|
|
end block;
|
end block;
|
|
|
end rtl;
|
end rtl;
|
|
|
No newline at end of file
|
No newline at end of file
|
|
|
No newline at end of file
|
No newline at end of file
|