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

powered by: WebSVN 2.1.0

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