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 186 to Rev 187
    Reverse comparison

Rev 186 → Rev 187

/Open8_pkg.vhd
76,6 → 76,7
port(
Clock : in std_logic;
Reset : in std_logic;
CPU_Halt : in std_logic;
Interrupts : in INTERRUPT_BUNDLE;
Address : out ADDRESS_TYPE;
Rd_Data : in DATA_TYPE;
143,7 → 144,7
 
type CPU_STATES is (
-- Instruction fetch & Decode
PIPE_FILL_0, PIPE_FILL_1, PIPE_FILL_2, INSTR_DECODE,
IPF_C0, IPF_C1, IPF_C2, IDC_C0,
-- Branching
BRN_C1, DBNZ_C1, JMP_C1, JMP_C2,
-- Loads
156,11 → 157,10
-- Stack
PSH_C1, POP_C1, POP_C2, POP_C3, POP_C4,
-- Subroutines & Interrupts
WAIT_FOR_INT,
WAI_Cx, WAH_Cx, BRK_C1,
ISR_C1, ISR_C2, ISR_C3, JSR_C1, JSR_C2,
RTS_C1, RTS_C2, RTS_C3, RTS_C4, RTS_C5, RTI_C6,
-- Debugging
BRK_C1 );
RTS_C1, RTS_C2, RTS_C3, RTS_C4, RTS_C5, RTI_C6
);
 
type CACHE_MODES is (CACHE_IDLE, CACHE_INSTR, CACHE_OPER1, CACHE_OPER2,
CACHE_PREFETCH );
/o8_cpu.vhd
152,7 → 152,7
-- Seth Henry 09/20/11 Added BRK_Implements_WAI option, allowing the
-- processor to wait for an interrupt instead of the
-- normal BRK behavior.
-- Seth Henry 12/20/11 Modified core to allow WAIT_FOR_INT state to idle
-- Seth Henry 12/20/11 Modified core to allow WAI_Cx state to idle
-- the bus entirely (Rd_Enable is low)
-- Seth Henry 02/03/12 Replaced complex interrupt controller with simpler,
-- faster logic that simply does priority encoding.
176,6 → 176,13
-- for GMSK. This allowed the .data field to be
-- removed and Operand1 used in its place, which
-- simplified the logic a great deal.
-- Seth Henry 03/16/20 Added CPU_Halt input back, only now as an input to
-- the instruction decode state, where it acts as a
-- modified form of the BRK instruction that holds
-- state until CPU_Halt is deasserted. This has a
-- much smaller impact on Fmax/complexity than the
-- original clock enable, but imposes a mild impact
-- due to the need to reset the instruction pipeline
 
