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 184 to Rev 185
    Reverse comparison

Rev 184 → Rev 185

/Open8_pkg.vhd
1,4 → 1,4
-- Copyright (c)2006,2011,2012,2013,2015 Jeremy Seth Henry
-- Copyright (c)2006,2011,2012,2013,2015,2020 Jeremy Seth Henry
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
29,10 → 29,14
-- Seth Henry 07/22/06 Design Start
-- Seth Henry 02/03/12 Updated generics to match current model
-- Seth Henry 10/29/15 Migrated type/constant definitions to this file
-- Seth Henry 03/09/20 Created new ALU/SP opcodes for handling new RSP
-- Seth Henry 03/09/20 Created new ALU/SP opcodes for handling new RSP
-- Seth Henry 03/12/20 Rationalized the naming of the CPU flags to match
-- the assembler names. Also removed superfluous
-- signals in the ALU and PC records.
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
package Open8_pkg is
 
45,7 → 49,7
 
-- These must never be changed, as the core requires them to be these static
-- values for proper operation. These are ONLY defined here to allow user
-- code to dynamically configure itself to match the Open8 core ONLY.
-- code to dynamically configure itself to match the Open8 core.
 
constant OPEN8_ADDR_WIDTH : integer := 16; -- DON'T EVEN CONTEMPLATE
constant OPEN8_DATA_WIDTH : integer := 8; -- CHANGING THESE!
56,19 → 60,19
subtype INTERRUPT_BUNDLE is DATA_TYPE;
 
