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