library ieee;
use ieee.std_logic_1164.all;
201,7 → 208,8
port(
Clock : in std_logic;
Reset : in std_logic;
Interrupts : in INTERRUPT_BUNDLE;
CPU_Halt : in std_logic := '0';
Interrupts : in INTERRUPT_BUNDLE := x"00";
--
Address : out ADDRESS_TYPE;
Rd_Data : in DATA_TYPE;
221,9 → 229,11
constant INT_VECTOR_6 : ADDRESS_TYPE := ISR_Start_Addr+12;
constant INT_VECTOR_7 : ADDRESS_TYPE := ISR_Start_Addr+14;
 
signal CPU_Next_State : CPU_STATES := PIPE_FILL_0;
signal CPU_State : CPU_STATES := PIPE_FILL_0;
signal CPU_Next_State : CPU_STATES := IPF_C0;
signal CPU_State : CPU_STATES := IPF_C0;
 
signal CPU_Halt_Req : std_logic;
 
signal Cache_Ctrl : CACHE_MODES := CACHE_IDLE;
 
signal Opcode : OPCODE_TYPE := (others => '0');
309,7 → 319,7
-- State Logic / Instruction Decoding & Execution
-------------------------------------------------------------------------------
 
State_Logic: process(CPU_State, Flags, Int_Mask, Opcode,
State_Logic: process(CPU_State, Flags, Int_Mask, CPU_Halt_Req, Opcode,
SubOp , SubOp_p1, Operand1, Operand2, Int_Req )
variable Reg : integer range 0 to 7 := 0;
begin
338,21 → 348,21
-------------------------------------------------------------------------------
-- Initial Instruction fetch & decode
-------------------------------------------------------------------------------
when PIPE_FILL_0 =>
CPU_Next_State <= PIPE_FILL_1;
when IPF_C0 =>
CPU_Next_State <= IPF_C1;
PC_Ctrl.Offset <= PC_NEXT;
 
when PIPE_FILL_1 =>
CPU_Next_State <= PIPE_FILL_2;
when IPF_C1 =>
CPU_Next_State <= IPF_C2;
PC_Ctrl.Offset <= PC_NEXT;
 
when PIPE_FILL_2 =>
CPU_Next_State <= INSTR_DECODE;
when IPF_C2 =>
CPU_Next_State <= IDC_C0;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Offset <= PC_NEXT;
 
when INSTR_DECODE =>
CPU_Next_State <= INSTR_DECODE;
when IDC_C0 =>
CPU_Next_State <= IDC_C0;
Cache_Ctrl <= CACHE_INSTR;
 
case Opcode is
384,9 → 394,12
 
when OP_INT =>
PC_Ctrl.Offset <= PC_NEXT;
-- Make sure the requested interrupt is actually enabled first
-- Make sure the requested interrupt is actually enabled first.
-- Also, unlike CPU_Halt, the INT instruction is actually being
-- executed, so go ahead and increment the program counter before
-- pausing so the CPU restarts on the next instruction.
if( Int_Mask(Reg) = '1' )then
CPU_Next_State <= WAIT_FOR_INT;
CPU_Next_State <= WAI_Cx;
INT_Ctrl.Soft_Ints(Reg) <= '1';
end if;
 
395,12 → 408,22
when SOP_RSP =>
PC_Ctrl.Offset <= PC_NEXT;
if( not Allow_Stack_Address_Move )then
-- The default behavior for this instruction is to simply
-- repoint the SP to the HDL default
SP_Ctrl.Oper <= SP_CLR;
end if;
if( Allow_Stack_Address_Move and Flags(Stack_Xfer_Flag) = '1' )then
if( Allow_Stack_Address_Move and
Flags(Stack_Xfer_Flag) = '1' )then
-- If RSP is set to allow SP moves, and the specified flag
-- is true, then signal the stack pointer logic to load
-- from R1:R0
SP_Ctrl.Oper <= SP_SET;
end if;
if( Allow_Stack_Address_Move and Flags(Stack_Xfer_Flag) = '0')then
if( Allow_Stack_Address_Move and
Flags(Stack_Xfer_Flag) = '0')then
-- If RSP is set to allow SP moves, and the specified flag
-- is false, then signal the ALU to copy the stack pointer
-- to R1:R0
ALU_Ctrl.Oper <= ALU_RSP;
end if;
 
409,13 → 432,17
SP_Ctrl.Oper <= SP_POP;
 
when SOP_BRK =>
CPU_Next_State <= BRK_C1;
PC_Ctrl.Offset <= PC_REV2;
-- If Break implements Wait for Interrupt, replace the normal
-- flow with a modified version of the INT instruction
if( BRK_Implements_WAI )then
CPU_Next_State <= WAIT_FOR_INT;
-- If BRK_Implements_WAI, then jump to the WAI_Cx and
-- increment the PC similar to an ISR flow.
CPU_Next_State <= WAI_Cx;
PC_Ctrl.Offset <= PC_NEXT;
else
-- If Break is implemented normally, back the PC up by
-- 2 and return through IPF_C0 in order to execute a 5
-- clock cycle delay
CPU_Next_State <= BRK_C1;
PC_Ctrl.Offset <= PC_REV2;
end if;
 
when SOP_JMP =>
470,7 → 497,6
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Offset <= PC_NEXT;
 
 
when OP_LDO =>
CPU_Next_State <= LDO_C1;
Cache_Ctrl <= CACHE_OPER1;
508,15 → 534,34
 
if( Int_Req = '1' )then
CPU_Next_State <= ISR_C1;
end if;
 
if( CPU_Halt_Req = '1' )then
CPU_Next_State <= WAH_Cx;
end if;
 
-- If either of these override conditions are true, the decoder needs
-- to undo everything it just setup, since even "single-cycle"
-- instructions will be executed again upon return.
if( Int_Req = '1' or CPU_Halt_Req = '1' )then
-- In either case, we want to skip loading the cache, as the cache
-- will be invalid by the time we get back.
Cache_Ctrl <= CACHE_IDLE;
-- Rewind the PC by 3 to compensate for the pipeline registers
-- Rewind the PC by 3 to put the PC back to the current instruction,
-- compensating for the pipeline registers.
PC_Ctrl.Offset <= PC_REV3;
-- Reset all of the sub-block controls to IDLE, to avoid unintended
-- operation due to the current instruction
-- operation due to the current instruction.
ALU_Ctrl.Oper <= ALU_IDLE;
SP_Ctrl.Oper <= SP_IDLE;
-- Interrupt logic outside of the state machine needs this to be set
-- to DATA_RD_MEM, while CPU_Halt considers this a "don't care".
DP_Ctrl.Src <= DATA_RD_MEM;
INT_Ctrl.Soft_Ints <= (others => '0');
-- If an INT/SMSK instruction was going to be executed, it will get
-- executed again when normal processing resumes, so axe their
-- requests for now.
INT_Ctrl.Mask_Set <= '0';
INT_Ctrl.Soft_Ints(Reg) <= '0';
end if;
 
-------------------------------------------------------------------------------
524,21 → 569,21
-------------------------------------------------------------------------------
 
when BRN_C1 =>
CPU_Next_State <= INSTR_DECODE;
CPU_Next_State <= IDC_C0;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Offset <= PC_NEXT;
if( Flags(Reg) = Opcode(0) )then
CPU_Next_State <= PIPE_FILL_0;
CPU_Next_State <= IPF_C0;
Cache_Ctrl <= CACHE_IDLE;
PC_Ctrl.Offset <= Operand1;
end if;
 
when DBNZ_C1 =>
CPU_Next_State <= INSTR_DECODE;
CPU_Next_State <= IDC_C0;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Offset <= PC_NEXT;
if( Flags(PSR_Z) = '0' )then
CPU_Next_State <= PIPE_FILL_0;
CPU_Next_State <= IPF_C0;
Cache_Ctrl <= CACHE_IDLE;
PC_Ctrl.Offset <= Operand1;
end if;
548,7 → 593,7
Cache_Ctrl <= CACHE_OPER2;
 
when JMP_C2 =>
CPU_Next_State <= PIPE_FILL_0;
CPU_Next_State <= IPF_C0;
PC_Ctrl.Oper <= PC_LOAD;
 
-------------------------------------------------------------------------------
572,7 → 617,7
PC_Ctrl.Offset <= PC_NEXT;
 
when LDI_C1 =>
CPU_Next_State <= INSTR_DECODE;
CPU_Next_State <= IDC_C0;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_LDI;
603,7 → 648,7
PC_Ctrl.Offset <= PC_NEXT;
 
when LDX_C4 =>
CPU_Next_State <= INSTR_DECODE;
CPU_Next_State <= IDC_C0;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_LDI;
623,12 → 668,12
PC_Ctrl.Offset <= PC_NEXT;
 
when STA_C3 =>
CPU_Next_State <= PIPE_FILL_2;
CPU_Next_State <= IPF_C2;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Offset <= PC_NEXT;
 
when STO_C1 =>
CPU_Next_State <= PIPE_FILL_0;
CPU_Next_State <= IPF_C0;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Offset <= PC_NEXT;
if( Enable_Auto_Increment and SubOp(0) = '1' )then
638,13 → 683,13
end if;
 
when STO_C2 =>
CPU_Next_State <= PIPE_FILL_1;
CPU_Next_State <= IPF_C1;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_UPP2;
ALU_Ctrl.Reg <= SubOp(2 downto 1) & '1';
 
when STX_C1 =>
CPU_Next_State <= PIPE_FILL_1;
CPU_Next_State <= IPF_C1;
PC_Ctrl.Offset <= PC_NEXT;
if( Enable_Auto_Increment and SubOp(0) = '1' )then
CPU_Next_State <= STX_C2;
653,7 → 698,7
end if;
 
when STX_C2 =>
CPU_Next_State <= PIPE_FILL_2;
CPU_Next_State <= IPF_C2;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_UPP2;
ALU_Ctrl.Reg <= SubOp(2 downto 1) & '1';
667,12 → 712,12
-- need to tell the ALU to store the results to R1:R0 here. Note that
-- there is no ALU_Ctrl.Reg, as this is implied in the ALU instruction
when MUL_C1 =>
CPU_Next_State <= PIPE_FILL_2;
CPU_Next_State <= IPF_C2;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_MUL;
 
when UPP_C1 =>
CPU_Next_State <= PIPE_FILL_2;
CPU_Next_State <= IPF_C2;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_UPP2;
ALU_Ctrl.Reg <= SubOp_p1;
681,7 → 726,7
-- Basic Stack Manipulation (PSH, POP, RSP)
-------------------------------------------------------------------------------
when PSH_C1 =>
CPU_Next_State <= PIPE_FILL_1;
CPU_Next_State <= IPF_C1;
SP_Ctrl.Oper <= SP_PUSH;
 
when POP_C1 =>
697,7 → 742,7
PC_Ctrl.Offset <= PC_NEXT;
 
when POP_C4 =>
CPU_Next_State <= INSTR_DECODE;
CPU_Next_State <= IDC_C0;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_POP;
706,11 → 751,12
-------------------------------------------------------------------------------
-- Subroutines & Interrupts (RTS, JSR)
-------------------------------------------------------------------------------
when WAIT_FOR_INT => -- For soft interrupts only, halt the Program_Ctr
when WAI_Cx => -- For soft interrupts only, halt the Program_Ctr
DP_Ctrl.Src <= DATA_BUS_IDLE;
if( Int_Req = '1' )then
CPU_Next_State <= ISR_C1;
-- Rewind the PC by 3 to compensate for the pipeline registers
-- Rewind the PC by 3 to put the PC back to would have been the next
-- instruction, compensating for the pipeline registers.
PC_Ctrl.Offset <= PC_REV3;
-- Reset all of the sub-block controls to IDLE, to avoid unintended
-- operation due to the current instruction
717,6 → 763,16
DP_Ctrl.Src <= DATA_RD_MEM;
end if;
 
when WAH_Cx => -- Holds until CPU_Halt_Req is deasserted.
DP_Ctrl.Src <= DATA_BUS_IDLE;
if( CPU_Halt_Req = '0' )then
CPU_Next_State <= IPF_C0;
DP_Ctrl.Src <= DATA_RD_MEM;
end if;
 
when BRK_C1 => -- Debugging (BRK) Performs a 5-clock NOP.
CPU_Next_State <= IPF_C0;
 
when ISR_C1 =>
CPU_Next_State <= ISR_C2;
INT_Ctrl.Incr_ISR <= '1';
743,7 → 799,7
DP_Ctrl.Reg <= PC_LSB;
 
when JSR_C2 =>
CPU_Next_State <= PIPE_FILL_0;
CPU_Next_State <= IPF_C0;
PC_Ctrl.Oper <= PC_LOAD;
SP_Ctrl.Oper <= SP_PUSH;
 
767,7 → 823,7
Cache_Ctrl <= CACHE_OPER2;
 
when RTS_C5 =>
CPU_Next_State <= PIPE_FILL_0;
CPU_Next_State <= IPF_C0;
PC_Ctrl.Oper <= PC_LOAD;
-- if this is an RTI, then we need to clear the I bit
if( SubOp = SOP_RTI )then
778,16 → 834,10
end if;
 
when RTI_C6 =>
CPU_Next_State <= PIPE_FILL_1;
CPU_Next_State <= IPF_C1;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_RFLG;
 
-------------------------------------------------------------------------------
-- Debugging (BRK) Performs a 5-clock NOP
-------------------------------------------------------------------------------
when BRK_C1 =>
CPU_Next_State <= PIPE_FILL_0;
 
when others =>
null;
end case;
806,7 → 856,7
variable Temp : std_logic_vector(8 downto 0) := "000000000";
begin
if( Reset = Reset_Level )then
CPU_State <= PIPE_FILL_0;
CPU_State <= IPF_C0;
Opcode <= OP_INC;
SubOp <= ACCUM;
SubOp_p1 <= ACCUM;
815,6 → 865,8
Instr_Prefetch <= '0';
Prefetch <= x"00";
 
CPU_Halt_Req <= '0';
 
Wr_Data <= (others => '0');
Wr_Enable <= '0';
Rd_Enable <= '1';
842,6 → 894,9
Flags <= x"00";
 
elsif( rising_edge(Clock) )then
 
CPU_Halt_Req <= CPU_Halt;
 
Wr_Enable <= '0';
Wr_Data <= x"00";
Rd_Enable <= '0';

powered by: WebSVN 2.1.0

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