-- Component declaration
-- (assumes a 1K RAM at 0x0000 and ROM at the end of the memory map)
-- (assumes a 1K RAM at 0x0000 and ROM at the top of the memory map)
component o8_cpu is
generic(
Program_Start_Addr : ADDRESS_TYPE := x"8000"; -- Initial PC location
ISR_Start_Addr : ADDRESS_TYPE := x"FFF0"; -- Bottom of ISR vec's
Stack_Start_Addr : ADDRESS_TYPE := x"03FF"; -- Top of Stack
Allow_Stack_Address_Move : boolean := false; -- Use Normal v8 RSP
Stack_Xfer_Flag : integer := 4; -- If enabled, GP1 alters RSP
Enable_Auto_Increment : boolean := false; -- Modify indexed instr
BRK_Implements_WAI : boolean := false; -- BRK -> Wait for Int
Enable_NMI : boolean := true; -- Force INTR0 enabled
Default_Interrupt_Mask : DATA_TYPE := x"FF"; -- Enable all Ints
Reset_Level : std_logic := '0' ); -- Active reset level
Program_Start_Addr : ADDRESS_TYPE := x"8000";
ISR_Start_Addr : ADDRESS_TYPE := x"FFF0";
Stack_Start_Addr : ADDRESS_TYPE := x"03FF";
Allow_Stack_Address_Move : boolean := false;
Stack_Xfer_Flag : integer := 4;
Enable_Auto_Increment : boolean := false;
BRK_Implements_WAI : boolean := false;
Enable_NMI : boolean := true;
Default_Interrupt_Mask : DATA_TYPE := x"FF";
Reset_Level : std_logic := '0' );
port(
Clock : in std_logic;
Reset : in std_logic;
143,7 → 147,8
-- Branching
BRN_C1, DBNZ_C1, JMP_C1, JMP_C2,
-- Loads
LDA_C1, LDA_C2, LDA_C3, LDA_C4, LDI_C1, LDO_C1, LDX_C1, LDX_C2, LDX_C3, LDX_C4,
LDA_C1, LDA_C2, LDA_C3, LDA_C4, LDI_C1,
LDO_C1, LDX_C1, LDX_C2, LDX_C3, LDX_C4,
-- Stores
STA_C1, STA_C2, STA_C3, STO_C1, STO_C2, STX_C1, STX_C2,
-- 2-cycle math
159,14 → 164,21
type CACHE_MODES is (CACHE_IDLE, CACHE_INSTR, CACHE_OPER1, CACHE_OPER2,
CACHE_PREFETCH );
 
type PC_MODES is ( PC_IDLE, PC_REV1, PC_REV2, PC_INCR, PC_LOAD );
type PC_MODES is ( PC_INCR, PC_LOAD );
 
type PC_CTRL_TYPE is record
Oper : PC_MODES;
Offset : DATA_TYPE;
Addr : ADDRESS_TYPE;
end record;
 
-- These are fixed constant offsets to the program counter logic, which is
-- always either incrementing or loading.
constant PC_NEXT : DATA_TYPE := x"03";
constant PC_IDLE : DATA_TYPE := x"02";
constant PC_REV1 : DATA_TYPE := x"01";
constant PC_REV2 : DATA_TYPE := x"00";
constant PC_REV3 : DATA_TYPE := x"FF";
 
type SP_MODES is ( SP_IDLE, SP_CLR, SP_SET, SP_POP, SP_PUSH );
 
type SP_CTRL_TYPE is record
190,8 → 202,9
Incr_ISR : std_logic;
end record;
 
-- Most of the ALU instructions are the same as their Opcode equivalents with
-- three exceptions (for IDLE, UPP2, and MUL2)
-- Most of the ALU instructions are the same as their Opcode equivalents,
-- with exceptions for IDLE, UPP2, RFLG, RSP, and GMSK, which perform
-- internal operations not otherwise exposed by the instruction set.
constant ALU_INC : OPCODE_TYPE := "00000"; -- x"00"
constant ALU_ADC : OPCODE_TYPE := "00001"; -- x"01"
constant ALU_TX0 : OPCODE_TYPE := "00010"; -- x"02"
216,31 → 229,13
constant ALU_IDLE : OPCODE_TYPE := "10000"; -- x"10"
constant ALU_UPP2 : OPCODE_TYPE := "10010"; -- x"12"
constant ALU_RFLG : OPCODE_TYPE := "10011"; -- x"13"
constant ALU_TSX : OPCODE_TYPE := "10111"; -- x"17"
constant ALU_RSP : OPCODE_TYPE := "10111"; -- x"17"
constant ALU_GMSK : OPCODE_TYPE := "11111"; -- x"1F"
 
constant FL_ZERO : integer := 0;
constant FL_CARRY : integer := 1;
constant FL_NEG : integer := 2;
constant FL_INT_EN : integer := 3;
constant FL_GP1 : integer := 4;
constant FL_GP2 : integer := 5;
constant FL_GP3 : integer := 6;
constant FL_GP4 : integer := 7;
 
type ALU_CTRL_TYPE is record
Oper : OPCODE_TYPE;
Reg : SUBOP_TYPE;
Data : DATA_TYPE;
end record;
 
constant ACCUM : SUBOP_TYPE := "000";
constant INT_FLAG : SUBOP_TYPE := "011";
 
type REGFILE_TYPE is array (0 to 7) of DATA_TYPE;
 
subtype FLAG_TYPE is DATA_TYPE;
 
end Open8_pkg;
 
package body Open8_pkg is
end package body;
-- These should match the assembler's definitions for the flags
constant PSR_Z : integer := 0;
constant PSR_C : integer := 1;
constant PSR_N : integer := 2;
constant PSR_I : integer := 3;
constant PSR_GP4 : integer := 4;
constant PSR_GP5 :
/o8_cpu.vhd
1,4 → 1,4
-- Copyright (c)2006, 2011, 2012, 2013, 2015, 2019 Jeremy Seth Henry
-- Copyright (c)2006, 2011, 2012, 2013, 2015, 2019, 2020 Jeremy Seth Henry
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
166,8 → 166,16
-- redundancies. Came across and fixed a problem with
-- the STO instruction when Enable_Auto_Increment is
-- NOT set.
-- Seth Henry 03/11/20 Renamed core to "o8_cpu" to fit theme settled on
-- over multiple projects.
-- Seth Henry 03/12/20 Rationalized the naming of the CPU flags to match
-- the assembler names. Also fixed an issue where
-- the I bit wasn't being cleared after interrupts.
-- Simplified the program counter logic to only use
-- the offset for increments, redefining the
-- original modes as fixed offset values.
-- Modified the ALU section with a new ALU operation
-- for GMSK. This allowed the .data field to be
-- removed and Operand1 used in its place, which
-- simplified the logic a great deal.
 
library ieee;
use ieee.std_logic_1164.all;
184,7 → 192,7
ISR_Start_Addr : ADDRESS_TYPE := x"FFF0"; -- Bottom of ISR vec's
Stack_Start_Addr : ADDRESS_TYPE := x"03FF"; -- Top of Stack
Allow_Stack_Address_Move : boolean := false; -- Use Normal v8 RSP
Stack_Xfer_Flag : integer := FL_GP1; -- If enabled, use GP1 to control RSP
Stack_Xfer_Flag : integer := PSR_GP4; -- If enabled, use GP4 to control RSP
Enable_Auto_Increment : boolean := false; -- Modify indexed instr
BRK_Implements_WAI : boolean := false; -- BRK -> Wait for Int
Enable_NMI : boolean := true; -- Force INTR0 enabled
213,8 → 221,6
constant INT_VECTOR_6 : ADDRESS_TYPE := ISR_Start_Addr+12;
constant INT_VECTOR_7 : ADDRESS_TYPE := ISR_Start_Addr+14;
 
signal Halt : std_logic;
 
signal CPU_Next_State : CPU_STATES := PIPE_FILL_0;
signal CPU_State : CPU_STATES := PIPE_FILL_0;
 
252,12 → 258,13
 
begin
 
 
-------------------------------------------------------------------------------
-- Address bus selection/generation logic
-------------------------------------------------------------------------------
 
Address_Logic: process(CPU_State, Regfile, SubOp, SubOp_p1, Operand1, Operand2,
Program_Ctr, Stack_Ptr, ISR_Addr )
Address_Logic: process(CPU_State, Regfile, SubOp, SubOp_p1, Operand1,
Operand2, Program_Ctr, Stack_Ptr, ISR_Addr )
variable Reg, Reg_1 : integer range 0 to 7 := 0;
variable Offset_SX : ADDRESS_TYPE;
begin
309,13 → 316,11
CPU_Next_State <= CPU_State;
Cache_Ctrl <= CACHE_IDLE;
--
PC_Ctrl.Oper <= PC_IDLE;
PC_Ctrl.Offset <= x"03";
PC_Ctrl.Addr <= x"0000";
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_IDLE;
--
ALU_Ctrl.Oper <= ALU_IDLE;
ALU_Ctrl.Reg <= ACCUM;
ALU_Ctrl.Data <= x"00";
--
SP_Ctrl.Oper <= SP_IDLE;
--
335,16 → 340,16
-------------------------------------------------------------------------------
when PIPE_FILL_0 =>
CPU_Next_State <= PIPE_FILL_1;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when PIPE_FILL_1 =>
CPU_Next_State <= PIPE_FILL_2;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when PIPE_FILL_2 =>
CPU_Next_State <= INSTR_DECODE;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when INSTR_DECODE =>
CPU_Next_State <= INSTR_DECODE;
354,7 → 359,7
when OP_PSH =>
CPU_Next_State <= PSH_C1;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Oper <= PC_REV1;
PC_Ctrl.Offset <= PC_REV1;
DP_Ctrl.Src <= DATA_WR_REG;
DP_Ctrl.Reg <= SubOp;
 
361,23 → 366,24
when OP_POP =>
CPU_Next_State <= POP_C1;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Oper <= PC_REV2;
PC_Ctrl.Offset <= PC_REV2;
SP_Ctrl.Oper <= SP_POP;
 
when OP_BR0 | OP_BR1 =>
CPU_Next_State <= BRN_C1;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
 
when OP_DBNZ =>
CPU_Next_State <= DBNZ_C1;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_DEC;
ALU_Ctrl.Reg <= SubOp;
 
when OP_INT =>
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
-- Make sure the requested interrupt is actually enabled first
if( Int_Mask(Reg) = '1' )then
CPU_Next_State <= WAIT_FOR_INT;
387,51 → 393,49
when OP_STK =>
case SubOp is
when SOP_RSP =>
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
if( not Allow_Stack_Address_Move )then
SP_Ctrl.Oper <= SP_CLR;
SP_Ctrl.Oper <= SP_CLR;
end if;
if( Allow_Stack_Address_Move and Flags(Stack_Xfer_Flag) = '1' )then
SP_Ctrl.Oper <= SP_SET;
SP_Ctrl.Oper <= SP_SET;
end if;
if( Allow_Stack_Address_Move and Flags(Stack_Xfer_Flag) = '0')then
ALU_Ctrl.Oper <= ALU_TSX;
ALU_Ctrl.Oper <= ALU_RSP;
end if;
 
when SOP_RTS | SOP_RTI =>
CPU_Next_State <= RTS_C1;
Cache_Ctrl <= CACHE_IDLE;
SP_Ctrl.Oper <= SP_POP;
CPU_Next_State <= RTS_C1;
Cache_Ctrl <= CACHE_IDLE;
SP_Ctrl.Oper <= SP_POP;
 
when SOP_BRK =>
CPU_Next_State <= BRK_C1;
PC_Ctrl.Oper <= PC_REV2;
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;
PC_Ctrl.Oper <= PC_INCR;
CPU_Next_State <= WAIT_FOR_INT;
PC_Ctrl.Offset <= PC_NEXT;
end if;
 
when SOP_JMP =>
CPU_Next_State <= JMP_C1;
Cache_Ctrl <= CACHE_OPER1;
CPU_Next_State <= JMP_C1;
Cache_Ctrl <= CACHE_OPER1;
 
when SOP_SMSK =>
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
INT_Ctrl.Mask_Set <= '1';
 
when SOP_GMSK =>
PC_Ctrl.Oper <= PC_INCR;
ALU_Ctrl.Oper<= ALU_LDI;
ALU_Ctrl.Reg <= ACCUM;
ALU_Ctrl.Data<= Int_Mask;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_GMSK;
 
when SOP_JSR =>
CPU_Next_State <= JSR_C1;
Cache_Ctrl <= CACHE_OPER1;
DP_Ctrl.Src <= DATA_WR_PC;
DP_Ctrl.Reg <= PC_MSB;
Cache_Ctrl <= CACHE_OPER1;
DP_Ctrl.Src <= DATA_WR_PC;
DP_Ctrl.Reg <= PC_MSB;
 
when others => null;
end case;
444,7 → 448,7
-- We can get away with only 1 extra clock by pre-fetching the
-- next instruction, though.
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Oper <= PC_REV1;
PC_Ctrl.Offset <= PC_REV1;
-- Note that both the multiply process AND ALU process need the
-- source register for Rn (R1:R0 = R0 * Rn). Assert ALU_Ctrl.reg
-- now, but hold off on the ALU command until the next state.
454,7 → 458,7
when OP_UPP =>
CPU_Next_State <= UPP_C1;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Oper <= PC_REV1;
PC_Ctrl.Offset <= PC_REV1;
ALU_Ctrl.Oper <= Opcode;
ALU_Ctrl.Reg <= SubOp;
 
465,17 → 469,18
when OP_LDI =>
CPU_Next_State <= LDI_C1;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
 
when OP_LDO =>
CPU_Next_State <= LDO_C1;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Oper <= PC_REV2;
PC_Ctrl.Offset <= PC_REV2;
 
when OP_LDX =>
CPU_Next_State <= LDX_C1;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Oper <= PC_REV2;
PC_Ctrl.Offset <= PC_REV2;
 
when OP_STA =>
CPU_Next_State <= STA_C1;
484,7 → 489,7
when OP_STO =>
CPU_Next_State <= STO_C1;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Oper <= PC_REV2;
PC_Ctrl.Offset <= PC_REV2;
DP_Ctrl.Src <= DATA_WR_REG;
DP_Ctrl.Reg <= ACCUM;
 
491,12 → 496,12
when OP_STX =>
CPU_Next_State <= STX_C1;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Oper <= PC_REV2;
PC_Ctrl.Offset <= PC_REV2;
DP_Ctrl.Src <= DATA_WR_REG;
DP_Ctrl.Reg <= ACCUM;
 
when others =>
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= Opcode;
ALU_Ctrl.Reg <= SubOp;
 
509,7 → 514,7
when BRN_C1 =>
CPU_Next_State <= INSTR_DECODE;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
if( Flags(Reg) = Opcode(0) )then
CPU_Next_State <= PIPE_FILL_0;
Cache_Ctrl <= CACHE_IDLE;
519,8 → 524,8
when DBNZ_C1 =>
CPU_Next_State <= INSTR_DECODE;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Oper <= PC_INCR;
if( Flags(FL_ZERO) = '0' )then
PC_Ctrl.Offset <= PC_NEXT;
if( Flags(PSR_Z) = '0' )then
CPU_Next_State <= PIPE_FILL_0;
Cache_Ctrl <= CACHE_IDLE;
PC_Ctrl.Offset <= Operand1;
533,7 → 538,6
when JMP_C2 =>
CPU_Next_State <= PIPE_FILL_0;
PC_Ctrl.Oper <= PC_LOAD;
PC_Ctrl.Addr <= Operand2 & Operand1;
 
-------------------------------------------------------------------------------
-- Data Storage - Load from memory (LDA, LDI, LDO, LDX)
548,24 → 552,23
 
when LDA_C3 =>
CPU_Next_State <= LDA_C4;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when LDA_C4 =>
CPU_Next_State <= LDI_C1;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when LDI_C1 =>
CPU_Next_State <= INSTR_DECODE;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_LDI;
ALU_Ctrl.Reg <= SubOp;
ALU_Ctrl.Data <= Operand1;
 
when LDO_C1 =>
CPU_Next_State <= LDX_C2;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
if( Enable_Auto_Increment and SubOp(0) = '1' )then
ALU_Ctrl.Oper <= ALU_UPP;
ALU_Ctrl.Reg <= SubOp(2 downto 1) & '0';
580,20 → 583,19
 
when LDX_C2 =>
CPU_Next_State <= LDX_C3;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when LDX_C3 =>
CPU_Next_State <= LDX_C4;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when LDX_C4 =>
CPU_Next_State <= INSTR_DECODE;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_LDI;
ALU_Ctrl.Reg <= ACCUM;
ALU_Ctrl.Data <= Operand1;
 
-------------------------------------------------------------------------------
-- Data Storage - Store to memory (STA, STO, STX)
606,17 → 608,17
 
when STA_C2 =>
CPU_Next_State <= STA_C3;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when STA_C3 =>
CPU_Next_State <= PIPE_FILL_2;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when STO_C1 =>
CPU_Next_State <= PIPE_FILL_0;
Cache_Ctrl <= CACHE_PREFETCH;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
if( Enable_Auto_Increment and SubOp(0) = '1' )then
CPU_Next_State <= STO_C2;
ALU_Ctrl.Oper <= ALU_UPP;
625,13 → 627,13
 
when STO_C2 =>
CPU_Next_State <= PIPE_FILL_1;
PC_Ctrl.Oper <= PC_INCR;
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;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
if( Enable_Auto_Increment and SubOp(0) = '1' )then
CPU_Next_State <= STX_C2;
ALU_Ctrl.Oper <= ALU_UPP;
640,7 → 642,7
 
when STX_C2 =>
CPU_Next_State <= PIPE_FILL_2;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_UPP2;
ALU_Ctrl.Reg <= SubOp(2 downto 1) & '1';
 
654,12 → 656,12
-- there is no ALU_Ctrl.Reg, as this is implied in the ALU instruction
when MUL_C1 =>
CPU_Next_State <= PIPE_FILL_2;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_MUL;
 
when UPP_C1 =>
CPU_Next_State <= PIPE_FILL_2;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_UPP2;
ALU_Ctrl.Reg <= SubOp_p1;
 
675,20 → 677,19
 
when POP_C2 =>
CPU_Next_State <= POP_C3;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when POP_C3 =>
CPU_Next_State <= POP_C4;
Cache_Ctrl <= CACHE_OPER1;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
 
when POP_C4 =>
CPU_Next_State <= INSTR_DECODE;
Cache_Ctrl <= CACHE_INSTR;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_POP;
ALU_Ctrl.Reg <= SubOp;
ALU_Ctrl.Data <= Operand1;
 
-------------------------------------------------------------------------------
-- Subroutines & Interrupts (RTS, JSR)
709,7 → 710,7
CPU_Next_State <= JSR_C1;
Cache_Ctrl <= CACHE_OPER1;
ALU_Ctrl.Oper <= ALU_STP;
ALU_Ctrl.Reg <= INT_FLAG;
ALU_Ctrl.Reg <= conv_std_logic_vector(PSR_I,3);
SP_Ctrl.Oper <= SP_PUSH;
DP_Ctrl.Src <= DATA_WR_PC;
DP_Ctrl.Reg <= PC_MSB;
725,7 → 726,6
when JSR_C2 =>
CPU_Next_State <= PIPE_FILL_0;
PC_Ctrl.Oper <= PC_LOAD;
PC_Ctrl.Addr <= Operand2 & Operand1;
SP_Ctrl.Oper <= SP_PUSH;
 
when RTS_C1 =>
750,17 → 750,18
when RTS_C5 =>
CPU_Next_State <= PIPE_FILL_0;
PC_Ctrl.Oper <= PC_LOAD;
PC_Ctrl.Addr <= Operand2 & Operand1;
-- if this is an RTI, then we need to clear the I bit
if( SubOp = SOP_RTI )then
CPU_Next_State <= RTI_C6;
Cache_Ctrl <= CACHE_OPER1;
ALU_Ctrl.Oper <= ALU_CLP;
ALU_Ctrl.Reg <= conv_std_logic_vector(PSR_I,3);
end if;
 
when RTI_C6 =>
CPU_Next_State <= PIPE_FILL_1;
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= PC_NEXT;
ALU_Ctrl.Oper <= ALU_RFLG;
ALU_Ctrl.Data <= Operand1;
 
-------------------------------------------------------------------------------
-- Debugging (BRK) Performs a 5-clock NOP
779,8 → 780,7
CPU_Next_State <= ISR_C1;
Cache_Ctrl <= CACHE_IDLE;
-- Rewind the PC by 3 to compensate for the pipeline registers
PC_Ctrl.Oper <= PC_INCR;
PC_Ctrl.Offset <= x"FF";
PC_Ctrl.Offset <= PC_REV3;
-- Reset all of the sub-block controls to IDLE, to avoid unintended
-- operation due to the current instruction
ALU_Ctrl.Oper <= ALU_IDLE;
882,20 → 882,11
Offset_SX(7 downto 0) := PC_Ctrl.Offset;
 
case PC_Ctrl.Oper is
when PC_IDLE =>
null;
 
when PC_REV1 =>
Program_Ctr <= Program_Ctr - 1;
 
when PC_REV2 =>
Program_Ctr <= Program_Ctr - 2;
 
when PC_INCR =>
Program_Ctr <= Program_Ctr + Offset_SX - 2;
 
when PC_LOAD =>
Program_Ctr <= PC_Ctrl.Addr;
Program_Ctr <= Operand2 & Operand1;
 
when others =>
null;
977,36 → 968,29
if( Pending(0) = '1' )then
ISR_Addr <= INT_VECTOR_0;
Pending(0) <= '0';
Wait_for_FSM <= '1';
elsif( Pending(1) = '1' )then
ISR_Addr <= INT_VECTOR_1;
Pending(1) <= '0';
Wait_for_FSM <= '1';
elsif( Pending(2) = '1' )then
ISR_Addr <= INT_VECTOR_2;
Pending(2) <= '0';
Wait_for_FSM <= '1';
elsif( Pending(3) = '1' )then
ISR_Addr <= INT_VECTOR_3;
Pending(3) <= '0';
Wait_for_FSM <= '1';
elsif( Pending(4) = '1' )then
ISR_Addr <= INT_VECTOR_4;
Pending(4) <= '0';
Wait_for_FSM <= '1';
elsif( Pending(5) = '1' )then
ISR_Addr <= INT_VECTOR_5;
Pending(5) <= '0';
Wait_for_FSM <= '1';
elsif( Pending(6) = '1' )then
ISR_Addr <= INT_VECTOR_6;
Pending(6) <= '0';
Wait_for_FSM <= '1';
elsif( Pending(7) = '1' )then
ISR_Addr <= INT_VECTOR_7;
Pending(7) <= '0';
Wait_for_FSM <= '1';
end if;
Wait_for_FSM <= or_reduce(Pending);
end if;
 
-- Reset the Wait_for_FSM flag on Int_Ack
1036,103 → 1020,103
when ALU_INC => -- Rn = Rn + 1 : Flags N,C,Z
Sum := ("0" & x"01") +
("0" & Regfile(Index));
Flags(FL_ZERO) <= nor_reduce(Sum(7 downto 0));
Flags(FL_CARRY) <= Sum(8);
Flags(FL_NEG) <= Sum(7);
Flags(PSR_Z) <= nor_reduce(Sum(7 downto 0));
Flags(PSR_C) <= Sum(8);
Flags(PSR_N) <= Sum(7);
Regfile(Index) <= Sum(7 downto 0);
 
when ALU_UPP => -- Rn = Rn + 1
Sum := ("0" & x"01") +
("0" & Regfile(Index));
Flags(FL_CARRY) <= Sum(8);
Flags(PSR_C) <= Sum(8);
Regfile(Index) <= Sum(7 downto 0);
 
when ALU_UPP2 => -- Rn = Rn + C
Sum := ("0" & x"00") +
("0" & Regfile(Index)) +
Flags(FL_CARRY);
Flags(FL_CARRY) <= Sum(8);
Flags(PSR_C);
Flags(PSR_C) <= Sum(8);
Regfile(Index) <= Sum(7 downto 0);
 
when ALU_ADC => -- R0 = R0 + Rn + C : Flags N,C,Z
Sum := ("0" & Regfile(0)) +
("0" & Regfile(Index)) +
Flags(FL_CARRY);
Flags(FL_ZERO) <= nor_reduce(Sum(7 downto 0));
Flags(FL_CARRY) <= Sum(8);
Flags(FL_NEG) <= Sum(7);
Flags(PSR_C);
Flags(PSR_Z) <= nor_reduce(Sum(7 downto 0));
Flags(PSR_C) <= Sum(8);
Flags(PSR_N) <= Sum(7);
Regfile(0) <= Sum(7 downto 0);
 
when ALU_TX0 => -- R0 = Rn : Flags N,Z
Temp := "0" & Regfile(Index);
Flags(FL_ZERO) <= nor_reduce(Temp(7 downto 0));
Flags(FL_NEG) <= Temp(7);
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
Flags(PSR_N) <= 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(FL_ZERO) <= nor_reduce(Temp(7 downto 0));
Flags(FL_NEG) <= Temp(7);
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
Flags(PSR_N) <= 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(FL_ZERO) <= nor_reduce(Temp(7 downto 0));
Flags(FL_NEG) <= Temp(7);
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
Flags(PSR_N) <= Temp(7);
Regfile(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) <= nor_reduce(Temp(7 downto 0));
Flags(FL_NEG) <= Temp(7);
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
Flags(PSR_N) <= Temp(7);
Regfile(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) <= nor_reduce(Temp(7 downto 0));
Flags(FL_CARRY) <= Temp(8);
Flags(FL_NEG) <= Temp(7);
Temp := Regfile(Index) & Flags(PSR_C);
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
Flags(PSR_C) <= Temp(8);
Flags(PSR_N) <= Temp(7);
Regfile(Index) <= Temp(7 downto 0);
 
when ALU_ROR => -- Rn = C,Rn>>1 : Flags N,C,Z
Temp := Regfile(Index)(0) & Flags(FL_CARRY) &
Temp := Regfile(Index)(0) & Flags(PSR_C) &
Regfile(Index)(7 downto 1);
Flags(FL_ZERO) <= nor_reduce(Temp(7 downto 0));
Flags(FL_CARRY) <= Temp(8);
Flags(FL_NEG) <= Temp(7);
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
Flags(PSR_C) <= Temp(8);
Flags(PSR_N) <= Temp(7);
Regfile(Index) <= Temp(7 downto 0);
 
when ALU_DEC => -- Rn = Rn - 1 : Flags N,C,Z
Sum := ("0" & Regfile(Index)) +
("0" & x"FF");
Flags(FL_ZERO) <= nor_reduce(Sum(7 downto 0));
Flags(FL_CARRY) <= Sum(8);
Flags(FL_NEG) <= Sum(7);
Flags(PSR_Z) <= nor_reduce(Sum(7 downto 0));
Flags(PSR_C) <= Sum(8);
Flags(PSR_N) <= Sum(7);
Regfile(Index) <= Sum(7 downto 0);
 
when ALU_SBC => -- Rn = R0 - Rn - C : Flags N,C,Z
Sum := ("0" & Regfile(0)) +
("1" & (not Regfile(Index))) +
Flags(FL_CARRY);
Flags(FL_ZERO) <= nor_reduce(Sum(7 downto 0));
Flags(FL_CARRY) <= Sum(8);
Flags(FL_NEG) <= Sum(7);
Flags(PSR_C);
Flags(PSR_Z) <= nor_reduce(Sum(7 downto 0));
Flags(PSR_C) <= Sum(8);
Flags(PSR_N) <= Sum(7);
Regfile(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);
Flags(PSR_C) <= Sum(8);
Regfile(0) <= Sum(7 downto 0);
Flags(FL_ZERO) <= nor_reduce(Sum(7 downto 0));
Flags(FL_NEG) <= Sum(7);
Flags(PSR_Z) <= nor_reduce(Sum(7 downto 0));
Flags(PSR_N) <= 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);
Flags(PSR_Z) <= not Regfile(0)(Index);
Flags(PSR_N) <= Regfile(0)(7);
 
