diff --git a/cMIPS/tests/mmu_context.s b/cMIPS/tests/mmu_context.s index 90e4d09c0fd7ee2e959f1a201e9de8047f4257d3..0b6e554d3bfc44647ae8ba78283963c96d79476d 100644 --- a/cMIPS/tests/mmu_context.s +++ b/cMIPS/tests/mmu_context.s @@ -18,24 +18,6 @@ # New entries cannot overwrite tlb[0,1] that map base of ROM + I/O - # EntryHi cannot have an ASID different from zero, otw TLB misses - .set entryHi_1, 0x00012000 # VPN2 (31..13) 0000 0000 0000 asid - # pfn0 zzcc cdvg - .set entryLo0_1, 0x0000091b # PPN (31..9)=9 1001 0001 1011 x91b - .set entryLo1_1, 0x00000c1b # x0 x0 x0 x0 x0 1100 0001 1011 xc1b - - .set entryHi_2, 0x00014000 # pfn0 zzcc cdvg - .set entryLo0_2, 0x00001016 # x0 x0 x0 x0 x1 0000 0001 0110 x1016 - .set entryLo1_2, 0x0000141e # x0 x0 x0 x0 x1 0100 0001 1110 x141e - - .set entryHi_3, 0x00016000 # pfn0 zzcc cdvg - .set entryLo0_3, 0x0000191f # x0 x0 x0 x0 x1 1001 0001 1111 x191f - .set entryLo1_3, 0x00001d3f # x0 x0 x0 x0 x1 1101 0011 1111 x1d3f - - .set entryHi_4, 0x00018000 # VPN2=30,31 pfn0 zzcc cdvg - .set entryLo0_4, 0x00000012 # x0 x0 x0 x0 x0 0000 0001 0010 x12 - .set entryLo1_4, 0x00000412 # x0 x0 x0 x0 x0 0100 0001 0010 x412 - .set MMU_ini_tag_RAM0, x_DATA_BASE_ADDR .set MMU_ini_dat_RAM0, 0x0001005 # this mapping is INVALID .set MMU_ini_dat_RAM1, 0x0001047 diff --git a/cMIPS/tests/mtc0CAUSE2.s b/cMIPS/tests/mtc0CAUSE2.s index 862dce87d2a8a414a893850e3b999715b8f176cf..c91bb51ef4c57c7aede9ee0193c5615aff66947f 100644 --- a/cMIPS/tests/mtc0CAUSE2.s +++ b/cMIPS/tests/mtc0CAUSE2.s @@ -24,6 +24,7 @@ _exit: nop # flush pipeline nop nop .end _start + .org x_EXCEPTION_0180,0 # exception vector_180 .ent _excp_180 @@ -40,23 +41,23 @@ _excp_180: .org x_ENTRY_POINT,0 # normal code start main: la $15,x_IO_BASE_ADDR - li $7,4 # do four rounds + li $7,4 # do four rounds li $5,0 here: sw $5, 0($15) - li $6, 0x10000302 # kernel mode, disable interrupts + li $6, 0x10000302 # kernel mode, disable interrupts mtc0 $6,cop0_STATUS - li $6, 0x0000ffff # write garbage to CAUSE, assert sw interr 0,1 + li $6, 0x0000ffff # write garbage to CAUSE, assert sw interr 0,1 mtc0 $6,cop0_CAUSE addiu $5,$5,2 - li $6, 0x10000311 # user mode, enable sw interrupts + li $6, 0x10000311 # user mode, enable sw interrupts mtc0 $6,cop0_STATUS nop nop nop - nop # wait for software interrupt + nop # wait for software interrupt bne $7,$zero, here nop diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd index 1650a7050f351cfa620a75384069e3baace4f9b9..133163c875e303020ea26da81a0f0085391435fa 100644 --- a/cMIPS/vhdl/core.vhd +++ b/cMIPS/vhdl/core.vhd @@ -85,7 +85,7 @@ architecture rtl of core is EX_trapped: out boolean); end component reg_excp_RF_EX; - component reg_excp_EX_MM is + component reg_excp_EX_MM is -- jjjjj port(clk, rst, ld: in std_logic; EX_cop0_reg: in reg5; MM_cop0_reg: out reg5; @@ -95,21 +95,25 @@ architecture rtl of core is MM_PC: out std_logic_vector; EX_v_addr: in std_logic_vector; MM_v_addr: out std_logic_vector; - nullify: in boolean; + EX_nullify: in boolean; MM_nullify: out boolean; - addrError: in boolean; + EX_addrError: in boolean; MM_addrError: out boolean; - addrErr_stage_mm: in boolean; + EX_addrErr_stage_mm: in boolean; MM_addrErr_stage_mm: out boolean; - EX_is_delayslot: in std_logic; - MM_is_delayslot: out std_logic; - EX_trapped: in boolean; - MM_trapped: out boolean; - EX_ll_sc_abort: in boolean; - MM_ll_sc_abort: out boolean; - TLB_exception: in boolean; + EX_mem_excp_type: in exception_type; + MM_mem_excp_type: out exception_type; + EX_is_delayslot: in std_logic; + MM_is_delayslot: out std_logic; + EX_trapped: in boolean; + MM_trapped: out boolean; + EX_ll_sc_abort: in boolean; + MM_ll_sc_abort: out boolean; + EX_tlb_exception: in boolean; MM_tlb_exception: out boolean; - tlb_stage_MM: in boolean; + EX_tlb_excp_type: in exception_type; + MM_tlb_excp_type: out exception_type; + EX_tlb_stage_MM: in boolean; MM_tlb_stage_MM: out boolean; EX_nmi: in std_logic; MM_nmi: out std_logic; @@ -121,8 +125,12 @@ architecture rtl of core is MM_is_SC: out boolean; EX_is_MFC0: in boolean; MM_is_MFC0: out boolean; - EX_is_exception: in exception_type; - MM_is_exception: out exception_type); + EX_ext_event: in boolean; + MM_ext_event: out boolean; + EX_ext_event_type: in exception_type; + MM_ext_event_type: out exception_type; + EX_int_event_type: in exception_type; + MM_int_event_type: out exception_type); end component reg_excp_EX_MM; component reg_excp_MM_WB is @@ -143,8 +151,9 @@ architecture rtl of core is signal nullify_fetch, nullify, MM_nullify : boolean; signal addrError, MM_addrError, abort_ref, MM_ll_sc_abort : boolean; signal PC_abort, RF_PC_abort, EX_PC_abort : boolean; - signal IF_excp_type,RF_excp_type: exception_type; - signal mem_excp_type, TLB_excp_type : exception_type; + signal IF_excp_type,RF_excp_type : exception_type; + signal mem_excp_type, MM_mem_excp_type : exception_type; + signal tlb_excp_type, MM_tlb_excp_type : exception_type; signal trap_instr,EX_trap_instr: instr_type; signal RF_PC,EX_PC,MM_PC,WB_PC, LLaddr: reg32; signal ll_sc_bit, MM_LLbit,WB_LLbit: std_logic; @@ -164,7 +173,8 @@ architecture rtl of core is signal STATUSinp,STATUS, CAUSEinp,CAUSE, EPCinp,EPC : reg32; signal COUNT, COMPARE : reg32; signal count_eq_compare,count_update,count_enable : std_logic; - signal exception,EX_exception, is_exception, MM_is_exception : exception_type; + signal exception,EX_exception, MM_exception : exception_type; + signal is_exception, MM_is_exception : exception_type; signal ExcCode : reg5 := cop0code_NULL; signal exception_dec,TLB_excp_num,trap_dec: integer; -- debugging signal RF_is_delayslot,EX_is_delayslot,MM_is_delayslot,WB_is_delayslot,is_delayslot : std_logic; @@ -175,8 +185,10 @@ architecture rtl of core is signal BadVAddr_update : std_logic; signal is_SC, MM_is_SC, is_MFC0, MM_is_MFC0 : boolean; - signal busError : boolean; + signal is_busError, is_nmi, is_interr, is_ovfl, ext_event, MM_ext_event : boolean; signal busError_type : exception_type; + signal ext_event_type, MM_ext_event_type : exception_type; + signal int_event_type, MM_int_event_type : exception_type; -- MMU signals -- signal INDEX, index_inp, RANDOM, WIRED, wired_inp : reg32; @@ -338,7 +350,7 @@ architecture rtl of core is signal WB_mem_t : reg2; signal alu_inp_A,alu_fwd_B,alu_inp_B : reg32; - signal alu_move_ok, MM_alu_move_ok, ovfl,MM_ovfl : std_logic; + signal alu_move_ok, MM_alu_move_ok, ovfl : std_logic; signal selB,EX_selB: std_logic; signal oper,EX_oper: t_alu_fun; @@ -1093,7 +1105,7 @@ begin RF_DECODE_FUNCT: process (opcode,IF_RF_ld,ctrl_word,funct_word,rimm_word, func,shamt, a_rs,a_rd, STATUS, - RF_excp_type,RF_instruction) -- mem_excp_type) + RF_excp_type,RF_instruction, mem_excp_type) variable i_wreg : std_logic; variable i_csel : reg2; variable i_oper : t_alu_fun := opNOP; @@ -1776,7 +1788,8 @@ begin trap_taken,EX_trapped); - EX_nmi <= nmi; + is_nmi <= ( (nmi = '1') and (STATUS(STATUS_ERL) = '0') ); + int_req(7) <= (irq(5) or count_eq_compare); int_req(6) <= irq(4); int_req(5) <= irq(3); @@ -1789,25 +1802,36 @@ begin interrupt <= int_req(7) or int_req(6) or int_req(5) or int_req(4) or int_req(3) or int_req(2) or int_req(1) or int_req(0); + is_interr <= ( (interrupt = '1') and + (STATUS(STATUS_EXL) = '0') and + (STATUS(STATUS_ERL) = '0') and + (STATUS(STATUS_IE) = '1') ); + -- check for overflow in EX, send it to MM for later processing - EX_ovfl <= (EX_can_trap = b"10" and ovfl = '1'); + is_ovfl <= (EX_can_trap = b"10" and ovfl = '1'); is_SC <= (EX_exception = exSC); -- is StoreConditional? (alu_fwd) is_mfc0 <= (EX_exception = exMFC0); -- is MFC0? (alu_fwd) - -- priority is given to events later in the pipeline + + -- priority is always given to events later in the pipeline busError_type <= exDBE when d_busErr = '0' else exIBE when i_busErr = '0' else exNOP; - busError <= (i_busErr = '0') or (d_busErr = '0'); + is_busError <= (i_busErr = '0') or (d_busErr = '0'); - is_exception <= busError_type when busError else - TLB_excp_type when tlb_exception else - mem_excp_type when addrError else - exTrap when EX_trapped else - exOvfl when EX_ovfl else - IFaddressError when EX_PC_abort else - EX_exception; + ext_event <= is_nmi or is_interr or is_busError; + ext_event_type <= busError_type when is_busError else + exNMI when is_nmi else + exInterr when is_interr else + exNOP; + + -- must always check for these + int_event_type <= mem_excp_type when addrError else + exTrap when EX_trapped else + exOvfl when is_ovfl else + IFaddressError when EX_PC_abort else + EX_exception; -- ---------------------------------------------------------------------- PIPESTAGE_EXCP_EX_MM: reg_excp_EX_MM @@ -1816,18 +1840,37 @@ begin EX_PC,MM_PC, v_addr,MM_v_addr, nullify,MM_nullify, addrError,MM_addrError, addrErr_stage_mm,MM_addrErr_stage_mm, + mem_excp_type, MM_mem_excp_type, EX_is_delayslot,MM_is_delayslot, EX_trapped,MM_trapped, SL2BOOL(LL_SC_abort), MM_ll_sc_abort, - tlb_exception,MM_tlb_exception, tlb_stage_mm,MM_tlb_stage_mm, + tlb_exception,MM_tlb_exception, + tlb_excp_type,MM_tlb_excp_type, + tlb_stage_mm,MM_tlb_stage_mm, EX_nmi,MM_nmi, interrupt,MM_interrupt, int_req,MM_int_req, is_SC, MM_is_SC, is_MFC0, MM_is_MFC0, - is_exception,MM_is_exception); + ext_event, MM_ext_event, + ext_event_type, MM_ext_event_type, + int_event_type, MM_int_event_type); + + -- kkkkk +-- is_exception <= MM_ext_event_type when MM_ext_event else +-- MM_TLB_excp_type when MM_tlb_exception else +-- MM_mem_excp_type when MM_addrError else +-- exTrap when MM_trapped else +-- exOvfl when MM_ovfl else +-- IFaddressError when MM_PC_abort else +-- MM_exception; + is_exception <= MM_ext_event_type when MM_ext_event else + MM_TLB_excp_type when MM_tlb_exception else + MM_int_event_type; + + -- STATUS -- pg 79 -- cop0_12 -------------------- COP0_DECODE_EXCEPTION_AND_UPDATE_STATUS: - process (MM_a_rt, MM_is_exception, cop0_inp, + process (MM_a_rt, is_exception, cop0_inp, MM_cop0_reg, MM_cop0_sel, MM_nmi, MM_interrupt,MM_int_req, RF_is_delayslot, EX_is_delayslot, MM_is_delayslot, WB_is_delayslot, rom_stall,ram_stall, MM_is_mfc0, @@ -1863,7 +1906,7 @@ begin newSTATUS(STATUS_CU1) := '0'; -- COP-1 absent (always) newSTATUS(STATUS_CU0) := '1'; -- COP-0 present=1 (always) - case MM_is_exception is + case is_exception is when exMTC0 => -- move to COP-0 i_update_r := MM_cop0_reg; @@ -1938,7 +1981,7 @@ begin when exSYSCALL | exBREAK => -- SYSCALL, BREAK i_stall := '0'; - if MM_is_exception = exSYSCALL then + if is_exception = exSYSCALL then ExcCode <= cop0code_Sys; else ExcCode <= cop0code_Bp; @@ -2033,7 +2076,7 @@ begin i_update_r := cop0reg_STATUS; i_epc_update := '0'; i_nullify := TRUE; -- nullify instructions in IF,RF,EX - if MM_is_exception = MMaddressErrorST then + if is_exception = MMaddressErrorST then ExcCode <= cop0code_AdES; else ExcCode <= cop0code_AdEL; @@ -2073,7 +2116,7 @@ begin when exTLBrefillRD | exTLBrefillWR => - case MM_is_exception is + case is_exception is when exTLBrefillRD => ExcCode <= cop0code_TLBL; when exTLBrefillWR => @@ -2113,7 +2156,7 @@ begin when exTLBdblFaultRD | exTLBdblFaultWR | exTLBinvalRD | exTLBinvalWR | exTLBmod => - case MM_is_exception is + case is_exception is when exTLBinvalRD | exTLBdblFaultRD => ExcCode <= cop0code_TLBL; when exTLBinvalWR | exTLBdblFaultWR => @@ -2138,7 +2181,7 @@ begin when exIBE | exDBE => -- BUS ERROR - if MM_is_exception = exIBE then + if is_exception = exIBE then ExcCode <= cop0code_IBE; else ExcCode <= cop0code_DBE; @@ -2150,34 +2193,8 @@ begin i_nullify := TRUE; -- nullify instructions in IF,RF,EX - when others => -- interrupt pending? - - if ( (MM_nmi = '1') and (STATUS(STATUS_ERL) = '0') ) then - -- non maskable interrupt - -- assert false report "NMinterrupt PC="&SLV32HEX(PC) severity note; - exception_taken <= '1'; - newSTATUS(STATUS_BEV) := '1'; -- locationVector at bootstrap - newSTATUS(STATUS_TS) := '0'; -- not TLBmatchesSeveral - newSTATUS(STATUS_SR) := '0'; -- not softReset - newSTATUS(STATUS_NMI) := '1'; -- non maskable interrupt - newSTATUS(STATUS_ERL) := '1'; -- at error level - i_update := '1'; - i_update_r := cop0reg_STATUS; - i_stall := '0'; - i_epc_update := '0'; - i_nullify := TRUE; -- nullify instructions in IF,RF,EX - if MM_is_delayslot = '1' then -- instr is in delay slot - i_epc_source := EPC_src_MM; -- re-execute branch/jump - is_delayslot <= MM_is_delayslot; - else - i_epc_source := EPC_src_EX; - is_delayslot <= EX_is_delayslot; - end if; - - elsif ( (STATUS(STATUS_EXL) = '0') and (STATUS(STATUS_ERL) = '0') and - (STATUS(STATUS_IE) = '1') and (MM_interrupt = '1') and - (rom_stall = '0' and ram_stall = '0')) then - -- normal interrupt + when exInterr => -- normal interrupt + if (rom_stall = '0') and (ram_stall = '0') then -- assert false report "interrupt PC="&SLV32HEX(PC) severity note; interrupt_taken <= '1'; -- debugging only newSTATUS(STATUS_UM) := '0'; -- enter kernel mode @@ -2196,8 +2213,31 @@ begin i_epc_source := EPC_src_EX; is_delayslot <= EX_is_delayslot; end if; + end if; - end if; -- NMI or else interrupt + + when exNMI => -- non maskable interrupt + -- assert false report "NMinterrupt PC="&SLV32HEX(PC) severity note; + exception_taken <= '1'; + newSTATUS(STATUS_BEV) := '1'; -- locationVector at bootstrap + newSTATUS(STATUS_TS) := '0'; -- not TLBmatchesSeveral + newSTATUS(STATUS_SR) := '0'; -- not softReset + newSTATUS(STATUS_NMI) := '1'; -- non maskable interrupt + newSTATUS(STATUS_ERL) := '1'; -- at error level + i_update := '1'; + i_update_r := cop0reg_STATUS; + i_stall := '0'; + i_epc_update := '0'; + i_nullify := TRUE; -- nullify instructions in IF,RF,EX + if MM_is_delayslot = '1' then -- instr is in delay slot + i_epc_source := EPC_src_MM; -- re-execute branch/jump + is_delayslot <= MM_is_delayslot; + else + i_epc_source := EPC_src_EX; + is_delayslot <= EX_is_delayslot; + end if; + + when others => null; end case; @@ -2206,7 +2246,7 @@ begin update <= i_update; update_reg <= i_update_r; - if MM_is_exception = exMTC0 and MM_cop0_reg = cop0reg_EPC then + if is_exception = exMTC0 and MM_cop0_reg = cop0reg_EPC then epc_update <= i_epc_update; else epc_update <= i_epc_update OR STATUS(STATUS_EXL); @@ -2220,12 +2260,12 @@ begin -- Select input to PC on an exception -------------------- - COP0_SEL_EPC: process (MM_is_exception, MM_nmi, MM_interrupt, STATUS, CAUSE, + COP0_SEL_EPC: process (is_exception, MM_nmi, MM_interrupt, STATUS, CAUSE, MM_trapped, rom_stall, ram_stall) variable i_excp_PCsel : reg3; begin - case MM_is_exception is + case is_exception is when exERET => -- exception return i_excp_PCsel := PCsel_EXC_EPC; -- PC <= EPC @@ -2247,24 +2287,23 @@ begin when exTLBrefillIF | exTLBrefillRD | exTLBrefillWR => i_excp_PCsel := PCsel_EXC_0000; -- PC <= exception_0000 - when others => -- interrupt pending? + when exNMI => -- non maskable interrupt + i_excp_PCsel := PCsel_EXC_BFC0; -- PC <= 0xBFC0.0000 - if ( (MM_nmi = '1') and (STATUS(STATUS_ERL) = '0') ) then - -- non maskable interrupt - i_excp_PCsel := PCsel_EXC_BFC0; -- PC <= 0xBFC0.0000 - - elsif ( (STATUS(STATUS_EXL) = '0') and (STATUS(STATUS_ERL) = '0') and - (STATUS(STATUS_IE) = '1') and (MM_interrupt = '1') and - (rom_stall = '0' and ram_stall = '0')) then - -- normal interrupt + when exInterr => -- normal interrupt + if (rom_stall = '0' and ram_stall = '0') then if CAUSE(CAUSE_IV) = '1' then i_excp_PCsel := PCsel_EXC_0200; -- PC <= exception_0200 else i_excp_PCsel := PCsel_EXC_0180; -- PC <= exception_0180 end if; - else - i_excp_PCsel := PCsel_EXC_none; -- should never get here - end if; -- NMI or interrupt + end if; + + when exNOP => + i_excp_PCsel := PCsel_EXC_none; -- no exception, do nothing to PC + + when others => -- should never get here + i_excp_PCsel := PCsel_EXC_none; end case; @@ -2341,7 +2380,7 @@ begin end if; end process COP0_COMPUTE_CAUSE; - COP0_CAUSE_HOLD: process(rst,clk, ExcCode,MM_is_exception, + COP0_CAUSE_HOLD: process(rst,clk, ExcCode,is_exception, MM_cop0_reg,not_stalled) variable state: reg32; begin @@ -2349,7 +2388,7 @@ begin cause_update <= '0'; elsif ( rising_edge(clk) and (ExcCode /= cop0code_NULL) ) then cause_update <= '1'; -- syscall/trap/interrupt/exception - elsif ( rising_edge(clk) and (MM_is_exception = exMFC0) and + elsif ( rising_edge(clk) and (is_exception = exMFC0) and MM_cop0_reg = cop0reg_CAUSE and (not_stalled = '1') ) then cause_update <= '0'; -- CAUSE is being read end if; @@ -2402,11 +2441,11 @@ begin -- BadVAddr -- pg 74 --------------------------- - U_BadVAddr_UPDATE: process(MM_is_exception, RF_is_delayslot, RF_PC, EX_PC, + U_BadVAddr_UPDATE: process(is_exception, RF_is_delayslot, RF_PC, EX_PC, MM_v_addr) variable i_update : std_logic; begin - case MM_is_exception is + case is_exception is when IFaddressError | exTLBrefillIF | exTLBdblFaultIF | exTLBinvalIF => if RF_is_delayslot = '1' then -- instr is in delay slot BadVAddr_inp <= EX_PC; @@ -2452,7 +2491,7 @@ begin if rst = '0' then ll_sc_bit <= '0'; elsif rising_edge(clk) then - case MM_is_exception is + case is_exception is when exERET => ll_sc_bit <= '0'; -- break SC -> LL when exLL => @@ -2700,7 +2739,7 @@ begin -- TLB_tag: 31..13 = VPN, 12..9 = 0, 8 = G, 7..0 = ASID -- TLB_dat: 29..6 = PPN, 5..3 = C, 2 = D, 1 = V, 0 = G - MMU_CONTROL: process(MM_is_exception, INDEX, RANDOM) + MMU_CONTROL: process(is_exception, INDEX, RANDOM) variable i_tlb_adr : integer range MMU_CAPACITY-1 downto 0; begin @@ -2722,7 +2761,7 @@ begin tlb_dat6_updt <= '1'; tlb_dat7_updt <= '1'; - case MM_is_exception is + case is_exception is when exTLBP => tlb_probe <= '1'; @@ -2739,7 +2778,7 @@ begin tlb_probe <= '0'; tlb_read <= '0'; - if MM_is_exception = exTLBWI then + if is_exception = exTLBWI then i_tlb_adr := to_integer(unsigned(INDEX(MMU_CAPACITY-1 downto 0))); else i_tlb_adr := to_integer(unsigned(RANDOM)); diff --git a/cMIPS/vhdl/exception.vhd b/cMIPS/vhdl/exception.vhd index 193176046b8a62ca33bf4c84696511d2f0a11a0b..ca089e6f24d7218a7a8c5ef5feaf033224879b45 100644 --- a/cMIPS/vhdl/exception.vhd +++ b/cMIPS/vhdl/exception.vhd @@ -126,21 +126,25 @@ entity reg_excp_EX_MM is MM_PC: out reg32; EX_v_addr: in reg32; MM_v_addr: out reg32; - nullify: in boolean; + EX_nullify: in boolean; MM_nullify: out boolean; - addrError: in boolean; + EX_addrError: in boolean; MM_addrError: out boolean; - addrErr_stage_mm: in boolean; + EX_addrErr_stage_mm: in boolean; MM_addrErr_stage_mm: out boolean; - EX_is_delayslot: in std_logic; - MM_is_delayslot: out std_logic; - EX_trapped: in boolean; - MM_trapped: out boolean; - EX_ll_sc_abort: in boolean; - MM_ll_sc_abort: out boolean; - tlb_exception: in boolean; + EX_mem_excp_type: in exception_type; + MM_mem_excp_type: out exception_type; + EX_is_delayslot: in std_logic; + MM_is_delayslot: out std_logic; + EX_trapped: in boolean; + MM_trapped: out boolean; + EX_ll_sc_abort: in boolean; + MM_ll_sc_abort: out boolean; + EX_tlb_exception: in boolean; MM_tlb_exception: out boolean; - tlb_stage_mm: in boolean; + EX_tlb_excp_type: in exception_type; + MM_tlb_excp_type: out exception_type; + EX_tlb_stage_mm: in boolean; MM_tlb_stage_mm: out boolean; EX_nmi: in std_logic; MM_nmi: out std_logic; @@ -152,9 +156,12 @@ entity reg_excp_EX_MM is MM_is_SC: out boolean; EX_is_MFC0: in boolean; MM_is_MFC0: out boolean; - EX_is_exception: in exception_type; - MM_is_exception: out exception_type - ); + EX_ext_event: in boolean; + MM_ext_event: out boolean; + EX_ext_event_type: in exception_type; + MM_ext_event_type: out exception_type; + EX_int_event_type: in exception_type; + MM_int_event_type: out exception_type); end reg_excp_EX_MM; architecture funcional of reg_excp_EX_MM is @@ -165,28 +172,35 @@ begin MM_trapped <= FALSE; MM_nullify <= FALSE; MM_addrError <= FALSE; + MM_trapped <= FALSE; MM_tlb_exception <= FALSE; - MM_is_exception <= exNOP; + MM_ext_event <= FALSE; + MM_ext_event_type <= exNOP; + MM_int_event_type <= exNOP; elsif rising_edge(clk) then if ld = '0' then MM_cop0_reg <= EX_cop0_reg ; MM_cop0_sel <= EX_cop0_sel ; MM_PC <= EX_PC ; MM_v_addr <= EX_v_addr ; - MM_nullify <= nullify ; - MM_addrError <= addrError ; - MM_addrErr_stage_mm <= addrErr_stage_mm; + MM_nullify <= EX_nullify ; + MM_addrError <= EX_addrError ; + MM_addrErr_stage_mm <= EX_addrErr_stage_mm; + MM_mem_excp_type <= EX_mem_excp_type; MM_is_delayslot <= EX_is_delayslot; MM_trapped <= EX_trapped ; MM_ll_sc_abort <= EX_ll_sc_abort ; - MM_tlb_exception <= TLB_exception ; - MM_tlb_stage_MM <= tlb_stage_MM ; + MM_tlb_exception <= EX_tlb_exception; + MM_tlb_excp_type <= EX_tlb_excp_type; + MM_tlb_stage_MM <= EX_tlb_stage_MM; MM_nmi <= EX_nmi ; MM_interrupt <= EX_interrupt ; MM_int_req <= EX_int_req ; MM_is_SC <= EX_is_SC ; MM_is_MFC0 <= EX_is_MFC0 ; - MM_is_exception <= EX_is_exception; + MM_ext_event <= EX_ext_event; + MM_ext_event_type <= EX_ext_event_type; + MM_int_event_type <= EX_int_event_type; end if; end if; end process; diff --git a/cMIPS/vhdl/packageExcp.vhd b/cMIPS/vhdl/packageExcp.vhd index 0b6e556a2e24818bbb1563a6868f9f47ba6f39ad..f1781d3442456ec1552f52a55918ca30d10b4f88 100644 --- a/cMIPS/vhdl/packageExcp.vhd +++ b/cMIPS/vhdl/packageExcp.vhd @@ -38,15 +38,31 @@ package p_EXCEPTION is exTLBP, exTLBR, exTLBWI, exTLBWR, -- 31 exDERET, -- 32 exIBE, exDBE, -- 34 + exNMI, exInterr, -- 36 invalid_exception); attribute enum_encoding of exception_type : type is - "000000 000001 000010 000011 000100 000101 000110 000111 001000 001001 001010 001011 001100 001101 001110 001111 010000 010001 010010 010011 010100 010101 010110 010111 011000 011001 011010 011011 011100 011101 011110 011111 100000 100001"; + "000000 000001 000010 000011 000100 000101 000110 000111 001000 001001 001010 001011 001100 001101 001110 001111 010000 010001 010010 010011 010100 010101 010110 010111 011000 011001 011010 011011 011100 011101 011110 011111 100000 100001 100010 100011 100100 100101"; -- 100110"; --- 100010"; + + -- Table 8-25 Cause Register ExcCode Field, pg 95 + constant cop0code_Int : reg5 := b"00000"; -- 0, interrupt=00 (CAUSE lsB) + constant cop0code_Mod : reg5 := b"00001"; -- 1, TLBmodified=x04 + constant cop0code_TLBL : reg5 := b"00010"; -- 2, TLBload if/ld=x08 + constant cop0code_TLBS : reg5 := b"00011"; -- 3, TLBstore if/ld=x0c + constant cop0code_AdEL : reg5 := b"00100"; -- 4, AddrError if/ld=x10 + constant cop0code_AdES : reg5 := b"00101"; -- 5, AddrError store=x14 + constant cop0code_IBE : reg5 := b"00110"; -- 6, BusErrorExcp if=x18 + constant cop0code_DBE : reg5 := b"00111"; -- 7, BusErrorExcp ld/st=x1c + constant cop0code_Sys : reg5 := b"01000"; -- 8, syscall=x20 + constant cop0code_Bp : reg5 := b"01001"; -- 9, breakpoint=x24 + constant cop0code_RI : reg5 := b"01010"; -- 10, reserved instruction=x28 + constant cop0code_CpU : reg5 := b"01011"; -- 11, CopUnusable excp=x2c + constant cop0code_Ov : reg5 := b"01100"; -- 12, arithmetic overflow=x30 + constant cop0code_Tr : reg5 := b"01101"; -- 13, trap=x34 + constant cop0code_NULL : reg5 := b"11111"; -- 1f, (no exception)=x3c - -- Table 8-1 Coprocessor 0 Registers, pg 55 constant cop0reg_Index : reg5 := b"00000"; -- 0 constant cop0reg_Random : reg5 := b"00001"; -- 1 @@ -66,25 +82,7 @@ package p_EXCEPTION is constant cop0reg_CONFIG : reg5 := b"10000"; -- 16 constant cop0reg_LLAddr : reg5 := b"10001"; -- 17 constant cop0reg_ErrorPC : reg5 := b"11110"; -- 30 - - -- Table 8-25 Cause Register ExcCode Field, pg 95 - constant cop0code_Int : reg5 := b"00000"; -- 0, interrupt=00 (CAUSE lsB) - constant cop0code_Mod : reg5 := b"00001"; -- 1, TLBmodified=x04 - constant cop0code_TLBL : reg5 := b"00010"; -- 2, TLBload if/ld=x08 - constant cop0code_TLBS : reg5 := b"00011"; -- 3, TLBstore if/ld=x0c - constant cop0code_AdEL : reg5 := b"00100"; -- 4, AddrError if/ld=x10 - constant cop0code_AdES : reg5 := b"00101"; -- 5, AddrError store=x14 - constant cop0code_IBE : reg5 := b"00110"; -- 6, BusErrorExcp if=x18 - constant cop0code_DBE : reg5 := b"00111"; -- 7, BusErrorExcp ld/st=x1c - constant cop0code_Sys : reg5 := b"01000"; -- 8, syscall=x20 - constant cop0code_Bp : reg5 := b"01001"; -- 9, breakpoint=x24 - constant cop0code_RI : reg5 := b"01010"; -- 10, reserved instruction=x28 - constant cop0code_CpU : reg5 := b"01011"; -- 11, CopUnusable excp=x2c - constant cop0code_Ov : reg5 := b"01100"; -- 12, arithmetic overflow=x30 - constant cop0code_Tr : reg5 := b"01101"; -- 13, trap=x34 - constant cop0code_NULL : reg5 := b"11111"; -- 1f, (no exception)=x3c - -- at exception level, kernel mode, cop0, all else disabled constant RESET_STATUS: std_logic_vector(31 downto 0) := x"10000002"; diff --git a/cMIPS/vhdl/packageMemory.vhd b/cMIPS/vhdl/packageMemory.vhd index 3e0e7994a91947ccff9c27e6878a64f7c3b6e794..2458190015c4ee163930f69074af127ad86a42c9 100644 --- a/cMIPS/vhdl/packageMemory.vhd +++ b/cMIPS/vhdl/packageMemory.vhd @@ -41,8 +41,8 @@ package p_MEMORY is -- begin DO NOT change these names as several scripts depend on them -- -- you may change the values, not names neither formatting -- constant x_INST_BASE_ADDR : reg32 := x"00000000"; - constant x_INST_MEM_SZ : reg32 := x"00004000"; - constant x_DATA_BASE_ADDR : reg32 := x"00020000"; + constant x_INST_MEM_SZ : reg32 := x"00010000"; + constant x_DATA_BASE_ADDR : reg32 := x"00010000"; constant x_DATA_MEM_SZ : reg32 := x"00008000"; constant x_IO_BASE_ADDR : reg32 := x"0F000000"; constant x_IO_MEM_SZ : reg32 := x"00002000"; diff --git a/cMIPS/vhdl/tb_cMIPS.vhd b/cMIPS/vhdl/tb_cMIPS.vhd index 2ad57d84fd65fc4c0ac6774e2f9a1c1f8c472d82..2643bc6a00305b2f4f4acdcc62d30a036e7a1816 100644 --- a/cMIPS/vhdl/tb_cMIPS.vhd +++ b/cMIPS/vhdl/tb_cMIPS.vhd @@ -509,7 +509,7 @@ begin -- TB cpu_d_wait <= data_wait and io_wait; io_wait <= io_lcd_wait and io_fpu_wait; - not_waiting <= (inst_wait and data_wait); -- and io_wait); + not_waiting <= (inst_wait and data_wait and io_wait); -- irq <= b"000000"; -- NO interrupt requests irq <= uart_irq & counter_irq & b"0000"; -- uart+counter interrupts @@ -672,15 +672,18 @@ architecture behavioral of inst_addr_decode is constant HI_ADDR : integer := HI_SEL_BITS; constant LO_ADDR : integer := log2_ceil(INST_BASE_ADDR + INST_MEM_SZ); constant PREFIX : std_logic_vector(HI_ADDR downto LO_ADDR) := (others=>'0'); + + signal in_range : boolean; begin - aVal <= '0' when ( cpu_i_aVal = '0' and rst = '1' - and (addr(HI_ADDR downto LO_ADDR) = PREFIX) ) - else '1'; + in_range <= (addr(HI_ADDR downto LO_ADDR) = PREFIX); + + aVal <= '0' when ( cpu_i_aVal = '0' and rst = '1' and in_range ) else + '1'; i_busError <= '0' when ( cpu_i_aVal = '0' and rst = '1' - and (addr(HI_ADDR downto LO_ADDR) /= PREFIX) ) - else '1'; + and not(in_range) ) else + '1'; end architecture behavioral; --++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++