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/trunk/VHDL
    from Rev 251 to Rev 252
    Reverse comparison

Rev 251 → Rev 252

/o8_cpu.vhd
229,6 → 229,11
-- Seth Henry 05/24/20 Removed the Default_Int_Flag, as it is covered by
-- Supervisor_Mode. If Supervisor_Mode isn't set,
-- code can simply use STP to set the bit
-- Seth Henry 06/09/20 Added ability to use unsigned index offsets for
-- LDO/SDO. Also pipelined the address calculation
-- for indexed instructions, reducing the final
-- address generator to a multiplexor fed only by
-- registers.
 
library ieee;
use ieee.std_logic_1164.all;
252,6 → 257,7
Sequential_Interrupts : boolean := false; -- Interruptable ISRs
RTI_Ignores_GP_Flags : boolean := false; -- RTI sets all flags
Supervisor_Mode : boolean := false; -- I bit is restricted
Unsigned_Index_Offsets : boolean := false; -- Offsets are signed
Default_Interrupt_Mask : DATA_TYPE := x"FF"; -- Enable all Ints
Clock_Frequency : real -- Clock Frequency
);
329,6 → 335,14
signal Wait_for_FSM : std_logic := '0';
signal Wait_for_ISR : std_logic := '0';
 
signal IDX_Offset : ADDRESS_TYPE := x"0000";
 
signal IDX_Reg_l : integer := 0;
signal IDX_Reg_h : integer := 0;
 
signal IDX_NoOffset_Calc : ADDRESS_TYPE := x"0000";
signal IDX_Offset_Calc : ADDRESS_TYPE := x"0000";
 
begin
 
-------------------------------------------------------------------------------
368,23 → 382,54
-- Address bus selection/generation logic
-------------------------------------------------------------------------------
 
Address_Logic: process(CPU_State, Regfile, SubOp, SubOp_p1, Operand1,
Operand2, Program_Ctr, Stack_Ptr, ISR_Addr )
-- The original model treated the offset to LDO/STO as a signed value
-- allowing access to locations -128 to +127 from [Rn+1:Rn]. This isn't
-- always helpful, so the generic allows the CPU to use unsigned math
-- for the offsets. This makes the range 0 to +255 instead.
Unsigned_Idx_Offsets : if( Unsigned_Index_Offsets )generate
IDX_Offset(15 downto 8) <= (others => '0');
IDX_Offset(7 downto 0) <= Operand1;
end generate;
 
Signed_Idx_Offsets: if( not Unsigned_Index_Offsets )generate
IDX_Offset(15 downto 8) <= (others => Operand1(7));
IDX_Offset(7 downto 0) <= Operand1;
end generate;
 
-- Enable_Auto_Increment uses the LSB to determine whether or not to
-- do the auto-increment, so we need to lock the LSB for each operand
-- if it is enabled. This forces [ODD:EVEN] pairing.
 
Auto_Incr_Set: if( Enable_Auto_Increment )generate
IDX_Reg_l <= conv_integer(SubOp(2 downto 1) & '0');
IDX_Reg_h <= conv_integer(SubOp(2 downto 1) & '1');
end generate;
 
Auto_Incr_Not_Set: if( not Enable_Auto_Increment )generate
IDX_Reg_l <= conv_integer(SubOp);
IDX_Reg_h <= conv_integer(SubOp_p1);
end generate;
 
-- Pipeline registers for the indexed and indexed with offset addresses.
Idx_Addr_Calc_proc: process( Clock, Reset )
variable Reg, Reg_1 : integer range 0 to 7 := 0;
variable Offset_SX : ADDRESS_TYPE;
begin
 
if( Enable_Auto_Increment )then
Reg := conv_integer(SubOp(2 downto 1) & '0');
Reg_1 := conv_integer(SubOp(2 downto 1) & '1');
else
Reg := conv_integer(SubOp);
Reg_1 := conv_integer(SubOp_p1);
if( Reset = Reset_Level )then
IDX_NoOffset_Calc <= x"0000";
IDX_Offset_Calc <= x"0000";
elsif( rising_edge(Clock))then
IDX_NoOffset_Calc <= (Regfile(IDX_Reg_h) & Regfile(IDX_Reg_l));
IDX_Offset_Calc <= (Regfile(IDX_Reg_h) & Regfile(IDX_Reg_l)) +
IDX_Offset;
end if;
end process;
 
Offset_SX(15 downto 0) := (others => Operand1(7));
Offset_SX(7 downto 0) := Operand1;
 
-- Address selection logic based on current CPU state. This is combinatorial,
-- as adding pipeline registration would add a clock cycle to every instr,
-- without really adding the Fmax to compensate.
Address_Logic: process(CPU_State, Operand1, Operand2, IDX_NoOffset_Calc,
IDX_Offset_Calc, ISR_Addr, Stack_Ptr, Program_Ctr )
begin
case( CPU_State )is
 
when LDA_C2 | STA_C2 =>
391,10 → 436,10
Open8_Bus.Address <= Operand2 & Operand1;
 
when LDX_C1 | STX_C1 =>
Open8_Bus.Address <= (Regfile(Reg_1) & Regfile(Reg));
Open8_Bus.Address <= IDX_NoOffset_Calc;
 
when LDO_C1 | STO_C1 =>
Open8_Bus.Address <= (Regfile(Reg_1) & Regfile(Reg)) + Offset_SX;
when LDO_C2 | STO_C2 =>
Open8_Bus.Address <= IDX_Offset_Calc;
 
when ISR_C1 | ISR_C2 =>
Open8_Bus.Address <= ISR_Addr;
406,7 → 451,6
Open8_Bus.Address <= Program_Ctr;
 
end case;
 
end process;
 
-------------------------------------------------------------------------------
612,9 → 656,7
when OP_STO =>
CPU_Next_State <= STO_C1;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Offset <= PC_REV2;
DP_Ctrl.Src <= DATA_WR_REG;
DP_Ctrl.Reg <= ACCUM;
PC_Ctrl.Offset <= PC_REV1;
 
when OP_STX =>
CPU_Next_State <= STX_C1;
734,6 → 776,9
ALU_Ctrl.Reg <= SubOp;
 
when LDO_C1 =>
CPU_Next_State <= LDO_C2;
 
when LDO_C2 =>
CPU_Next_State <= LDX_C2;
PC_Ctrl.Offset <= PC_NEXT;
if( Enable_Auto_Increment and SubOp(0) = '1' )then
783,17 → 828,22
PC_Ctrl.Offset <= PC_NEXT;
 
when STO_C1 =>
CPU_Next_State <= IPF_C0;
CPU_Next_State <= STO_C2;
Cache_Ctrl <= CACHE_PREFETCH;
DP_Ctrl.Src <= DATA_WR_REG;
DP_Ctrl.Reg <= ACCUM;
 
when STO_C2 =>
CPU_Next_State <= IPF_C1;
PC_Ctrl.Offset <= PC_NEXT;
if( Enable_Auto_Increment and SubOp(0) = '1' )then
CPU_Next_State <= STO_C2;
CPU_Next_State <= STO_C3;
ALU_Ctrl.Oper <= ALU_UPP;
ALU_Ctrl.Reg <= SubOp(2 downto 1) & '0';
end if;
 
when STO_C2 =>
CPU_Next_State <= IPF_C1;
when STO_C3 =>
CPU_Next_State <= IPF_C2;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_UPP2;
ALU_Ctrl.Reg <= SubOp(2 downto 1) & '1';

powered by: WebSVN 2.1.0

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