when ALU_CLP => -- Clears bit(n) in the Flags register
Flags(Index) <= '0';
1139,8 → 1123,8
 
when ALU_T0X => -- Rn = R0 : Flags N,Z
Temp := "0" & Regfile(0);
Flags(FL_ZERO) <= nor_reduce(Temp(7 downto 0));
Flags(FL_NEG) <= Temp(7);
Flags(PSR_Z) <= nor_reduce(Temp(7 downto 0));
Flags(PSR_N) <= Temp(7);
Regfile(Index) <= Temp(7 downto 0);
 
when ALU_CMP => -- Sets Flags on R0 - Rn : Flags N,C,Z
1147,30 → 1131,34
Sum := ("0" & Regfile(0)) +
("1" & (not Regfile(Index))) +
'1';
Flags(FL_ZERO) <= nor_reduce(Sum(7 downto 0));
Flags(FL_CARRY) <= Sum(8);
Flags(FL_NEG) <= Sum(7);
Flags(PSR_Z) <= nor_reduce(Sum(7 downto 0));
Flags(PSR_C) <= Sum(8);
Flags(PSR_N) <= Sum(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) <= nor_reduce(Mult);
Flags(PSR_Z) <= nor_reduce(Mult);
 
when ALU_LDI => -- Rn <= Data : Flags N,Z
Flags(FL_ZERO) <= nor_reduce(ALU_Ctrl.Data);
Flags(FL_NEG) <= ALU_Ctrl.Data(7);
Regfile(Index) <= ALU_Ctrl.Data;
Flags(PSR_Z) <= nor_reduce(Operand1);
Flags(PSR_N) <= Operand1(7);
Regfile(Index) <= Operand1;
 
when ALU_POP => -- Rn <= Data
Regfile(Index) <= ALU_Ctrl.Data;
Regfile(Index) <= Operand1;
 
when ALU_RFLG =>
Flags <= ALU_Ctrl.Data;
Flags <= Operand1;
 
when ALU_TSX =>
when ALU_RSP =>
Regfile(0) <= Stack_Ptr(7 downto 0);
Regfile(1) <= Stack_Ptr(15 downto 8);
 
when ALU_GMSK =>
Flags(PSR_Z) <= nor_reduce(Int_Mask);
Regfile(0) <= Int_Mask;
 
when others =>
null;
end case;
1189,8 → 1177,4
begin
if( rising_edge(Clock) )then
Mult <= Regfile(0) *
Regfile(conv_integer(ALU_Ctrl.Reg));
end if;
end process;
 
end architecture;

powered by: WebSVN 2.1.0

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