Commit 981cbff7 authored by Roberto Hexsel's avatar Roberto Hexsel

fixed extCounter.c

parent 0fdaf364
00000318
[
08800010
00000319
]
00000319
[
08800010
0000031a
]
0000031a
[
08800010
0000031b
08800010
]
0000031b
......@@ -13,7 +13,7 @@ _start: nop
nop
mtc0 $k0, cop0_EPC
nop
eret # go into user mode, all else disabled
eret # leave exception level, all else disabled
nop
exit:
_exit: nop # flush pipeline
......@@ -26,40 +26,51 @@ _exit: nop # flush pipeline
nop
.end _start
.org x_EXCEPTION_0180,0 # exception vector_180
.global _excp_180
.org x_EXCEPTION_0180,0 # exception vector_180
.global excp_180
.ent _excp_180
excp_180:
_excp_180:
.ent excp_180
excp_180:
li $k0, '[' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
li $k0, '\n'
sw $k0, x_IO_ADDR_RANGE($14)
mfc0 $k0, cop0_CAUSE
sw $k0, 0($15) # print CAUSE
sw $k0, 0($14) # print CAUSE
mfc0 $k0, cop0_EPC # fix return address
sw $k0, 0($14) # print EPC
addiu $7, $7, -1
srl $k0, $k0, 2
sll $k0, $k0, 2
mtc0 $k0, cop0_EPC
nop
addiu $k1, $zero, -4 # -4 = 0xffff.fffc
and $k1, $k1, $k0 # fix the invalid address
mtc0 $k1, cop0_EPC
li $k0, ']' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
li $k0, '\n'
sw $k0, x_IO_ADDR_RANGE($14)
eret
.end _excp_180
.end excp_180
.org x_ENTRY_POINT,0 # normal code start
main: la $15,x_IO_BASE_ADDR
li $7,4
la $3,here
nop
main: la $14, x_IO_BASE_ADDR # used by handler
la $15, x_IO_BASE_ADDR
li $7, 3
la $3, here
nop
here: sw $3, 0($15)
here: sw $3, 0($15)
nop # 4th jr is to this address
beq $7,$zero, end
beq $7, $zero, end
nop
addiu $3,$3,1
addiu $3, $3, 1
nop # do not stall on $3
nop
jr $3
jr $3
nop
nop
nop
end: j exit
nop
\ No newline at end of file
00000000
[
08800014
00000318
0f000001
]
00000001
00000002
[
08800014
00000318
0f000002
]
00000002
00000003
[
08800014
00000318
0f000003
]
00000003
00000004
08800014
00000318
00000004
00000003
[
08800010
00000354
00000358
00400001
]
00000002
[
08800010
00000354
00000358
00400002
]
00000001
[
08800010
00000354
00000358
00400003
]
00000000
00000000
[
08800014
000003a0
0f000001
]
00000001
00000002
[
08800014
00000390
00000002
000003b8
0f000003
]
00000003
00000004
08800014
00000390
00000004
00000005
00000006
08800014
00000390
00000006
00000003
[
08800010
000003c8
000003f0
00400001
]
00000002
00000002
[
08800010
000003c8
00000410
00400003
]
00000001
08800010
000003c8
00000000
......@@ -13,7 +13,7 @@ _start: nop
nop
mtc0 $k0, cop0_EPC
nop
eret # go into user mode, all else disabled
eret # leave exception level, all else disabled
nop
nop
exit:
......@@ -27,94 +27,149 @@ _exit: nop # flush pipeline
nop
.end _start
.org x_EXCEPTION_0180,0 # exception vector_180
.global _excp_180
.org x_EXCEPTION_0180,0 # exception vector_180
.global excp_180
.ent _excp_180
.ent excp_180
excp_180:
_excp_180:
li $k0, '[' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
li $k0, '\n' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
mfc0 $k0, cop0_CAUSE
sw $k0,0($14) # print CAUSE
sw $k0, 0($14) # print CAUSE
mfc0 $k0, cop0_EPC # print EPC
sw $k0, 0($14)
mfc0 $k0, cop0_EPC #
sw $k0,0($14) # print EPC
addiu $7,$7,-1 # repetiton counter
mfc0 $k0, cop0_BadVAddr # print BadVAddr
sw $k0, 0($14)
addiu $k1, $zero, -4 # -4 = 0xffff.fffc
and $15,$15,$k1 # fix the invalid address
addiu $7, $7, -1 # repetiton counter
addiu $k1, $zero, -4 # -4 = 0xffff.fffc
and $15, $15, $k1 # fix the invalid address
li $k0, ']' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
li $k0, '\n' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
eret
.end _excp_180
.end excp_180
.org x_ENTRY_POINT,0 # normal code start
main: la $14, x_IO_BASE_ADDR
la $15, x_IO_BASE_ADDR
li $7, 3 # do 3 rounds
la $3, -1
##
## do 4 stores: 1st aligned, 2nd, 3rd, 4th misaligned,
## hence 3 exceptions of type AddrError store=x14
##
main: la $14, x_IO_BASE_ADDR # used by exception handler
la $15, x_IO_BASE_ADDR # used to generate misaligned references
li $7, 3 # do 4 rounds for each type of exception
li $3, 0 # exception handler decreases $7
nop
here: addiu $3, $3, 1
sw $3, 0($15) # exception handler decreases $7
beq $7, $zero, next # there should be 3 exceptions: addr&{01,10,11}
nop # of type AddrError store=x14
addu $15, $15, $3
j here
here: nop
sw $3, 0($15) # causes 3 exceptions: addr&{01,10,11}
addiu $3, $3, 1 # 1st is aligned, 2nd,3rd,4th misaligned
beq $7, $zero, next
nop
j here
addu $15, $15, $3
next: li $29, '\n' # to separate output
next: li $29, '\n' # to separate output
sw $29, x_IO_ADDR_RANGE($14)
sw $29, x_IO_ADDR_RANGE($14)
##
## do 4 loads, 1st aligned, 2nd, 3rd, 4th misaligned
## hence 3 exceptions of type AddrError if/ld=x10
##
la $15, x_DATA_BASE_ADDR
la $18, x_IO_BASE_ADDR
li $7, 3
la $3, -1
li $7, 3 # do 3 rounds
li $3, 0
sw $7, 0($15)
nop
there: addiu $3,$3,1
lw $3, 0($15) # there should be 3 exceptions: addr&{01,10,11}
sw $7, 0($18) # of type AddrError if/ld=x10
beq $7, $zero, after
nop
addu $15, $15, $3
j there
nop
there: nop
lw $5, 0($15) # causes 3 exceptions: addr&{01,10,11}
sw $7, 0($18) # print value changed by handler
# sw $5, 0($18) # print value read from memory
addiu $3, $3, 1
beq $7, $zero, after
nop
j there
addu $15, $15, $3
after: li $29, '\n' # to separate output
sw $29, x_IO_ADDR_RANGE($14)
la $14, x_IO_BASE_ADDR
sw $29, x_IO_ADDR_RANGE($14)
##
## do 4 half-word stores: 1st,3rd aligned, 2nd,4th misaligned,
## hence 3 exceptions of type AddrError store=x14
##
la $14, x_IO_BASE_ADDR # used by exception handler
la $15, x_IO_BASE_ADDR
li $7, 3
la $3, -1
li $3, 0
nop
here2: addiu $3, $3, 1 # there should be 3 exceptions: addr&{01,11}
sh $3, 0($15) # of type AddrError store=x14
beq $7, $zero, next2
nop
addu $15, $15, $3
j here2
nop
here2: sh $3, 0($15) # causes no exception: addr & 00
addiu $15, $15, 1 # of type AddrError store=x14
addiu $3 , $3, 1
sh $3, 0($15) # causes exception: addr & 01
addiu $15, $15, 2 # handler fixes $15 to addr & 00
addiu $3 , $3, 1
sh $3, 0($15) # causes no exception: addr & 10
addiu $15, $15, 1
addiu $3 , $3, 1
sh $3, 0($15) # causes exception: addr & 10
next2: li $29, '\n' # to separate output
sw $29, x_IO_ADDR_RANGE($14)
sw $29, x_IO_ADDR_RANGE($14)
la $15, x_DATA_BASE_ADDR
la $18, x_IO_BASE_ADDR
li $7, 3
la $3, -1
la $3, 0
sw $7, 0($15)
nop
there2: lh $3, 0($15) # there should be 3 exceptions: addr&{01,11}
sw $7, 0($18) # of type AddrError if/ld=x10
beq $7, $zero, end
nop
addu $15, $15, $3
nop
j there2
nop
##
## do 4 half-word loads: 1st,3rd aligned, 2nd,4th misaligned,
## hence 3 exceptions of type AddrError if/ld=x10
##
there2: lh $3, 0($15) # causes no exception: addr & 00
sw $7, 0($18)
addiu $15, $15, 1
addiu $3 , $3, 1
lh $3, 0($15) # causes exception: addr & 01
sw $7, 0($18)
addiu $15, $15, 2 # handler fixes $15 to addr & 00
addiu $3 , $3, 1
lh $3, 0($15) # causes no exception: addr & 10
sw $7, 0($18)
addiu $15, $15, 1
addiu $3 , $3, 1
lh $3, 0($15) # causes exception: addr & 10
sw $7, 0($18)
end: j exit
nop
......@@ -30,7 +30,7 @@ void main(void) {
if ( (new=readCounter()) > old) {
increased = increased & TRUE;
old = new;
// print(new); // print current count
// print(new); // print current count, not for automated tests
} else {
increased = FALSE;
}
......
......@@ -53,6 +53,8 @@ architecture rtl of core is
port(clk, rst, ld: in std_logic;
IF_excp_type: in exception_type;
RF_excp_type: out exception_type;
PC_abort: in boolean;
RF_PC_abort: out boolean;
IF_PC: in std_logic_vector;
RF_PC: out std_logic_vector);
end component reg_excp_IF_RF;
......@@ -71,6 +73,8 @@ architecture rtl of core is
EX_cop0_sel: out std_logic_vector;
RF_is_delayslot: in std_logic;
EX_is_delayslot: out std_logic;
RF_PC_abort: in boolean;
EX_PC_abort: out boolean;
RF_PC: in std_logic_vector;
EX_PC: out std_logic_vector;
RF_nmi: in std_logic;
......@@ -95,6 +99,8 @@ architecture rtl of core is
MM_PC: out std_logic_vector;
EX_cop0_LLbit: in std_logic;
MM_cop0_LLbit: out std_logic;
addrError: in boolean;
MM_abort: out boolean;
EX_cop0_a_c: in std_logic_vector;
MM_cop0_a_c: out std_logic_vector;
EX_cop0_val: in std_logic_vector;
......@@ -115,8 +121,8 @@ architecture rtl of core is
WB_PC: out std_logic_vector;
MM_cop0_LLbit: in std_logic;
WB_cop0_LLbit: out std_logic;
MM_abort: in std_logic;
WB_abort: out std_logic;
MM_abort: in boolean;
WB_abort: out boolean;
MM_cop0_a_c: in std_logic_vector;
WB_cop0_a_c: out std_logic_vector;
MM_cop0_val: in std_logic_vector;
......@@ -127,9 +133,11 @@ architecture rtl of core is
signal interrupt,EX_interrupt, exception_stall : std_logic;
signal exception_taken, interrupt_taken, trap_taken : std_logic;
signal nullify, nullify_EX, abort, MM_abort,WB_abort : std_logic;
signal nullify, nullify_EX, abort : std_logic;
signal addrError, MM_abort, WB_abort : boolean;
signal PC_abort, RF_PC_abort, EX_PC_abort : boolean;
signal IF_excp_type,RF_excp_type,EX_excp_type,WB_excp_type: exception_type := exNOP;
signal MM_excp_type, MM_excp_type_i, MM_addr_error, MM_excp_TLB : exception_type;
signal MM_excp_type, MM_excp_type_i, 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 EX_LLbit,MM_LLbit,WB_LLbit: std_logic;
......@@ -158,7 +166,7 @@ architecture rtl of core is
signal cop0_inp, RF_cop0_val,EX_cop0_val,MM_cop0_val,WB_cop0_val : reg32;
signal EX_cop0_a_c,MM_cop0_a_c,WB_cop0_a_c : reg5;
signal BadVAddr, BadVAddr_inp : reg32;
signal BadVAddr_update, BadVAddr_source : std_logic;
signal BadVAddr_update : std_logic;
-- MMU signals --
signal INDEX, index_inp, RANDOM, WIRED, wired_inp : reg32;
......@@ -177,10 +185,11 @@ architecture rtl of core is
signal hit4_pc, hit5_pc, hit6_pc, hit7_pc : boolean;
signal hit0_mm, hit1_mm, hit2_mm, hit3_mm, hit_mm : boolean;
signal hit4_mm, hit5_mm, hit6_mm, hit7_mm : boolean;
signal tlb_miss, tlb_miss_IF, tlb_miss_MM, tlb_exception : boolean;
signal hit_mm_v, hit_mm_d, hit_pc_v : std_logic;
signal tlb_adr_mm : MMU_idx_bits;
signal tlb_probe, probe_hit, hit_mm_bit : std_logic;
signal mm : std_logic_vector(VA_HI_BIT downto VA_LO_BIT);
signal mm, tlb_excp_VA : std_logic_vector(VA_HI_BIT downto VA_LO_BIT);
signal tlb_adr,tlb_a0_pc,tlb_a1_pc,tlb_a2_pc : natural range 0 to (MMU_CAPACITY-1);
signal hit_pc_adr, hit_mm_adr : natural range 0 to (MMU_CAPACITY-1);
signal tlb_a0_mm,tlb_a1_mm,tlb_a2_mm : natural range 0 to (MMU_CAPACITY-1);
......@@ -700,7 +709,7 @@ begin
stalled <= ram_stall or rom_stall;
not_stalled <= not(stalled);
-- end INSTR_FETCH_STATE_MACHINE --------------------------
-- end INSTR_FETCH_STATE_MACHINE --------------------------
-- PROGRAM COUNTER AND INSTRUCTION FETCH ------------------
......@@ -748,7 +757,9 @@ begin
IF_excp_type <= IFaddressError when PC(1 downto 0) /= b"00" else
exNOP;
PC_abort <= PC(1 downto 0) /= b"00";
PIPESTAGE_PC: register32 generic map (x_INST_BASE_ADDR)
port map (clk, rst, PCload, PCinp, PC);
......@@ -765,7 +776,7 @@ begin
-- uncomment this when making use of the TLB
-- i_addr <= phy_i_addr;
abort <= MM_abort or WB_abort;
abort <= '1' when addrError else '0';
instr_fetched <= instr when (nullify = '0' and abort = '0'
and PC(1 downto 0) = b"00") else
......@@ -1019,8 +1030,8 @@ begin
RF_DECODE_FUNCT: process (opcode,IF_RF_ld,ctrl_word,funct_word,rimm_word,
func,shamt, a_rs,a_rd, STATUS, MM_abort,
IF_excp_type,RF_excp_type,MM_excp_type)
func,shamt, a_rs,a_rd, STATUS, addrError,
RF_excp_type,MM_excp_type)
variable i_wreg : std_logic;
variable i_csel : reg2;
variable i_oper : t_alu_fun := opNOP;
......@@ -1142,11 +1153,11 @@ begin
when b"110000" => i_exception := exLL; -- not REALLY exceptions
when b"111000" => i_exception := exSC;
when b"111111" =>
if MM_abort = '1' then
i_exception := MM_excp_type;
else
i_exception := RF_excp_type; -- delayed by pipe
end if;
-- if addrError then
-- i_exception := MM_excp_type;
-- else
-- i_exception := RF_excp_type; -- delayed by pipe
-- end if;
when others => null; -- i_exception := exRESV_INSTR;
end case;
i_wreg := ctrl_word.wreg;
......@@ -1262,8 +1273,7 @@ begin
alu_move_ok, EX_oper,EX_postn,EX_shamt, ovfl);
EX_wreg <= EX_wreg_pre -- movz,movn, move/DO_NOT move
or nullify_EX -- abort wr if prev excep in EX
or abort; -- abort write if exception in MEM
or nullify_EX; -- abort wr if prev excep in EX
EX_wrmem_cond <= EX_wrmem
or nullify_EX -- abort write if exception in EX
......@@ -1276,10 +1286,58 @@ begin
-- this adder performs address calculation so the TLB can be checked during
-- EX and signal any exception as early as possible
-- EX so we may signal an exception as early as possible
U_VIR_ADDR_ADD: mf_alt_adder port map (alu_inp_A, EX_displ32, v_addr);
U_EX_ADDR_ERR_EXCP: process(EX_mem_t,EX_aVal,EX_wrmem, v_addr)
begin
case EX_mem_t(1 downto 0) is -- xx,by,hf,wd
when b"11" =>
if ( EX_mem_t(3) = '0' and -- normal LOAD, not LWL,LWR
EX_aVal = '0' and v_addr(1 downto 0) /= b"00" ) then
if EX_wrmem = '1' then
MM_excp_type <= MMaddressErrorLD;
else
MM_excp_type <= MMaddressErrorST;
end if;
addrError <= TRUE;
else
MM_excp_type <= exNOP;
addrError <= FALSE;
end if;
when b"10" => -- LH*, SH
if EX_aVal = '0' and v_addr(0) /= '0' then
if EX_wrmem = '1' then
MM_excp_type <= MMaddressErrorLD;
else
MM_excp_type <= MMaddressErrorST;
end if;
addrError <= TRUE;
else
MM_excp_type <= exNOP;
addrError <= FALSE;
end if;
when others => -- LB*, SB
MM_excp_type <= exNOP;
addrError <= FALSE;
end case;
-- assert MM_excp_type = exNOP -- DEBUG
-- report "SIMULATION ERROR -- data addressing error: " &
-- integer'image(exception_type'pos(MM_excp_type)) &
-- " at address: " & SLV32HEX(v_addr)
-- severity error;
end process U_EX_ADDR_ERR_EXCP; ----------------------------------
-- ----------------------------------------------------------------------
PIPESTAGE_EX_MM: reg_EX_MM
......@@ -1305,7 +1363,7 @@ begin
ram_stall <= not(daVal) and not(d_wait);
-- end DATA_BUS_STATE_MACHINE -------------------------------------
wr <= MM_wrmem or abort;
wr <= MM_wrmem;
rd_data_raw <= data_inp when (MM_wrmem = '1' and MM_aVal = '0') else
(others => 'X');
......@@ -1326,25 +1384,12 @@ begin