URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/open8_urisc
- from Rev 154 to Rev 155
- ↔ Reverse comparison
Rev 154 → Rev 155
/trunk/VHDL/Open8.vhd
74,6 → 74,10
------------------ -------- --------------------------------------------------- |
-- Seth Henry 07/19/06 Design Start |
-- Seth Henry 01/18/11 Fixed BTT instruction to match V8 |
-- Seth Henry 07/22/11 Fixed interrupt transition logic to avoid data |
-- corruption issues. |
-- Seth Henry 07/26/11 Optimized logic in ALU, stack pointer, and data path |
-- sections. |
|
library ieee; |
use ieee.std_logic_1164.all; |
224,261 → 228,234
end generate; |
|
------------------------------------------------------------------------------- |
-- ALU (Arithmetic / Logic Unit |
-- ALU (Arithmetic / Logic Unit) |
-- Notes: |
-- 1) Infers a multiplier in Xilinx/Altera parts - should be checked in others |
------------------------------------------------------------------------------- |
|
Open8_ALU : block is |
|
-- Preinitialization is for simulation only - check actual reset conditions |
signal Regfile_D, Regfile : REGFILE_TYPE := (others => (others => '0') ); |
signal Flags_D, Flags : FLAG_TYPE := (others => '0'); |
signal Mult : ADDRESS_TYPE := (others => '0'); |
|
signal Sum : std_logic_vector(8 downto 0) := (others => '0'); |
signal Addend_A, Addend_B : DATA_TYPE := (others => '0'); |
signal Carry : std_logic := '0'; |
|
signal Regfile : REGFILE_TYPE := (others => (others => '0') ); |
signal Flags : FLAG_TYPE := (others => '0'); |
signal Mult : ADDRESS_TYPE := (others => '0'); |
begin |
|
ALU_Regs <= Regfile; |
ALU_Flags <= Flags; |
|
ALU_proc: process( ALU_Ctrl, Regfile, Flags, Mult, Sum ) |
-- We need to infer a hardware multipler, so we create a special clocked |
-- process with no reset or clock enable |
Multiplier: process( Clock ) |
begin |
if( rising_edge(Clock) )then |
Mult <= Regfile(0) * |
Regfile(conv_integer(ALU_Ctrl.Reg)); |
end if; |
end process; |
|
ALU: process( Reset, Clock ) |
variable Sum : std_logic_vector(8 downto 0) := "000000000"; |
variable Index : integer range 0 to 7 := 0; |
variable Temp : std_logic_vector(8 downto 0); |
begin |
Regfile_D <= Regfile; |
Flags_D <= Flags; |
Addend_A <= x"00"; |
Addend_B <= x"00"; |
Carry <= '0'; |
if( Reset = Reset_Level )then |
for i in 0 to 7 loop |
Regfile(i) <= (others => '0'); |
end loop; |
Flags <= x"00"; |
elsif( rising_edge(Clock) )then |
Temp := (others => '0'); |
Index := conv_integer(ALU_Ctrl.Reg); |
if( Halt = '0' )then |
case ALU_Ctrl.Oper is |
when ALU_INC | ALU_UPP => -- Rn = Rn + 1 : Flags N,C,Z |
Sum := ("0" & x"01") + |
("0" & Regfile(Index)); |
Flags(FL_CARRY) <= Sum(8); |
Regfile(Index) <= Sum(7 downto 0); |
-- ALU_INC and ALU_UPP are essentially the same, except that ALU_UPP |
-- doesn't set the N or Z flags. Note that the MSB can be used to |
-- distinguish between the two ALU modes. |
if( ALU_Ctrl.Oper(4) = '0' )then |
Flags(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags(FL_ZERO)<= '1'; |
end if; |
Flags(FL_NEG) <= Sum(7); |
end if; |
|
Temp := (others => '0'); |
Index := conv_integer(ALU_Ctrl.Reg); |
when ALU_UPP2 => -- Rn = Rn + C |
Sum := ("0" & x"00") + |
("0" & Regfile(Index)) + |
Flags(FL_CARRY); |
Flags(FL_CARRY) <= Sum(8); |
Regfile(Index) <= Sum(7 downto 0); |
|
case ALU_Ctrl.Oper is |
when ALU_INC | ALU_UPP => -- Rn = Rn + 1 : Flags N,C,Z |
Addend_A <= x"01"; |
Addend_B <= Regfile(Index); |
Flags_D(FL_CARRY) <= Sum(8); |
Regfile_D(Index) <= Sum(7 downto 0); |
-- ALU_INC and ALU_UPP are essentially the same, except that ALU_UPP |
-- doesn't set the N or Z flags. Note that the MSB can be used to |
-- distinguish between the two ALU modes. |
if( ALU_Ctrl.Oper(4) = '0' )then |
Flags_D(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= Sum(7); |
end if; |
when ALU_ADC => -- R0 = R0 + Rn + C : Flags N,C,Z |
Sum := ("0" & Regfile(0)) + |
("0" & Regfile(Index)) + |
Flags(FL_CARRY); |
Flags(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_CARRY) <= Sum(8); |
Flags(FL_NEG) <= Sum(7); |
Regfile(0) <= Sum(7 downto 0); |
|
when ALU_UPP2 => -- Rn = Rn + C |
Addend_A <= x"00"; |
Addend_B <= Regfile(Index); |
Carry <= Flags(FL_CARRY); |
Flags_D(FL_CARRY) <= Sum(8); |
Regfile_D(Index) <= Sum(7 downto 0); |
when ALU_TX0 => -- R0 = Rn : Flags N,Z |
Temp := "0" & Regfile(Index); |
Flags(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_NEG) <= Temp(7); |
Regfile(0) <= Temp(7 downto 0); |
|
when ALU_ADC => -- R0 = R0 + Rn + C : Flags N,C,Z |
Addend_A <= Regfile(0); |
Addend_B <= Regfile(Index); |
Carry <= Flags(FL_CARRY); |
Flags_D(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_CARRY) <= Sum(8); |
Flags_D(FL_NEG) <= Sum(7); |
Regfile_D(0) <= Sum(7 downto 0); |
when ALU_OR => -- R0 = R0 | Rn : Flags N,Z |
Temp(7 downto 0) := Regfile(0) or Regfile(Index); |
Flags(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_NEG) <= Temp(7); |
Regfile(0) <= Temp(7 downto 0); |
|
when ALU_TX0 => -- R0 = Rn : Flags N,Z |
Temp := "0" & Regfile(Index); |
Flags_D(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= Temp(7); |
Regfile_D(0) <= Temp(7 downto 0); |
when ALU_AND => -- R0 = R0 & Rn : Flags N,Z |
Temp(7 downto 0) := Regfile(0) and Regfile(Index); |
Flags(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_NEG) <= Temp(7); |
Regfile(0) <= Temp(7 downto 0); |
|
when ALU_OR => -- R0 = R0 | Rn : Flags N,Z |
Temp(7 downto 0) := Regfile(0) or Regfile(Index); |
Flags_D(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= Temp(7); |
Regfile_D(0) <= Temp(7 downto 0); |
when ALU_XOR => -- R0 = R0 ^ Rn : Flags N,Z |
Temp(7 downto 0) := Regfile(0) xor Regfile(Index); |
Flags(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_NEG) <= Temp(7); |
Regfile(0) <= Temp(7 downto 0); |
|
when ALU_AND => -- R0 = R0 & Rn : Flags N,Z |
Temp(7 downto 0) := Regfile(0) and Regfile(Index); |
Flags_D(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= Temp(7); |
Regfile_D(0) <= Temp(7 downto 0); |
when ALU_ROL => -- Rn = Rn<<1,C : Flags N,C,Z |
Temp := Regfile(Index) & Flags(FL_CARRY); |
Flags(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_CARRY) <= Temp(8); |
Flags(FL_NEG) <= Temp(7); |
Regfile(Index) <= Temp(7 downto 0); |
|
when ALU_XOR => -- R0 = R0 ^ Rn : Flags N,Z |
Temp(7 downto 0) := Regfile(0) xor Regfile(Index); |
Flags_D(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= Temp(7); |
Regfile_D(0) <= Temp(7 downto 0); |
|
when ALU_ROL => -- Rn = Rn<<1,C : Flags N,C,Z |
Temp := Regfile(Index) & Flags(FL_CARRY); |
Flags_D(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_CARRY) <= Temp(8); |
Flags_D(FL_NEG) <= Temp(7); |
Regfile_D(Index) <= Temp(7 downto 0); |
|
when ALU_ROR => -- Rn = C,Rn>>1 : Flags N,C,Z |
Temp := Regfile(Index)(0) & Flags(FL_CARRY) & |
when ALU_ROR => -- Rn = C,Rn>>1 : Flags N,C,Z |
Temp := Regfile(Index)(0) & Flags(FL_CARRY) & |
Regfile(Index)(7 downto 1); |
Flags_D(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_CARRY) <= Temp(8); |
Flags_D(FL_NEG) <= Temp(7); |
Regfile_D(Index) <= Temp(7 downto 0); |
Flags(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_CARRY) <= Temp(8); |
Flags(FL_NEG) <= Temp(7); |
Regfile(Index) <= Temp(7 downto 0); |
|
when ALU_DEC => -- Rn = Rn - 1 : Flags N,C,Z |
Addend_A <= Regfile(Index); |
Addend_B <= x"FF"; |
Flags_D(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_CARRY) <= Sum(8); |
Flags_D(FL_NEG) <= Sum(7); |
Regfile_D(Index) <= Sum(7 downto 0); |
when ALU_DEC => -- Rn = Rn - 1 : Flags N,C,Z |
Sum := ("0" & Regfile(Index)) + |
("0" & x"FF"); |
Flags(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_CARRY) <= Sum(8); |
Flags(FL_NEG) <= Sum(7); |
Regfile(Index) <= Sum(7 downto 0); |
|
when ALU_SBC => -- Rn = R0 - Rn - C : Flags N,C,Z |
Sum := ("0" & Regfile(0)) + |
("0" & (not Regfile(Index))) + |
Flags(FL_CARRY); |
Flags(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_CARRY) <= Sum(8); |
Flags(FL_NEG) <= Sum(7); |
Regfile(0) <= Sum(7 downto 0); |
|
when ALU_SBC => -- Rn = R0 - Rn - C : Flags N,C,Z |
Addend_A <= Regfile(0); |
Addend_B <= not Regfile(Index); |
Carry <= Flags(FL_CARRY); |
Flags_D(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_CARRY) <= Sum(8); |
Flags_D(FL_NEG) <= Sum(7); |
Regfile_D(0) <= Sum(7 downto 0); |
when ALU_ADD => -- R0 = R0 + Rn : Flags N,C,Z |
Sum := ("0" & Regfile(0)) + |
("0" & Regfile(Index)); |
Flags(FL_CARRY) <= Sum(8); |
Regfile(0) <= Sum(7 downto 0); |
Flags(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_NEG) <= Sum(7); |
|
when ALU_STP => -- Sets bit(n) in the Flags register |
Flags(Index) <= '1'; |
|
when ALU_BTT => -- Z = !R0(N), N = R0(7) |
Flags(FL_ZERO) <= not Regfile(0)(Index); |
Flags(FL_NEG) <= Regfile(0)(7); |
|
when ALU_ADD => -- R0 = R0 + Rn : Flags N,C,Z |
Addend_A <= Regfile(0); |
Addend_B <= Regfile(Index); |
Flags_D(FL_CARRY) <= Sum(8); |
Regfile_D(0) <= Sum(7 downto 0); |
Flags_D(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= Sum(7); |
when ALU_CLP => -- Clears bit(n) in the Flags register |
Flags(Index) <= '0'; |
|
when ALU_STP => -- Sets bit(n) in the Flags register |
Flags_D(Index) <= '1'; |
when ALU_T0X => -- Rn = R0 : Flags N,Z |
Temp := "0" & Regfile(0); |
Flags(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_NEG) <= Temp(7); |
Regfile(Index) <= Temp(7 downto 0); |
|
when ALU_CMP => -- Sets Flags on R0 - Rn : Flags N,C,Z |
Sum := ("0" & Regfile(0)) + |
("0" & (not Regfile(Index))) + |
'1'; |
Flags(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_CARRY) <= Sum(8); |
Flags(FL_NEG) <= Sum(7); |
|
when ALU_BTT => -- Z = !R0(N), N = R0(7) |
Flags_D(FL_ZERO) <= not Regfile(0)(Index); |
Flags_D(FL_NEG) <= Regfile(0)(7); |
-- Temp := "0" & Regfile(Index); |
-- Flags_D(FL_ZERO) <= '0'; |
-- if( Temp(7 downto 0) = 0 )then |
-- Flags_D(FL_ZERO) <= '1'; |
-- end if; |
-- Flags_D(FL_NEG) <= Temp(7); |
when ALU_MUL => -- Stage 1 of 2 {R1:R0} = R0 * Rn : Flags Z |
Regfile(0) <= Mult(7 downto 0); |
Regfile(1) <= Mult(15 downto 8); |
Flags(FL_ZERO) <= '0'; |
if( Mult = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
|
when ALU_LDI | ALU_POP => -- Rn <= Data : Flags N,Z |
-- The POP instruction doesn't alter the flags, so we need to check |
if( ALU_Ctrl.Oper = ALU_LDI )then |
Flags(FL_ZERO) <= '0'; |
if( ALU_Ctrl.Data = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_NEG) <= ALU_Ctrl.Data(7); |
end if; |
Regfile(Index) <= ALU_Ctrl.Data; |
|
when ALU_CLP => -- Clears bit(n) in the Flags register |
Flags_D(Index) <= '0'; |
when ALU_LDX => -- R0 <= Data : Flags N,Z |
Flags(FL_ZERO) <= '0'; |
if( ALU_Ctrl.Data = 0 )then |
Flags(FL_ZERO) <= '1'; |
end if; |
Flags(FL_NEG) <= ALU_Ctrl.Data(7); |
Regfile(0) <= ALU_Ctrl.Data; |
|
when ALU_T0X => -- Rn = R0 : Flags N,Z |
Temp := "0" & Regfile(0); |
Flags_D(FL_ZERO) <= '0'; |
if( Temp(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= Temp(7); |
Regfile_D(Index) <= Temp(7 downto 0); |
|
when ALU_CMP => -- Sets Flags on R0 - Rn : Flags N,C,Z |
Addend_A <= Regfile(0); |
Addend_B <= not Regfile(Index); |
Carry <= '1'; |
Flags_D(FL_ZERO) <= '0'; |
if( Sum(7 downto 0) = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_CARRY) <= Sum(8); |
Flags_D(FL_NEG) <= Sum(7); |
|
when ALU_MUL => -- Stage 1 of 2 {R1:R0} = R0 * Rn : Flags Z |
Regfile_D(0) <= Mult(7 downto 0); |
Regfile_D(1) <= Mult(15 downto 8); |
Flags_D(FL_ZERO) <= '0'; |
if( Mult = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
|
when ALU_LDI | ALU_POP => -- Rn <= Data : Flags N,Z |
-- The POP instruction doesn't alter the flags, so we need to check |
if( ALU_Ctrl.Oper = ALU_LDI )then |
Flags_D(FL_ZERO) <= '0'; |
if( ALU_Ctrl.Data = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= ALU_Ctrl.Data(7); |
end if; |
Regfile_D(Index) <= ALU_Ctrl.Data; |
|
when ALU_LDX => -- R0 <= Data : Flags N,Z |
Flags_D(FL_ZERO) <= '0'; |
if( ALU_Ctrl.Data = 0 )then |
Flags_D(FL_ZERO) <= '1'; |
end if; |
Flags_D(FL_NEG) <= ALU_Ctrl.Data(7); |
Regfile_D(0) <= ALU_Ctrl.Data; |
|
when ALU_RFLG => |
Flags_D <= ALU_Ctrl.Data; |
|
when others => null; |
end case; |
end process; |
|
-- 8-bit Adder with carry |
Sum <= ("0" & Addend_A) + ("0" & Addend_B) + Carry; |
|
-- We need to infer a hardware multipler, so we create a special clocked |
-- process with no reset or clock enable |
M_Reg: process( Clock ) |
begin |
if( rising_edge(Clock) )then |
Mult <= Regfile(0) * |
Regfile(conv_integer(ALU_Ctrl.Reg)); |
end if; |
end process; |
|
S_Regs: process( Reset, Clock ) |
begin |
if( Reset = Reset_Level )then |
for i in 0 to 7 loop |
Regfile(i) <= (others => '0'); |
end loop; |
Flags <= x"00"; |
elsif( rising_edge(Clock) )then |
if( Halt = '0' )then |
Regfile <= Regfile_D; |
Flags <= Flags_D; |
when ALU_RFLG => |
Flags <= ALU_Ctrl.Data; |
|
when others => null; |
end case; |
end if; |
end if; |
end process; |
492,35 → 469,26
Open8_PC : block is |
-- Preinitialization is for simulation only - check actual reset conditions |
signal PC_Q : ADDRESS_TYPE := (others => '0'); |
signal Rewind_1_2n : std_logic := '0'; |
begin |
|
PC <= PC_Q; |
|
-- This sets the carry input on the "rewind" adder. If the rewind command is |
-- PC_REV2, then we clear the carry. Otherwise, we leave it high. |
Rewind_PC_Calc: process( PC_Ctrl ) |
begin |
Rewind_1_2n <= '1'; |
if( PC_Ctrl.Oper = PC_REV2 )then |
Rewind_1_2n <= '0'; |
end if; |
end process; |
|
Program_Counter: process( Reset, Clock, Halt, PC_Ctrl, PC_Q, Rewind_1_2n ) |
Program_Counter: process( Reset, Clock ) |
variable PC_Offset_SX : ADDRESS_TYPE := x"0000"; |
begin |
PC_Offset_SX(15 downto 8):= (others => PC_Ctrl.Offset(7)); |
PC_Offset_SX(7 downto 0) := PC_Ctrl.Offset; |
if( Reset = Reset_Level )then |
PC_Q <= Program_Start_Addr; |
elsif( rising_edge(Clock) )then |
PC_Offset_SX(15 downto 8):= (others => PC_Ctrl.Offset(7)); |
PC_Offset_SX(7 downto 0) := PC_Ctrl.Offset; |
if( Halt = '0' )then |
case PC_Ctrl.Oper is |
when PC_IDLE => |
null; |
when PC_REV1 | PC_REV2 => |
PC_Q <= PC_Q - 2 + Rewind_1_2n; |
when PC_REV1 => |
PC_Q <= PC_Q - 1; |
when PC_REV2 => |
PC_Q <= PC_Q - 2; |
when PC_INCR => |
PC_Q <= PC_Q + PC_Offset_SX - 2; |
when PC_LOAD => |
562,6 → 530,73
end block; |
|
------------------------------------------------------------------------------- |
-- Address Source Mux |
------------------------------------------------------------------------------- |
|
Open8_AS : block is |
begin |
|
Address_Select: process( AS_Ctrl, PC, SP, IMM, ISR ) |
begin |
Address <= (others => '0'); |
case AS_Ctrl.Src is |
when ADDR_PC => |
Address <= PC; |
when ADDR_SP => |
Address <= SP; |
when ADDR_IMM => |
Address <= IMM; |
when ADDR_ISR => |
Address <= ISR; |
end case; |
end process; |
|
end block; |
|
------------------------------------------------------------------------------- |
-- (Write) Data Path |
------------------------------------------------------------------------------- |
|
Open8_DP : block is |
begin |
|
Data_Path: process( Reset, Clock ) |
begin |
if( Reset = Reset_Level )then |
Wr_Data <= (others => '0'); |
Wr_Enable <= '0'; |
Rd_Enable <= '1'; |
elsif( rising_edge(Clock) )then |
if( Halt = '0' )then |
Wr_Enable <= '0'; |
Rd_Enable <= '1'; |
case DP_Ctrl.Src is |
when DATA_IDLE => |
null; |
when DATA_REG => |
Wr_Enable <= '1'; |
Rd_Enable <= '0'; |
Wr_Data <= ALU_Regs(conv_integer(DP_Ctrl.Reg)); |
when DATA_FLAG => |
Wr_Enable <= '1'; |
Rd_Enable <= '0'; |
Wr_Data <= ALU_Flags; |
when DATA_PC => |
Wr_Enable <= '1'; |
Rd_Enable <= '0'; |
Wr_Data <= PC(15 downto 8); |
if( DP_Ctrl.Reg = ACCUM )then |
Wr_Data <= PC(7 downto 0); |
end if; |
when others => null; |
end case; |
end if; |
end if; |
end process; |
|
end block; |
|
------------------------------------------------------------------------------- |
-- Interrupt Controller |
------------------------------------------------------------------------------- |
|
1333,6 → 1368,7
Cache_Ctrl <= CACHE_IDLE; |
SP_Ctrl.Oper <= SP_IDLE; |
DP_Ctrl.Src <= DATA_IDLE; -- JSH 7/20 |
INT_Ctrl.Soft_Ints <= (others => '0'); -- JSH 7/22 |
-- Rewind the PC by 3 to compensate for the pipeline registers |
PC_Ctrl.Oper <= PC_INCR; |
PC_Ctrl.Offset <= x"FF"; |
1417,97 → 1453,4
|
end block; |
|
------------------------------------------------------------------------------- |
-- Address Source Mux |
------------------------------------------------------------------------------- |
|
Open8_AS : block is |
begin |
|
Address_Select: process( AS_Ctrl, PC, SP, IMM, ISR ) |
variable PC_Mux, SP_Mux : ADDRESS_TYPE; |
variable IMM_Mux, ISR_Mux: ADDRESS_TYPE; |
begin |
PC_Mux := (others => '0'); |
SP_Mux := (others => '0'); |
IMM_Mux := (others => '0'); |
ISR_Mux := (others => '0'); |
|
case AS_Ctrl.Src is |
when ADDR_PC => |
PC_Mux := PC; |
when ADDR_SP => |
SP_Mux := SP; |
when ADDR_IMM => |
IMM_Mux := IMM; |
when ADDR_ISR => |
ISR_Mux := ISR; |
end case; |
|
for i in 0 to 15 loop |
Address(i) <= PC_Mux(i) or SP_Mux(i) or IMM_Mux(i) or |
ISR_Mux(i); |
end loop; |
end process; |
|
end block; |
|
------------------------------------------------------------------------------- |
-- (Write) Data Path |
------------------------------------------------------------------------------- |
|
Open8_DP : block is |
signal Wr_Data_D : DATA_TYPE := (others => '0'); |
signal Wr_Enable_D : std_logic := '0'; |
begin |
|
Data_Select: process( DP_Ctrl, ALU_Regs, ALU_Flags, PC ) |
variable Reg_Mux, PC_Mux : DATA_TYPE; |
variable Flag_Mux : DATA_TYPE; |
begin |
Reg_Mux := (others => '0'); |
Flag_Mux := (others => '0'); |
PC_Mux := (others => '0'); |
Wr_Enable_D <= '0'; |
|
case DP_Ctrl.Src is |
when DATA_IDLE => |
null; |
when DATA_REG => |
Reg_Mux := ALU_Regs(conv_integer(DP_Ctrl.Reg)); |
Wr_Enable_D <= '1'; |
when DATA_FLAG => |
Flag_Mux := ALU_Flags; |
Wr_Enable_D <= '1'; |
when DATA_PC => |
Wr_Enable_D <= '1'; |
if( DP_Ctrl.Reg = ACCUM )then |
PC_Mux := PC(7 downto 0); |
else |
PC_Mux := PC(15 downto 8); |
end if; |
end case; |
|
for i in 0 to 7 loop |
Wr_Data_D(i) <= Reg_Mux(i) or Flag_Mux(i) or PC_Mux(i); |
end loop; |
end process; |
|
S_Regs: process( Reset, Clock ) |
begin |
if( Reset = Reset_Level )then |
Wr_Data <= (others => '0'); |
Wr_Enable <= '0'; |
Rd_Enable <= '1'; |
elsif( rising_edge(Clock) )then |
if( Halt = '0' )then |
Wr_Data <= Wr_Data_D; |
Wr_Enable <= Wr_Enable_D; |
Rd_Enable <= not Wr_Enable_D; |
end if; |
end if; |
end process; |
|
end block; |
|
end rtl; |