diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd index d5991dac45a6a7116940a2d4ae773b2dd4a8e63c..54af5119218ef717bbabf11d05152ddceaf1dd63 100644 --- a/cMIPS/vhdl/core.vhd +++ b/cMIPS/vhdl/core.vhd @@ -48,251 +48,6 @@ end core; architecture rtl of core is --- fields of the control table --- aVal: std_logic; -- addressValid, enable data-mem=0 --- wmem: std_logic; -- READ=1/WRITE=0 in/to memory --- i: instr_type; -- instruction --- wreg: std_logic; -- register write=0 --- selB: std_logic; -- B ALU input, reg=0 ext=1 --- fun: std_logic; -- check function_field=1 --- oper: t_alu_fun; -- ALU operation --- muxC: reg3; -- select result mem=0 ula=1 jr=2 pc+8=3 --- c_sel: reg2; -- select destination reg RD=0 RT=1 31=2 --- extS: std_logic; -- sign-extend=1, zero-ext=0 --- PCsel: reg2; -- PCmux 0=PC+4 1=beq 2=j 3=jr --- br_t: t_comparison; -- branch: 0=no 1=beq 2=bne --- excp: reg2 -- stage with exception 0=no,1=rf,2=ex,3=mm - - constant ctrl_table : t_control_mem := ( - --aVal wmem ins wreg selB fun oper muxC csel extS PCsel br_t excp - ('1','1',iALU, '1','0','1',opNOP,"001","00", '0', "00",cNOP,"00"),--ALU=0 - ('1','1',RIMM, '1','0','0',opNOP,"001","00", '1', "00",cOTH,"00"),--BR=1 - ('1','1',J, '1','0','0',opNOP,"001","00", '0', "10",cNOP,"00"),--j=2 - ('1','1',JAL, '0','0','0',opNOP,"011","10", '0', "10",cNOP,"00"),--jal=3 - ('1','1',BEQ, '1','0','0',opNOP,"001","00", '1', "01",cEQU,"00"),--beq=4 - ('1','1',BNE, '1','0','0',opNOP,"001","00", '1', "01",cNEQ,"00"),--bne=5 - ('1','1',BLEZ, '1','0','0',opNOP,"001","00", '1', "01",cLEZ,"00"),--blez=6 - ('1','1',BGTZ, '1','0','0',opNOP,"001","00", '1', "01",cGTZ,"00"),--bgtz=7 - ('1','1',ADDI, '0','1','0',opADD,"001","01", '1', "00",cNOP,"10"),--addi=8 - ('1','1',ADDIU,'0','1','0',opADD,"001","01", '1', "00",cNOP,"00"),--addiu=9 - ('1','1',SLTI, '0','1','0',opSLT,"001","01", '1', "00",cNOP,"10"),--slti=10 - ('1','1',SLTIU,'0','1','0',opSLTU,"001","01",'1', "00",cNOP,"00"),--sltiu11 - ('1','1',ANDI, '0','1','0',opAND,"001","01", '0', "00",cNOP,"00"),--andi=12 - ('1','1',ORI, '0','1','0',opOR, "001","01", '0', "00",cNOP,"00"),--ori=13 - ('1','1',XORI, '0','1','0',opXOR,"001","01", '0', "00",cNOP,"00"),--xori=14 - ('1','1',LUI, '0','1','0',opLUI,"001","01", '0', "00",cNOP,"00"),--lui=15 - ('1','1',COP0, '1','0','1',opNOP,"110","01", '0', "00",cNOP,"00"),--COP0=16 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--17 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--18 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--19 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--beql=20 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--bnel=21 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--blzel=22 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--bgtzl=23 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--24 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--25 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--26 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--27 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--28 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--29 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--30 - ('1','1',SPEC3,'0','0','0',opSPC,"001","00", '0', "00",cNOP,"00"),--special3 - ('0','1',LB, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lb=32 - ('0','1',LH, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lh=33 - ('0','1',LWL, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lwl=34 - ('0','1',LW, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lw=35 - ('0','1',LBU, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lbu=36 - ('0','1',LHU, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lhu=37 - ('0','1',LWR, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lwr=38 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--39 - ('0','0',SB, '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sb=40 - ('0','0',SH, '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sh=41 - ('1','1',NIL, '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swl=42 - ('0','0',SW, '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sw=43 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--44 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--45 - ('1','1',NIL, '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swr=46 - ('1','1',NIL, '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--cache=47 - ('0','1',LL, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--ll=48 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--lwc1=49 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--lwc2=50 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--pref=51 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--52 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--ldc1=53 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--ldc2=54 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--55 - ('0','0',SC, '0','1','0',opADD,"111","01", '1', "00",cNOP,"00"),--sc=56 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swc1=57 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swc2=58 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--59 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--60 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--sdc1=61 - ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--sdc2=62 - ('1','1',NOP, '1','0','0',opNOP,"000","00", '0', "00",cNOP,"00") --63 - ); - --- fields of the function table (opcode=0) --- i: instr_type; -- instruction --- wreg: std_logic; -- register write=0 --- selB: std_logic; -- B ALU input, reg=0 ext=1 --- oper: t_alu_fun; -- ALU operation --- muxC: reg3; -- select result mem=0 ula=1 jr=2 pc+8=3 --- trap: std_logic; -- trap on compare --- move: std_logic; -- conditional move --- sync: std_logic; -- synch the memory hierarchy --- PCsel: reg2; -- PCmux 0=PC+4 1=beq 2=j 3=jr --- excp: reg2 -- stage with exception 0=no,1=rf,2=ex,3=mm - - constant func_table : t_function_mem := ( - -- i wreg selB oper muxC trap mov syn PCsel excp - (iSLL, '0','0',opSLL, "001",'0','0','0',"00","00"), --sll=0 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --1, FlPoint - (iSRL, '0','0',opSRL, "001",'0','0','0',"00","00"), --srl=2 - (iSRA, '0','0',opSRA, "001",'0','0','0',"00","00"), --sra=3 - (SLLV, '0','0',opSLLV, "001",'0','0','0',"00","00"), --sllv=4 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --5 - (SRLV, '0','0',opSRLV, "001",'0','0','0',"00","00"), --srlv=6 - (SRAV, '0','0',opSRAV, "001",'0','0','0',"00","00"), --srav=7 - (JR, '1','0',opNOP, "001",'0','0','0',"11","00"), --jr=8 - (JALR, '0','0',opNOP, "011",'0','0','0',"11","00"), --jalr=9 - (MOVZ, '0','0',opMOVZ, "001",'0','1','0',"00","00"), --movz=10 - (MOVN, '0','0',opMOVN, "001",'0','1','0',"00","00"), --movn=11 - (SYSCALL,'1','0',trNOP,"001",'1','0','0',"00","00"), --syscall=12 - (BREAK,'1','0',trNOP, "001",'1','0','0',"00","00"), --break=13 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --14 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --15 - (MFHI, '0','0',opMFHI, "100",'0','0','0',"00","00"), --mfhi=16 - (MTHI, '1','0',opMTHI, "001",'0','0','0',"00","00"), --mthi=17 - (MFLO, '0','0',opMFLO, "101",'0','0','0',"00","00"), --mflo=18 - (MTLO, '1','0',opMTLO, "001",'0','0','0',"00","00"), --mtlo=19 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --20 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --21 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --22 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --23 - (MULT, '1','0',opMULT, "001",'0','0','0',"00","00"), --mult=24 - (MULTU,'1','0',opMULTU,"001",'0','0','0',"00","00"), --multu=25 - (DIV, '1','0',opDIV, "001",'0','0','0',"00","00"), --div=26 - (DIVU, '1','0',opDIVU, "001",'0','0','0',"00","00"), --divu=27 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --28 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --29 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --30 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --31 - (ADD, '0','0',opADD, "001",'0','0','0',"00","10"), --add=32 - (ADDU, '0','0',opADDU, "001",'0','0','0',"00","00"), --addu=33 - (SUB, '0','0',opSUB, "001",'0','0','0',"00","10"), --sub=34 - (SUBU, '0','0',opSUBU, "001",'0','0','0',"00","00"), --subu=35 - (iAND, '0','0',opAND, "001",'0','0','0',"00","00"), --and=36 - (iOR, '0','0',opOR, "001",'0','0','0',"00","00"), --or=37 - (iXOR, '0','0',opXOR, "001",'0','0','0',"00","00"), --xor=38 - (iNOR, '0','0',opNOR, "001",'0','0','0',"00","00"), --nor=39 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --40 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --41 - (SLT, '0','0',opSLT, "001",'0','0','0',"00","10"), --slt=42 - (SLTU, '0','0',opSLTU, "001",'0','0','0',"00","00"), --sltu=43 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --44 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --45 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --46 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --47 - (TGE, '1','0',trGEQ, "001",'1','0','0',"00","01"), --tge=48 - (TGEU, '1','0',trGEU, "001",'1','0','0',"00","01"), --tgeu=49 - (TLT, '1','0',trLTH, "001",'1','0','0',"00","01"), --tlt=50 - (TLTU, '1','0',trLTU, "001",'1','0','0',"00","01"), --tltu=51 - (TEQ, '1','0',trEQU, "001",'1','0','0',"00","01"), --teq=52 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --53 - (TNE, '1','0',trNEQ, "001",'1','0','0',"00","01"), --tne=54 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --55 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --56 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --57 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --58 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --59 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --60 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --61 - (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --62 - (NOP, '1','0',opNOP, "001",'0','0','0',"00","00") --63 - ); - - -- fields of the register-immediate control table (opcode=1) - -- i: instr_type; -- instruction - -- wreg: std_logic; -- register write=0 - -- selB: std_logic; -- B ALU input, reg=0 ext=1 - -- br_t: t_comparison; -- comparison type: ltz,gez - -- muxC: reg3; -- select result mem=0 ula=1 jr=2 *al(pc+8)=3 - -- c_sel: reg2 -- select destination reg rd=0 rt=1 31=2 - -- trap: std_logic; -- trap on compare - -- PCsel: reg2; -- PCmux 0=PC+4 1=beq 2=j 3=jr - -- excp: reg2 -- stage with exception 0=no,1=rf,2=ex,3=mm - - constant rimm_table : t_rimm_mem := ( - -- i wreg selB br_t muxC csel trap PCsel excp - (BLTZ, '1','0',cLTZ, "001","00",'0',"01","00"), --0bltz - (BGEZ, '1','0',cGEZ, "001","00",'0',"01","00"), --1bgez - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --2 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --3 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --4 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --5 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --6 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --7 - (TGEI, '1','1',tGEQ, "001","00",'1',"00","10"), --8tgei - (TGEIU,'1','1',tGEU, "001","00",'1',"00","10"), --9tgeiu - (TLTI, '1','1',tLTH, "001","00",'1',"00","10"), --10tlti - (TLTIU,'1','1',tLTU, "001","00",'1',"00","10"), --11tltiu - (TEQI, '1','1',tEQU, "001","00",'1',"00","10"), --12teqi - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --13 - (TNEI, '1','1',tNEQ, "001","00",'1',"00","10"), --14tnei - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --15 - (BLTZAL,'0','0',cLTZ,"011","10",'0',"01","00"), --16bltzal - (BGEZAL,'0','0',cGEZ,"011","10",'0',"01","00"), --17bgezal - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --18 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --19 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --20 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --21 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --22 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --23 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --24 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --25 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --26 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --27 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --28 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --29 - (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --30 - (NOP, '1','0',cNOP, "001","00",'0',"00","00") --31 - ); - - -- Table 8-30 Config Register Field Descriptions, pg 101 - constant CONFIG0 : reg32 := ( - '1'& -- M, Config1 implemented = 1 - b"000"& -- K23, with MMU, kseg2,kseg3 coherency algorithm - b"000"& -- KU, with MMU, kuseg coherency algorithm - b"000000000"& -- Impl, implementation dependent = 0 - '0'& -- BE, little endian = 0 - b"00"& -- AT, MIPS32 = 0 - b"001"& -- AR, Release 2 = 1 - b"000"& -- MT, MMU type = 0, none - b"000"& -- nil, always zero = 0 - '1'& -- VI, Instruction Cache is virtual = 1 - b"000" -- K0, Kseg0 coherency algorithm - ); - - -- Table 8-31 Config1 Register Field Descriptions, pg 103 - constant CONFIG1 : reg32 := ( - '0'& -- M, Config2 implemented = 0 - b"000000"& -- MMUsz, MMU entries minus 1 - IC_SETS_PER_WAY & -- ICS, IC sets per way - IC_LINE_SIZE & -- ICL, IC line size - IC_ASSOCIATIVITY & -- ICA, IC associativity - DC_SETS_PER_WAY & -- DCS, DC sets per way - DC_LINE_SIZE & -- DCL, DC line size = 3 16 bytes/line - DC_ASSOCIATIVITY & -- DCA, DC associativity = 0 direct mapped - '0'& -- C2, No coprocessor 2 implemented = 0 - '0'& -- MD, No MDMX ASE implemented = 0 - '0'& -- PC, No performance counters implemented = 0 - '0'& -- WR, No watch registers implemented = 0 - '0'& -- CA, No code compression implemented = 0 - '0'& -- EP, No EJTAG implemented = 0 - '0' -- FP, No FPU implemented = 0 - ); - - -- control pipeline registers ------------ component reg_excp_IF_RF is port(clk, rst, ld: in std_logic; @@ -402,6 +157,30 @@ architecture rtl of core is signal BadVAddr, BadVAddr_inp : reg32; signal BadVAddr_update, BadVAddr_source : std_logic; + -- MMU signals -- + signal INDEX, index_inp, RANDOM, WIRED, wired_inp : reg32; + signal index_update, wired_update : std_logic; + signal EntryLo0, EntryLo1, EntryLo0_inp, EntryLo1_inp : reg32; + signal EntryHi, EntryHi_inp : reg32; + signal Context, PageMask, Context_inp, PageMask_inp : reg32; + signal entryLo0_update, entryLo1_update, entryHi_update : std_logic; + signal context_update, tlb_read : std_logic; + signal tlb_entrylo0_mm,tlb_entrylo1_mm,tlb_context_mm,tlb_entryhi : reg32; + signal tlb_tag0_updt, tlb_tag1_updt, tlb_tag2_updt, tlb_tag3_updt : std_logic; + signal tlb_dat0_updt, tlb_dat1_updt, tlb_dat2_updt, tlb_dat3_updt : std_logic; + signal hit_pc, hit0_pc, hit1_pc, hit2_pc, hit3_pc : std_logic; + signal tlb_a0_pc, tlb_a1_pc, tlb_a2_pc : std_logic; + signal hit_mm, hit0_mm, hit1_mm, hit2_mm, hit3_mm : std_logic; + signal tlb_a0_mm, tlb_a1_mm, tlb_a2_mm : std_logic; + signal tlb_adr_pc, tlb_adr_mm, probe_adr : MMU_idx_bits; + signal tlb_probe, probe_hit : std_logic; + signal mm : std_logic_vector(VA_HI_BIT downto VA_LO_BIT); + signal tlb_adr : natural range 0 to (MMU_CAPACITY - 1); + signal tlb_ppn : std_logic_vector(PPN_BITS - 1 downto 0); + + signal tlb_tag_inp, tlb_tag0, tlb_tag1, tlb_tag2, tlb_tag3 : reg32; + signal tlb_dat_inp, tlb_dat0, tlb_dat1, tlb_dat2, tlb_dat3 : reg28; + signal tlb_entryLo0, tlb_entryLo1, phy_i_addr : reg32; -- other components ------------ @@ -446,6 +225,13 @@ architecture rtl of core is Q: out std_logic_vector); end component register32; + component register28 is + generic (INITIAL_VALUE: std_logic_vector); + port(clk, rst, ld: in std_logic; + D: in std_logic_vector; + Q: out std_logic_vector); + end component register28; + component counter32 is generic (INITIAL_VALUE: std_logic_vector); port(clk, rst, ld, en: in std_logic; @@ -478,7 +264,7 @@ architecture rtl of core is signal br_target, br_addend, br_tgt_pl4, br_tgt_displ, j_target : reg32; signal RF_PCincd, RF_instruction : reg32; signal eq_fwd_A,eq_fwd_B : reg32; - + -- register fetch/read and instruction decode -- component reg_IF_RF is port(clk, rst, ld: in std_logic; @@ -499,7 +285,6 @@ architecture rtl of core is signal br_equal,br_negative,br_eq_zero: boolean; signal flush_RF_EX: boolean := FALSE; signal is_branch: std_logic; - -- attribute BUFFERED of is_branch : signal is "HIGH_DRIVE"; signal c_sel : reg2; -- execution and beyond -- @@ -513,8 +298,6 @@ architecture rtl of core is signal wrmem,EX_wrmem,EX_wrmem_cond,MM_wrmem, m_sign_ext: std_logic; signal mem_t, EX_mem_t,MM_mem_t: reg4; signal WB_mem_t : reg2; - -- attribute CLOCK_SIGNAL of MM_wrmem : signal is "no"; - -- attribute BUFFERED of MM_wrmem : signal is "HIGH_DRIVE"; signal alu_inp_A,alu_fwd_B,alu_inp_B : reg32; signal alu_move_ok, MM_alu_move_ok, ovfl,MM_ovfl : std_logic; @@ -532,8 +315,6 @@ architecture rtl of core is signal rd_data_raw, rd_data, WB_rd_data, WB_mem_data: reg32; signal MM_B_data, WB_B_data: reg32; signal jr_stall, br_stall, fwd_lwlr, sw_stall : std_logic; - -- attribute CLOCK_SIGNAL of rom_stall,ram_stall : signal is "no"; - -- attribute BUFFERED of rom_stall,ram_stall : signal is "HIGH_DRIVE"; signal fwd_mem, WB_addr2: reg2; @@ -611,34 +392,280 @@ architecture rtl of core is MM_pc_p8: out std_logic_vector); end component reg_EX_MM; - component reg_MM_WB is - port(clk, rst, ld: in std_logic; - MM_a_c: in std_logic_vector; - WB_a_c: out std_logic_vector; - MM_wreg: in std_logic; - WB_wreg: out std_logic; - MM_muxC: in std_logic_vector; - WB_muxC: out std_logic_vector; - MM_A: in std_logic_vector; - WB_A: out std_logic_vector; - MM_result: in std_logic_vector; - WB_result: out std_logic_vector; - MM_HI: in std_logic_vector; - WB_HI: out std_logic_vector; - MM_LO: in std_logic_vector; - WB_LO: out std_logic_vector; - rd_data: in std_logic_vector; - WB_rd_data: out std_logic_vector; - MM_B_data: in std_logic_vector; - WB_B_data: out std_logic_vector; - MM_addr2: in std_logic_vector; - WB_addr2: out std_logic_vector; - MM_oper: in std_logic_vector; - WB_oper: out std_logic_vector; - MM_pc_p8: in std_logic_vector; - WB_pc_p8: out std_logic_vector); - end component reg_MM_WB; + component reg_MM_WB is + port(clk, rst, ld: in std_logic; + MM_a_c: in std_logic_vector; + WB_a_c: out std_logic_vector; + MM_wreg: in std_logic; + WB_wreg: out std_logic; + MM_muxC: in std_logic_vector; + WB_muxC: out std_logic_vector; + MM_A: in std_logic_vector; + WB_A: out std_logic_vector; + MM_result: in std_logic_vector; + WB_result: out std_logic_vector; + MM_HI: in std_logic_vector; + WB_HI: out std_logic_vector; + MM_LO: in std_logic_vector; + WB_LO: out std_logic_vector; + rd_data: in std_logic_vector; + WB_rd_data: out std_logic_vector; + MM_B_data: in std_logic_vector; + WB_B_data: out std_logic_vector; + MM_addr2: in std_logic_vector; + WB_addr2: out std_logic_vector; + MM_oper: in std_logic_vector; + WB_oper: out std_logic_vector; + MM_pc_p8: in std_logic_vector; + WB_pc_p8: out std_logic_vector); + end component reg_MM_WB; + + +-- fields of the control table +-- aVal: std_logic; -- addressValid, enable data-mem=0 +-- wmem: std_logic; -- READ=1/WRITE=0 in/to memory +-- i: instr_type; -- instruction +-- wreg: std_logic; -- register write=0 +-- selB: std_logic; -- B ALU input, reg=0 ext=1 +-- fun: std_logic; -- check function_field=1 +-- oper: t_alu_fun; -- ALU operation +-- muxC: reg3; -- select result mem=0 ula=1 jr=2 pc+8=3 +-- c_sel: reg2; -- select destination reg RD=0 RT=1 31=2 +-- extS: std_logic; -- sign-extend=1, zero-ext=0 +-- PCsel: reg2; -- PCmux 0=PC+4 1=beq 2=j 3=jr +-- br_t: t_comparison; -- branch: 0=no 1=beq 2=bne +-- excp: reg2 -- stage with exception 0=no,1=rf,2=ex,3=mm + + constant ctrl_table : t_control_mem := ( + --aVal wmem ins wreg selB fun oper muxC csel extS PCsel br_t excp + ('1','1',iALU, '1','0','1',opNOP,"001","00", '0', "00",cNOP,"00"),--ALU=0 + ('1','1',RIMM, '1','0','0',opNOP,"001","00", '1', "00",cOTH,"00"),--BR=1 + ('1','1',J, '1','0','0',opNOP,"001","00", '0', "10",cNOP,"00"),--j=2 + ('1','1',JAL, '0','0','0',opNOP,"011","10", '0', "10",cNOP,"00"),--jal=3 + ('1','1',BEQ, '1','0','0',opNOP,"001","00", '1', "01",cEQU,"00"),--beq=4 + ('1','1',BNE, '1','0','0',opNOP,"001","00", '1', "01",cNEQ,"00"),--bne=5 + ('1','1',BLEZ, '1','0','0',opNOP,"001","00", '1', "01",cLEZ,"00"),--blez=6 + ('1','1',BGTZ, '1','0','0',opNOP,"001","00", '1', "01",cGTZ,"00"),--bgtz=7 + ('1','1',ADDI, '0','1','0',opADD,"001","01", '1', "00",cNOP,"10"),--addi=8 + ('1','1',ADDIU,'0','1','0',opADD,"001","01", '1', "00",cNOP,"00"),--addiu=9 + ('1','1',SLTI, '0','1','0',opSLT,"001","01", '1', "00",cNOP,"10"),--slti=10 + ('1','1',SLTIU,'0','1','0',opSLTU,"001","01",'1', "00",cNOP,"00"),--sltiu11 + ('1','1',ANDI, '0','1','0',opAND,"001","01", '0', "00",cNOP,"00"),--andi=12 + ('1','1',ORI, '0','1','0',opOR, "001","01", '0', "00",cNOP,"00"),--ori=13 + ('1','1',XORI, '0','1','0',opXOR,"001","01", '0', "00",cNOP,"00"),--xori=14 + ('1','1',LUI, '0','1','0',opLUI,"001","01", '0', "00",cNOP,"00"),--lui=15 + ('1','1',COP0, '1','0','1',opNOP,"110","01", '0', "00",cNOP,"00"),--COP0=16 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--17 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--18 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--19 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--beql=20 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--bnel=21 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--blzel=22 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--bgtzl=23 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--24 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--25 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--26 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--27 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--28 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--29 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--30 + ('1','1',SPEC3,'0','0','0',opSPC,"001","00", '0', "00",cNOP,"00"),--special3 + ('0','1',LB, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lb=32 + ('0','1',LH, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lh=33 + ('0','1',LWL, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lwl=34 + ('0','1',LW, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lw=35 + ('0','1',LBU, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lbu=36 + ('0','1',LHU, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lhu=37 + ('0','1',LWR, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--lwr=38 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--39 + ('0','0',SB, '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sb=40 + ('0','0',SH, '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sh=41 + ('1','1',NIL, '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swl=42 + ('0','0',SW, '1','1','0',opADD,"001","00", '1', "00",cNOP,"00"),--sw=43 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--44 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--45 + ('1','1',NIL, '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swr=46 + ('1','1',NIL, '1','1','0',opNOP,"001","00", '0', "00",cNOP,"00"),--cache=47 + ('0','1',LL, '0','1','0',opADD,"000","01", '1', "00",cNOP,"00"),--ll=48 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--lwc1=49 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--lwc2=50 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--pref=51 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--52 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--ldc1=53 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--ldc2=54 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--55 + ('0','0',SC, '0','1','0',opADD,"111","01", '1', "00",cNOP,"00"),--sc=56 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swc1=57 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--swc2=58 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--59 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--60 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--sdc1=61 + ('1','1',NIL, '1','0','0',opNOP,"001","00", '0', "00",cNOP,"00"),--sdc2=62 + ('1','1',NOP, '1','0','0',opNOP,"000","00", '0', "00",cNOP,"00") --63 + ); + +-- fields of the function table (opcode=0) +-- i: instr_type; -- instruction +-- wreg: std_logic; -- register write=0 +-- selB: std_logic; -- B ALU input, reg=0 ext=1 +-- oper: t_alu_fun; -- ALU operation +-- muxC: reg3; -- select result mem=0 ula=1 jr=2 pc+8=3 +-- trap: std_logic; -- trap on compare +-- move: std_logic; -- conditional move +-- sync: std_logic; -- synch the memory hierarchy +-- PCsel: reg2; -- PCmux 0=PC+4 1=beq 2=j 3=jr +-- excp: reg2 -- stage with exception 0=no,1=rf,2=ex,3=mm + + constant func_table : t_function_mem := ( + -- i wreg selB oper muxC trap mov syn PCsel excp + (iSLL, '0','0',opSLL, "001",'1','0','0',"00","00"), --sll=0, EHB + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --1, FlPoint + (iSRL, '0','0',opSRL, "001",'0','0','0',"00","00"), --srl=2 + (iSRA, '0','0',opSRA, "001",'0','0','0',"00","00"), --sra=3 + (SLLV, '0','0',opSLLV, "001",'0','0','0',"00","00"), --sllv=4 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --5 + (SRLV, '0','0',opSRLV, "001",'0','0','0',"00","00"), --srlv=6 + (SRAV, '0','0',opSRAV, "001",'0','0','0',"00","00"), --srav=7 + (JR, '1','0',opNOP, "001",'0','0','0',"11","00"), --jr=8 + (JALR, '0','0',opNOP, "011",'0','0','0',"11","00"), --jalr=9 + (MOVZ, '0','0',opMOVZ, "001",'0','1','0',"00","00"), --movz=10 + (MOVN, '0','0',opMOVN, "001",'0','1','0',"00","00"), --movn=11 + (SYSCALL,'1','0',trNOP,"001",'1','0','0',"00","00"), --syscall=12 + (BREAK,'1','0',trNOP, "001",'1','0','0',"00","00"), --break=13 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --14 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --15 + (MFHI, '0','0',opMFHI, "100",'0','0','0',"00","00"), --mfhi=16 + (MTHI, '1','0',opMTHI, "001",'0','0','0',"00","00"), --mthi=17 + (MFLO, '0','0',opMFLO, "101",'0','0','0',"00","00"), --mflo=18 + (MTLO, '1','0',opMTLO, "001",'0','0','0',"00","00"), --mtlo=19 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --20 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --21 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --22 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --23 + (MULT, '1','0',opMULT, "001",'0','0','0',"00","00"), --mult=24 + (MULTU,'1','0',opMULTU,"001",'0','0','0',"00","00"), --multu=25 + (DIV, '1','0',opDIV, "001",'0','0','0',"00","00"), --div=26 + (DIVU, '1','0',opDIVU, "001",'0','0','0',"00","00"), --divu=27 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --28 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --29 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --30 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --31 + (ADD, '0','0',opADD, "001",'0','0','0',"00","10"), --add=32 + (ADDU, '0','0',opADDU, "001",'0','0','0',"00","00"), --addu=33 + (SUB, '0','0',opSUB, "001",'0','0','0',"00","10"), --sub=34 + (SUBU, '0','0',opSUBU, "001",'0','0','0',"00","00"), --subu=35 + (iAND, '0','0',opAND, "001",'0','0','0',"00","00"), --and=36 + (iOR, '0','0',opOR, "001",'0','0','0',"00","00"), --or=37 + (iXOR, '0','0',opXOR, "001",'0','0','0',"00","00"), --xor=38 + (iNOR, '0','0',opNOR, "001",'0','0','0',"00","00"), --nor=39 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --40 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --41 + (SLT, '0','0',opSLT, "001",'0','0','0',"00","10"), --slt=42 + (SLTU, '0','0',opSLTU, "001",'0','0','0',"00","00"), --sltu=43 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --44 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --45 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --46 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --47 + (TGE, '1','0',trGEQ, "001",'1','0','0',"00","01"), --tge=48 + (TGEU, '1','0',trGEU, "001",'1','0','0',"00","01"), --tgeu=49 + (TLT, '1','0',trLTH, "001",'1','0','0',"00","01"), --tlt=50 + (TLTU, '1','0',trLTU, "001",'1','0','0',"00","01"), --tltu=51 + (TEQ, '1','0',trEQU, "001",'1','0','0',"00","01"), --teq=52 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --53 + (TNE, '1','0',trNEQ, "001",'1','0','0',"00","01"), --tne=54 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --55 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --56 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --57 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --58 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --59 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --60 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --61 + (NIL, '1','0',opNOP, "001",'0','0','0',"00","00"), --62 + (NOP, '1','0',opNOP, "001",'0','0','0',"00","00") --63 + ); + + -- fields of the register-immediate control table (opcode=1) + -- i: instr_type; -- instruction + -- wreg: std_logic; -- register write=0 + -- selB: std_logic; -- B ALU input, reg=0 ext=1 + -- br_t: t_comparison; -- comparison type: ltz,gez + -- muxC: reg3; -- select result mem=0 ula=1 jr=2 *al(pc+8)=3 + -- c_sel: reg2 -- select destination reg rd=0 rt=1 31=2 + -- trap: std_logic; -- trap on compare + -- PCsel: reg2; -- PCmux 0=PC+4 1=beq 2=j 3=jr + -- excp: reg2 -- stage with exception 0=no,1=rf,2=ex,3=mm + + constant rimm_table : t_rimm_mem := ( + -- i wreg selB br_t muxC csel trap PCsel excp + (BLTZ, '1','0',cLTZ, "001","00",'0',"01","00"), --0bltz + (BGEZ, '1','0',cGEZ, "001","00",'0',"01","00"), --1bgez + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --2 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --3 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --4 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --5 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --6 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --7 + (TGEI, '1','1',tGEQ, "001","00",'1',"00","10"), --8tgei + (TGEIU,'1','1',tGEU, "001","00",'1',"00","10"), --9tgeiu + (TLTI, '1','1',tLTH, "001","00",'1',"00","10"), --10tlti + (TLTIU,'1','1',tLTU, "001","00",'1',"00","10"), --11tltiu + (TEQI, '1','1',tEQU, "001","00",'1',"00","10"), --12teqi + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --13 + (TNEI, '1','1',tNEQ, "001","00",'1',"00","10"), --14tnei + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --15 + (BLTZAL,'0','0',cLTZ,"011","10",'0',"01","00"), --16bltzal + (BGEZAL,'0','0',cGEZ,"011","10",'0',"01","00"), --17bgezal + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --18 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --19 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --20 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --21 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --22 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --23 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --24 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --25 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --26 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --27 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --28 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --29 + (NIL, '1','0',cNOP, "001","00",'0',"00","00"), --30 + (NOP, '1','0',cNOP, "001","00",'0',"00","00") --31 + ); + + -- Table 8-30 Config Register Field Descriptions, pg 101 + constant CONFIG0 : reg32 := ( + '1'& -- M, Config1 implemented = 1 + b"000"& -- K23, with MMU, kseg2,kseg3 coherency algorithm + b"000"& -- KU, with MMU, kuseg coherency algorithm + b"000000000"& -- Impl, implementation dependent = 0 + '0'& -- BE, little endian = 0 + b"00"& -- AT, MIPS32 = 0 + b"001"& -- AR, Release 2 = 1 + b"001"& -- MT, MMU type = 1, standard + b"000"& -- nil, always zero = 0 + '1'& -- VI, Instruction Cache is virtual = 1 + b"000" -- K0, Kseg0 coherency algorithm + ); + + -- Table 8-31 Config1 Register Field Descriptions, pg 103 + constant CONFIG1 : reg32 := ( + '0'& -- M, Config2 not implemented = 0 + MMU_SIZE & -- MMUsz, MMU entries minus 1 + IC_SETS_PER_WAY & -- ICS, IC sets per way + IC_LINE_SIZE & -- ICL, IC line size + IC_ASSOCIATIVITY & -- ICA, IC associativity + DC_SETS_PER_WAY & -- DCS, DC sets per way + DC_LINE_SIZE & -- DCL, DC line size = 3 16 bytes/line + DC_ASSOCIATIVITY & -- DCA, DC associativity = 0 direct mapped + '0'& -- C2, No coprocessor 2 implemented = 0 + '0'& -- MD, No MDMX ASE implemented = 0 + '0'& -- PC, No performance counters implemented = 0 + '0'& -- WR, No watch registers implemented = 0 + '0'& -- CA, No code compression implemented = 0 + '0'& -- EP, No EJTAG implemented = 0 + '0' -- FP, No FPU implemented = 0 + ); + -- pipeline ============================================================ begin @@ -1002,6 +1029,10 @@ begin case funct_word.i is when SYSCALL => i_exception := exSYSCALL; when BREAK => i_exception := exBREAK; + when iSLL => + if RF_instruction = x"000000c0" then + i_exception := exEHB; + end if; when others => i_exception := exTRAP; end case; end if; @@ -1030,18 +1061,23 @@ begin i_wreg := '0'; when b"10000" => -- ERET case func is + when b"000001" => i_exception := exTLBR; + when b"000010" => i_exception := exTLBWI; + when b"000110" => i_exception := exTLBWR; + when b"001000" => i_exception := exTLBP; when b"011000" => i_exception := exERET; + when b"011111" => i_exception := exDERET; when b"100000" => i_exception := exWAIT; when others => i_exception := exRESV_INSTR; end case; when b"01011" => -- EI and DI case func is when b"100000" => -- EI; - i_exception := exEI; - i_wreg := '0'; + i_exception := exEI; + i_wreg := '0'; when b"000000" => -- DI; - i_exception := exDI; - i_wreg := '0'; + i_exception := exDI; + i_wreg := '0'; when others => i_exception := exRESV_INSTR; end case; when others => i_exception := exRESV_INSTR; @@ -1530,7 +1566,7 @@ begin end if; end process RF_FORWARDING_TRAPS; - + -- ---------------------------------------------------------------------- PIPESTAGE_EXCP_RF_EX: reg_excp_RF_EX port map (clk, rst, excp_RF_EX_ld, can_trap,EX_can_trap, @@ -1586,6 +1622,12 @@ begin BadVAddr_source <= '0'; BadVAddr_update <= '1'; + newSTATUS(STATUS_BEV) := '0'; -- interrupts at offset 0x200 + newSTATUS(STATUS_CU3) := '0'; -- COP-3 absent (always) + newSTATUS(STATUS_CU2) := '0'; -- COP-2 absent (always) + newSTATUS(STATUS_CU1) := '0'; -- COP-1 absent (always) + newSTATUS(STATUS_CU0) := '1'; -- COP-0 present=1 (always) + case is_exception is when exMTC0 => -- move to COP-0 @@ -1595,13 +1637,17 @@ begin newSTATUS := cop0_inp; i_update := '1'; i_stall := '1'; - when cop0reg_COUNT | cop0reg_COMPARE | cop0reg_CAUSE => + when cop0reg_COUNT | cop0reg_COMPARE | cop0reg_CAUSE | + cop0reg_EntryLo0 | cop0reg_EntryLo1 | cop0reg_EntryHi => i_update := '1'; i_stall := '1'; + when cop0reg_Index | cop0reg_Context | cop0reg_Wired => + i_update := '1'; + i_stall := '0'; when cop0reg_EPC => i_epc_update := '0'; i_epc_source := b"100"; -- EX_B - i_stall := '1'; + i_stall := '0'; when others => i_stall := '0'; i_update := '0'; @@ -1625,6 +1671,14 @@ begin when exMFC0 => -- move from COP-0 case EX_cop0_reg is + when cop0reg_Index => i_COP0_rd := INDEX; + when cop0reg_Random => i_COP0_rd := RANDOM; + when cop0reg_EntryLo0 => i_COP0_rd := EntryLo0; + when cop0reg_EntryLo1 => i_COP0_rd := EntryLo1; + when cop0reg_Context => i_COP0_rd := CONTEXT; + when cop0reg_PageMask => i_COP0_rd := PAGEMASK; + when cop0reg_Wired => i_COP0_rd := WIRED; + when cop0reg_EntryHi => i_COP0_rd := EntryHi; when cop0reg_COUNT => i_COP0_rd := COUNT; when cop0reg_COMPARE => i_COP0_rd := COMPARE; when cop0reg_STATUS => i_COP0_rd := STATUS; @@ -1640,17 +1694,17 @@ begin when others => i_COP0_rd := (others => 'X'); end case; i_a_c := EX_a_rt; - i_stall := '1'; + i_stall := '0'; when exERET => -- exception return i_update := '1'; i_update_r := cop0reg_STATUS; - i_stall := '0'; - i_excp_PCsel := PCsel_EXC_EPC; -- PC <= EPC - i_nullify := '1'; -- nullify instructions in IF,RF - + i_stall := '0'; -- do not stall + i_excp_PCsel := PCsel_EXC_EPC; -- PC <= EPC + i_nullify := '1'; -- nullify instructions in IF,RF + newSTATUS(STATUS_EXL) := '0'; -- leave exception level + when exTRAP | exSYSCALL | exBREAK => -- trap instruction - ExcCode <= cop0code_Tr; i_stall := '0'; case EX_trap_instr is when TEQ | TEQI => @@ -1663,15 +1717,20 @@ begin i_take_trap := not(EX_tr_less_than); when SYSCALL => i_take_trap := '1'; - ExcCode <= cop0code_Sys; when BREAK => i_take_trap := '1'; - ExcCode <= cop0code_Bp; when others => i_take_trap := '0'; end case; if i_take_trap = '1' then trap_taken <= '1'; + case EX_trap_instr is + when TEQ | TEQI | TNE | TNEI | TLT | TLTI | TLTU | TLTIU | + TGE | TGEI | TGEU | TGEIU => ExcCode <= cop0code_Tr; + when SYSCALL => ExcCode <= cop0code_Sys; + when BREAK => ExcCode <= cop0code_Bp; + when others => null; + end case; newSTATUS(STATUS_EXL) := '1'; -- at exception level newSTATUS(STATUS_UM) := '0'; -- enter kernel mode newSTATUS(STATUS_IE) := '0'; -- disable interrupts @@ -1695,7 +1754,7 @@ begin i_update_r := cop0reg_LLaddr; -- when exSC => null; if treated here, SC might delay an interrupt - + when exRESV_INSTR => -- reserved instruction ABORT SIMULATION assert true -- invalid opcode @@ -1738,8 +1797,15 @@ begin i_epc_source := b"011"; -- bad address is in EXCP_MM_PC badVAddr_source <= '1'; -- load/store end if; + + when exEHB => -- stall processor to clear hazards + i_stall := '1'; + + + when exTLBP | exTLBR | exTLBWI | exTLBWR => -- TLB access + i_stall := '1'; -- stall the processor + - when others => -- interrupt pending? if ( (EX_nmi = '1') and (STATUS(STATUS_ERL) = '0') ) then @@ -1793,22 +1859,22 @@ begin end case; - newSTATUS(STATUS_CU3) := '0'; -- COP-3 absent (always) - newSTATUS(STATUS_CU2) := '0'; -- COP-2 absent (always) - newSTATUS(STATUS_CU1) := '0'; -- COP-1 absent (always) - newSTATUS(STATUS_CU0) := '1'; -- COP-0 present=1 (always) - - STATUSinp <= newSTATUS; EX_cop0_val <= i_COP0_rd; EX_cop0_a_c <= i_a_c; -- only for forwarding COP0 values update <= i_update; update_reg <= i_update_r; - epc_update <= i_epc_update; + + if is_exception = exMTC0 and EX_cop0_reg = cop0reg_EPC then + epc_update <= i_epc_update; + else + epc_update <= i_epc_update OR STATUS(STATUS_EXL); + end if; epc_source <= i_epc_source; excp_PCsel <= i_excp_PCsel; + exception_stall <= i_stall; - nullify <= i_nullify; + nullify <= i_nullify; end process COP0_DECODE_EXCEPTION_AND_UPDATE_STATUS; @@ -1850,38 +1916,43 @@ begin EX_is_delayslot, count_eq_compare,count_enable, CAUSE) variable newCAUSE : reg32; begin - newCAUSE(CAUSE_BD) := EX_is_delayslot; -- instr is in delay slot - newCAUSE(CAUSE_TI) := count_eq_compare; - newCAUSE(CAUSE_CE1) := '0'; - newCAUSE(CAUSE_CE0) := '0'; - newCAUSE(CAUSE_DC) := CAUSE(CAUSE_DC); - newCAUSE(CAUSE_PCI) := '0'; - newCAUSE(25 downto 24) := b"00"; - newCAUSE(CAUSE_IV) := CAUSE(CAUSE_IV); - newCAUSE(CAUSE_WP) := '0'; - newCAUSE(21 downto 16) := b"000000"; - newCAUSE(CAUSE_IP7) := EX_int_req(7); - newCAUSE(CAUSE_IP6) := EX_int_req(6); - newCAUSE(CAUSE_IP5) := EX_int_req(5); - newCAUSE(CAUSE_IP4) := EX_int_req(4); - newCAUSE(CAUSE_IP3) := EX_int_req(3); - newCAUSE(CAUSE_IP2) := EX_int_req(2); - newCAUSE(CAUSE_IP1) := CAUSE(CAUSE_IP1); - newCAUSE(CAUSE_IP0) := CAUSE(CAUSE_IP0); - newCAUSE(7) := '0'; - newCAUSE(6 downto 2) := ExcCode; - newCAUSE(1 downto 0) := b"00"; - - if (update = '1' and update_reg = cop0reg_CAUSE) then - CAUSEinp <= newCAUSE(CAUSE_BD downto CAUSE_CE0) & - cop0_inp(CAUSE_DC) & cop0_inp(CAUSE_PCI) & b"00" & - cop0_inp(CAUSE_IV) & - newCAUSE(CAUSE_WP downto CAUSE_IP2) & - cop0_inp(CAUSE_IP1 downto CAUSE_IP0) & '0' & - newCAUSE(6 downto 2) & b"00"; - else - CAUSEinp <= newCAUSE; - end if; + + if STATUS(STATUS_EXL) = '0' then + newCAUSE(CAUSE_BD) := EX_is_delayslot; -- instr is in delay slot + else + newCAUSE(CAUSE_BD) := CAUSE(CAUSE_BD); + end if; + newCAUSE(CAUSE_TI) := count_eq_compare; + newCAUSE(CAUSE_CE1) := '0'; + newCAUSE(CAUSE_CE0) := '0'; + newCAUSE(CAUSE_DC) := CAUSE(CAUSE_DC); + newCAUSE(CAUSE_PCI) := '0'; + newCAUSE(25 downto 24) := b"00"; + newCAUSE(CAUSE_IV) := CAUSE(CAUSE_IV); + newCAUSE(CAUSE_WP) := '0'; + newCAUSE(21 downto 16) := b"000000"; + newCAUSE(CAUSE_IP7) := EX_int_req(7); + newCAUSE(CAUSE_IP6) := EX_int_req(6); + newCAUSE(CAUSE_IP5) := EX_int_req(5); + newCAUSE(CAUSE_IP4) := EX_int_req(4); + newCAUSE(CAUSE_IP3) := EX_int_req(3); + newCAUSE(CAUSE_IP2) := EX_int_req(2); + newCAUSE(CAUSE_IP1) := CAUSE(CAUSE_IP1); + newCAUSE(CAUSE_IP0) := CAUSE(CAUSE_IP0); + newCAUSE(7) := '0'; + newCAUSE(6 downto 2) := ExcCode; + newCAUSE(1 downto 0) := b"00"; + + if (update = '1' and update_reg = cop0reg_CAUSE) then + CAUSEinp <= newCAUSE(CAUSE_BD downto CAUSE_CE0) & + cop0_inp(CAUSE_DC) & cop0_inp(CAUSE_PCI) & b"00" & + cop0_inp(CAUSE_IV) & + newCAUSE(CAUSE_WP downto CAUSE_IP2) & + cop0_inp(CAUSE_IP1 downto CAUSE_IP0) & '0' & + newCAUSE(6 downto 2) & b"00"; + else + CAUSEinp <= newCAUSE; + end if; end process COP0_COMPUTE_CAUSE; COP0_CAUSE_HOLD: process(rst,clk, @@ -1925,8 +1996,8 @@ begin else '1'; COP0_COUNT: counter32 generic map (x"00000001") - -- port map (clk, rst, count_update, count_enable, cop0_inp, COUNT); - port map (clk, rst, count_update, PCload, cop0_inp, COUNT); -- DEBUG + port map (clk, rst, count_update, count_enable, cop0_inp, COUNT); + -- port map (clk, rst, count_update, PCload, cop0_inp, COUNT); -- DEBUG compare_set <= (count_eq_compare or BOOL2SL(COUNT = COMPARE)) when compare_update = '1' @@ -1949,7 +2020,7 @@ begin COP0_BadVAddr: register32 generic map(x"00000000") port map (clk, rst, BadVAddr_update, BadVAddr_inp, BadVAddr); - + -- LLaddr & LLbit ------------------------------ LL_update <= '0' when (update = '1' and update_reg = cop0reg_LLAddr) else '1'; @@ -1963,23 +2034,324 @@ begin '0'; COP0_LLbit: process(rst,phi2) - begin - if rst = '0' then - EX_LLbit <= '0'; -- break SC -> LL - elsif rising_edge(phi2) then - case is_exception is - when exERET => - EX_LLbit <= '0'; -- break SC -> LL - when exLL => - EX_LLbit <= not LL_update; -- update only if instr is a LL - when others => - null; -- LL_SC_abort <= '0'; - end case; + begin + if rst = '0' then + EX_LLbit <= '0'; -- break SC -> LL + elsif rising_edge(phi2) then + case is_exception is + when exERET => + EX_LLbit <= '0'; -- break SC -> LL + when exLL => + EX_LLbit <= not LL_update; -- update only if instr is a LL + when others => + null; + end case; + end if; + end process COP0_LLbit; + + EX_excp_type <= exNOP; + + + -- MMU-TLB =========================================================== + + -- MMU Index ----------------------------------- + + index_update <= '0' when (update = '1' and update_reg = cop0reg_Index) + else not(tlb_probe); + + index_inp <= not(hit_mm) & MMU_IDX_0s & tlb_adr_mm when tlb_probe = '1' else + '0' & MMU_IDX_0s & cop0_inp(MMU_CAPACITY_BITS-1 downto 0); + + MMU_Index: register32 generic map(x"00000000") + port map (clk, rst, index_update, index_inp, INDEX); + + + -- MMU Wired ----------------------------------- + + wired_update <= '0' when (update = '1' and update_reg = cop0reg_Wired) + else '1'; + + wired_inp <= '0' & MMU_IDX_0s & cop0_inp(MMU_CAPACITY_BITS-1 downto 0); + + MMU_Wired: register32 generic map(MMU_WIRED_INIT) + port map (clk, rst, wired_update, wired_inp, WIRED); + + -- MMU Random ---------------------------------- + + MMU_Random: process(clk, rst, WIRED, wired_update) + variable count : integer range -1 to MMU_CAPACITY-1; + begin + if rst = '0' or wired_update = '0' then + count := MMU_CAPACITY - 1 ; + elsif rising_edge(clk) then + count := count - 1; + if count = to_integer(unsigned(WIRED))-1 then + count := MMU_CAPACITY - 1; end if; - end process COP0_LLbit; - - EX_excp_type <= exNOP; - + end if; + RANDOM <= std_logic_vector(to_signed(count, 32)); + end process MMU_Random; + + -- MMU EntryLo0 -- pg 63 ---------------------- + + entryLo0_update <= '0' when (update = '1' and update_reg = cop0reg_EntryLo0) + else not(tlb_read); + + entryLo0_inp <= cop0_inp when tlb_read = '0' else tlb_entryLo0; + + MMU_EntryLo0: register32 generic map(x"00000000") + port map (clk, rst, entryLo0_update, entryLo0_inp, EntryLo0); + + -- MMU EntryLo1 -- pg 63 ---------------------- + + entryLo1_update <= '0' when (update = '1' and update_reg = cop0reg_EntryLo1) + else not(tlb_read); + + entryLo1_inp <= cop0_inp when tlb_read = '0' else tlb_entryLo1; + + MMU_EntryLo1: register32 generic map(x"00000000") + port map (clk, rst, entryLo1_update, entryLo1_inp, EntryLo1); + + -- MMU Context -- pg 67 ---------------------- + + context_update <= '0' when (update = '1' and update_reg = cop0reg_Context) + else '1'; + + context_inp <= cop0_inp when tlb_read = '0' else tlb_context_mm; + + MMU_Context: register32 generic map(x"00000000") + port map (clk, rst, context_update, context_inp, Context); + + -- MMU Pagemask ----------------------------- + -- page size is fixed = 4k, thus PageMask is not register + + -- pageMask_update <= '0' when (update='1' and update_reg=cop0reg_PageMask) + -- else '1'; + + -- pageMask_inp <= cop0_inp when tlb_read = '0' else tlb_pageMask_mm; + + -- MMU_PageMask: register32 generic map(x"00000000") + -- port map (clk, rst, pageMask_update, pageMask_inp, PageMask); + + PageMask <= x"00001800"; -- pg 68 + + -- MMU EntryHi -- pg 76 ---------------------- + -- EntryHi holds the ASID of the current process, to check for a match + + entryHi_update <= '0' when (update = '1' and update_reg = cop0reg_EntryHi) + else not(tlb_read); + + entryHi_inp <= cop0_inp when tlb_read = '0' else tlb_entryhi; + + MMU_EntryHi: register32 generic map(x"00000000") + port map (clk, rst, entryHi_update, entryHi_inp, EntryHi); + + + -- MMU TLB DATA array ------------------------ + + -- TLB_tag: 31..10 = VPN, 9 = 0, 8 = G, 7..0 = ASID + -- TLB_dat: 27..6 = PPN, 5..3 = C, 2 = D, 1 = V, 0 = G + + MMU_CONTROL: process(rst, clk, EX_exception, hit_mm, tlb_adr_mm, + INDEX, RANDOM, EntryHi, EntryLo0, -- EntryLo1, + tlb_tag0, tlb_tag1, tlb_tag2, tlb_tag3) + variable e_hi : reg32; + variable e_lo : reg28; + begin + + tlb_tag0_updt <= '1'; + tlb_tag1_updt <= '1'; + tlb_tag2_updt <= '1'; + tlb_tag3_updt <= '1'; + tlb_dat0_updt <= '1'; + tlb_dat1_updt <= '1'; + tlb_dat2_updt <= '1'; + tlb_dat3_updt <= '1'; + tlb_read <= '0'; + tlb_probe <= '0'; + + case EX_exception is + when exTLBP => + + tlb_probe <= '1'; + + when exTLBR => + + tlb_read <= '1'; + tlb_adr <= to_integer(unsigned(INDEX)); + + case tlb_adr is + when 0 => e_hi := tlb_tag0; e_lo := tlb_dat0; + when 1 => e_hi := tlb_tag1; e_lo := tlb_dat1; + when 2 => e_hi := tlb_tag2; e_lo := tlb_dat2; + when 3 => e_hi := tlb_tag3; e_lo := tlb_dat3; + when others => null; + end case; + + -- assert false + -- report "e_hi="&SLV32HEX(e_hi)&" adr="&natural'image(tlb_adr);--DEBUG + + tlb_entryLo0(31 downto ELO_AHI_BIT+1) <= (others => '0'); + tlb_entryLo0(ELO_AHI_BIT downto ELO_ALO_BIT) + <= e_lo(DAT_AHI_BIT downto DAT_ALO_BIT); + tlb_entryLo0(ELO_CHI_BIT downto ELO_CLO_BIT) + <= e_lo(DAT_CHI_BIT downto DAT_CLO_BIT); + tlb_entryLo0(ELO_D_BIT) <= e_lo(DAT_D_BIT); + tlb_entryLo0(ELO_V_BIT) <= e_lo(DAT_V_BIT); + tlb_entryLo0(ELO_G_BIT) <= e_lo(DAT_G_BIT); + + tlb_entryhi(EHI_AHI_BIT downto EHI_ALO_BIT) + <= e_hi(TAG_AHI_BIT downto TAG_ALO_BIT); + tlb_entryhi(EHI_ALO_BIT-1 downto EHI_ASIDHI_BIT+1) <= (others => '0'); + tlb_entryhi(EHI_ASIDHI_BIT downto EHI_ASIDLO_BIT) + <= e_hi(TAG_ASIDHI_BIT downto TAG_ASIDLO_BIT); + + when exTLBWI | exTLBWR => + + e_hi := EntryHi; + e_hi(TAG_G_BIT) := EntryLo0(ELO_G_BIT); + e_hi(TAG_Z_BIT) := '0'; + tlb_tag_inp <= e_hi; + + e_lo := EntryLo0(ELO_AHI_BIT downto ELO_G_BIT); + tlb_dat_inp <= e_lo; + + + case EX_exception is + when exTLBWI => tlb_adr <= to_integer(unsigned(INDEX)); + when exTLBWR => tlb_adr <= to_integer(unsigned(RANDOM)); + when others => null; + end case; + + case tlb_adr is + when 0 => tlb_tag0_updt <= '0'; tlb_dat0_updt <= '0'; + when 1 => tlb_tag1_updt <= '0'; tlb_dat1_updt <= '0'; + when 2 => tlb_tag2_updt <= '0'; tlb_dat2_updt <= '0'; + when 3 => tlb_tag3_updt <= '0'; tlb_dat3_updt <= '0'; + when others => null; + end case; + + when others => null; + + end case; + + end process MMU_CONTROL; + + + -- MMU TLB TAG array ------------------------- + + mm <= entryHi(VABITS-1 downto PAGE_SZ_BITS) when tlb_probe = '1' else + MM_result(VABITS-1 downto PAGE_SZ_BITS); + + MMU_TAG0: register32 generic map(x"00000000") + port map (clk, rst, tlb_tag0_updt, tlb_tag_inp, tlb_tag0); + + hit0_pc <= BOOL2SL( + tlb_tag0(VA_HI_BIT downto VA_LO_BIT) = PC(VA_HI_BIT downto VA_LO_BIT) AND + tlb_tag0(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0)); + + hit0_mm <= BOOL2SL( + tlb_tag0(VA_HI_BIT downto VA_LO_BIT) = mm(VA_HI_BIT downto VA_LO_BIT) AND + tlb_tag0(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0)); + + MMU_DAT0: register28 generic map(x"0000012") -- PPN=0, v=1 + port map (clk, rst, tlb_dat0_updt, tlb_dat_inp, tlb_dat0); + + + + MMU_TAG1: register32 generic map(x"00000400") + port map (clk, rst, tlb_tag1_updt, tlb_tag_inp, tlb_tag1); + + hit1_pc <= BOOL2SL( + tlb_tag1(VA_HI_BIT downto VA_LO_BIT) = PC(VA_HI_BIT downto VA_LO_BIT) AND + tlb_tag1(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0)); + + hit1_mm <= BOOL2SL( + tlb_tag1(VA_HI_BIT downto VA_LO_BIT) = mm(VA_HI_BIT downto VA_LO_BIT) AND + tlb_tag1(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0)); + + MMU_DAT1: register28 generic map(x"0000052") -- PPN=1, v=1 + port map (clk, rst, tlb_dat1_updt, tlb_dat_inp, tlb_dat1); + + + MMU_TAG2: register32 generic map(x"00000800") + port map (clk, rst, tlb_tag2_updt, tlb_tag_inp, tlb_tag2); + + hit2_pc <= BOOL2SL( + tlb_tag2(VA_HI_BIT downto VA_LO_BIT) = PC(VA_HI_BIT downto VA_LO_BIT) AND + tlb_tag2(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0)); + + hit2_mm <= BOOL2SL( + tlb_tag2(VA_HI_BIT downto VA_LO_BIT) = mm(VA_HI_BIT downto VA_LO_BIT) AND + tlb_tag2(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0)); + + MMU_DAT2: register28 generic map(x"0000092") -- PPN=2, v=1 + port map (clk, rst, tlb_dat2_updt, tlb_dat_inp, tlb_dat2); + + + MMU_TAG3: register32 generic map(x"00000c00") + port map (clk, rst, tlb_tag3_updt, tlb_tag_inp, tlb_tag3); + + hit3_pc <= BOOL2SL( + tlb_tag3(VA_HI_BIT downto VA_LO_BIT) = PC(VA_HI_BIT downto VA_LO_BIT) AND + tlb_tag3(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0)); + + hit3_mm <= BOOL2SL( + tlb_tag3(VA_HI_BIT downto VA_LO_BIT) = mm(VA_HI_BIT downto VA_LO_BIT) AND + tlb_tag3(ASID_HI_BIT downto 0) = EntryHi(ASID_HI_BIT downto 0)); + + MMU_DAT3: register28 generic map(x"00000d2") -- PPN=3, v=1 + port map (clk, rst, tlb_dat3_updt, tlb_dat_inp, tlb_dat3); + + + + tlb_a2_pc <= '0'; + tlb_a1_pc <= hit2_pc or hit3_pc; + tlb_a0_pc <= hit1_pc or hit3_pc; + + hit_pc <= hit0_pc or hit1_pc or hit2_pc or hit3_pc; + tlb_adr_pc <= tlb_a1_pc & tlb_a0_pc; -- tlb_a2_pc & + + tlb_ppn <= tlb_dat0(DAT_AHI_BIT downto DAT_ALO_BIT) when hit0_pc = '1' + else (others => 'Z'); + tlb_ppn <= tlb_dat1(DAT_AHI_BIT downto DAT_ALO_BIT) when hit1_pc = '1' + else (others => 'Z'); + tlb_ppn <= tlb_dat2(DAT_AHI_BIT downto DAT_ALO_BIT) when hit2_pc = '1' + else (others => 'Z'); + tlb_ppn <= tlb_dat3(DAT_AHI_BIT downto DAT_ALO_BIT) when hit2_pc = '1' + else (others => 'Z'); + + +-- with "00" select -- tlb_adr_pc select +-- tlb_ppn <= tlb_dat0(DAT_AHI_BIT downto DAT_ALO_BIT) when "00", +-- tlb_dat1(DAT_AHI_BIT downto DAT_ALO_BIT) when "01", +-- tlb_dat2(DAT_AHI_BIT downto DAT_ALO_BIT) when "10", +-- tlb_dat3(DAT_AHI_BIT downto DAT_ALO_BIT) when "11", +-- (others => 'X') when others; + + phy_i_addr <= tlb_ppn(21 downto 0) & PC(VA_LO_BIT-1 downto 0); + + assert false report LF& " dathi "&integer'image(DAT_AHI_BIT) & + " datlo "&integer'image(DAT_ALO_BIT) & + " valo " &integer'image(VA_LO_BIT) & + " ppn_b "&integer'image(PPN_BITS) & + " dathl "&integer'image(DAT_AHI_BIT - DAT_ALO_BIT) & + " ppn_bits " &integer'image(PPN_BITS)& + " 2bits " &integer'image(to_integer(signed(tlb_ppn(1 downto 0))))& + LF & " elohi "&integer'image(ELO_AHI_BIT)& + " elolo "&integer'image(ELO_ALO_BIT); + + + tlb_a2_mm <= '0'; + tlb_a1_mm <= hit2_mm or hit3_mm; + tlb_a0_mm <= hit1_mm or hit3_mm; + + hit_mm <= hit0_mm or hit1_mm or hit2_mm or hit3_mm; + tlb_adr_mm <= tlb_a1_mm & tlb_a0_mm; -- tlb_a2_mm & + + -- MMU-TLB == end ======================================================= + + -- ---------------------------------------------------------------------- PIPESTAGE_EXCP_EX_MM: reg_excp_EX_MM port map (clk, rst, excp_EX_MM_ld, EX_can_trap,MM_can_trap, diff --git a/cMIPS/vhdl/packageExcp.vhd b/cMIPS/vhdl/packageExcp.vhd index cca34ff70c9fbf9db12284ce90d8384431221b52..2b7c02cb10f909f7e0e10d1a1156816907752063 100644 --- a/cMIPS/vhdl/packageExcp.vhd +++ b/cMIPS/vhdl/packageExcp.vhd @@ -29,21 +29,33 @@ package p_EXCEPTION is exBREAK, exTRAP, exSYSCALL, -- 8 exRESV_INSTR, exWAIT, -- 10 IFaddressError, MMaddressErrorLD, MMaddressErrorST, - exTLBld, exTLBst, exTLBmod, --16 - exOvfl, -- 17 - exLL,exSC, -- 18,19 these are treated by COP0 + exTLBrefill, exTLBld, exTLBst, exTLBmod, -- 17 + exOvfl, -- 18 + exLL,exSC, -- 19,20 these are handled by COP0 + exEHB, -- 21 + exTLBP, exTLBR, exTLBWI, exTLBWR, -- 25 + exDERET, -- 26 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"; + "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"; --- 010101 010110 010111 011000 011001 011010 011011 011100 011101 011110 011111 100000 100001 100010"; +-- 011100 011101 011110 011111 100000 100001 100010"; -- Table 8-1 Coprocessor 0 Registers, pg 55 + constant cop0reg_Index : reg5 := b"00000"; -- 0 + constant cop0reg_Random : reg5 := b"00001"; -- 1 + constant cop0reg_EntryLo0 : reg5 := b"00010"; -- 2 + constant cop0reg_EntryLo1 : reg5 := b"00011"; -- 3 + constant cop0reg_Context : reg5 := b"00100"; -- 4 + constant cop0reg_PageMask : reg5 := b"00101"; -- 5 + constant cop0reg_Wired : reg5 := b"00110"; -- 6 + constant cop0reg_HWREna : reg5 := b"00111"; -- 7 constant cop0reg_BadVAddr : reg5 := b"01000"; -- 8 constant cop0reg_COUNT : reg5 := b"01001"; -- 9 + constant cop0reg_EntryHi : reg5 := b"01010"; -- 10 constant cop0reg_COMPARE : reg5 := b"01011"; -- 11 constant cop0reg_STATUS : reg5 := b"01100"; -- 12 constant cop0reg_CAUSE : reg5 := b"01101"; -- 13 @@ -70,10 +82,10 @@ package p_EXCEPTION is constant cop0code_NULL : reg5 := b"11111"; -- 1f, (no exception)=x3c - -- kernel mode, all else disabled + -- at exception level, kernel mode, cop0, all else disabled constant RESET_STATUS: std_logic_vector(31 downto 0) := x"10000002"; - -- COUNTER disabled, kernel mode, exceptionCode = noException + -- COUNTER disabled, special interr vector, exceptionCode = noException constant RESET_CAUSE: std_logic_vector(31 downto 0) := x"0880007c"; diff --git a/cMIPS/vhdl/packageMemory.vhd b/cMIPS/vhdl/packageMemory.vhd index b1ad89a0d896fac82077f11dac4f384b3701192c..a1ac9efbd4718cfff8fed2ba2ca3758386965f85 100644 --- a/cMIPS/vhdl/packageMemory.vhd +++ b/cMIPS/vhdl/packageMemory.vhd @@ -23,19 +23,23 @@ use work.p_wires.all; package p_MEMORY is -- To simplify (and accelerate) the RAM address decoding, - -- the BASE of the RAM addresses MUST be allocated at an - -- address that is above/larger the RAM capacity. Otherwise, the - -- base must be subtracted from the address on every reference, - -- which means having an adder in the critical path. Bad idea. + -- the BASE of the RAM addresses MUST be allocated at an + -- address that is above/larger the the RAM capacity. Otherwise, + -- the base must be subtracted from the address on every reference, + -- which means having an adder in the critical path. Not good. -- The address ranges for ROM, RAM and I/O must be distinct in the - -- uppermost 12 bits of the address (bits 31..20). + -- uppermost 12 bits of the address (bits 31..20). constant HI_SEL_BITS : integer := 31; constant LO_SEL_BITS : integer := 20; + - -- x_IO_ADDR_RANGE can have only ONE bit set, thus being a power of 2 + -- x_IO_ADDR_RANGE can have only ONE bit set, thus being a power of 2. + -- ACHTUNG: changing the above number may break some of the test programs. + -- begin DO NOT change these names as several scripts depend on them -- + -- you may change the values, not names nor formatting -- constant x_INST_BASE_ADDR : reg32 := x"00000000"; constant x_INST_MEM_SZ : reg32 := x"00002000"; constant x_DATA_BASE_ADDR : reg32 := x"00400000"; @@ -61,7 +65,7 @@ package p_MEMORY is constant IO_ADDR_MASK : integer := (0 - IO_ADDR_RANGE); constant x_IO_ADDR_MASK : reg32 := std_logic_vector(to_signed(0 - IO_ADDR_RANGE, 32)); - -- maximum number of IO devices, must be power of two. + -- maximum number of IO devices, must be a power of two. constant IO_MAX_NUM_DEVS : integer := 16; -- I/O addresses are IO_ADDR_RANGE apart @@ -80,6 +84,7 @@ package p_MEMORY is constant IO_HIGHEST_ADDR : integer := IO_BASE_ADDR + (IO_MAX_NUM_DEVS - 1)*IO_ADDR_RANGE; + -- DATA CACHE parameters ---------------------------------------------- -- The combination of capacity, associativity and block/line size @@ -96,7 +101,7 @@ package p_MEMORY is constant DC_WORD_SEL_BITS : natural := log2_ceil( DC_WORDS_PER_BLOCK ); constant DC_BYTE_SEL_BITS : natural := log2_ceil( DC_BYTES_PER_WORD ); - -- constants for CONFIG1 cop0 register + -- constants for CONFIG1 cop0 register (Table 8-24 pg 103) constant DC_SETS_PER_WAY: reg3 := std_logic_vector(to_signed(DC_INDEX_BITS - 6, 3)); constant DC_LINE_SIZE: reg3 := @@ -104,6 +109,7 @@ package p_MEMORY is constant DC_ASSOCIATIVITY: reg3 := std_logic_vector(to_signed(DC_NUM_WAYS - 1, 3)); + -- INSTRUCTION CACHE parameters --------------------------------------- -- The combination of capacity, associativity and block/line size @@ -120,7 +126,7 @@ package p_MEMORY is constant IC_WORD_SEL_BITS : natural := log2_ceil( IC_WORDS_PER_BLOCK ); constant IC_BYTE_SEL_BITS : natural := log2_ceil( IC_BYTES_PER_WORD ); - -- constants for CONFIG1 cop0 register + -- constants for CONFIG1 cop0 register (Table 8-24 pg 103) constant IC_SETS_PER_WAY: reg3 := std_logic_vector(to_signed(IC_INDEX_BITS - 6, 3)); constant IC_LINE_SIZE: reg3 := @@ -128,13 +134,73 @@ package p_MEMORY is constant IC_ASSOCIATIVITY: reg3 := std_logic_vector(to_signed(IC_NUM_WAYS - 1, 3)); - -- constants to access statistics counter + -- constants to access the cache statistics counters constant dcache_Stats_ref : reg3 := "000"; constant dcache_Stats_rdhit : reg3 := "001"; constant dcache_Stats_wrhit : reg3 := "010"; constant dcache_Stats_flush : reg3 := "011"; constant icache_Stats_ref : reg3 := "100"; constant icache_Stats_hit : reg3 := "101"; + + + -- MMU parameters ----------------------------------------------------- + + -- constants for CONFIG1 cop0 register (Table 8-24 pg 103) + constant MMU_CAPACITY : natural := 4; + constant MMU_CAPACITY_BITS : natural := log2_ceil( MMU_CAPACITY ); + constant MMU_SIZE: reg6 := + std_logic_vector(to_signed( (MMU_CAPACITY-1), 6) ); + constant MMU_WIRED_INIT : reg32 := x"00000000"; + + constant VABITS : natural := 32; + constant PABITS : natural := 32; + constant PAGE_SZ : natural := 1024; -- 1k pages + constant PAGE_SZ_BITS : natural := log2_ceil( PAGE_SZ ); + + constant PPN_BITS : natural := PABITS - PAGE_SZ_BITS; + constant VA_HI_BIT : natural := 31; -- VAaddr in EntryHi 31..PG_size + constant VA_LO_BIT : natural := PAGE_SZ_BITS; + + constant ASID_HI_BIT : natural := 7; -- ASID in EntryHi 7..0 + constant ASID_LO_BIT : natural := 0; + + constant EHI_ASIDLO_BIT : natural := 0; + constant EHI_ASIDHI_BIT : natural := 7; + constant EHI_ALO_BIT : natural := PAGE_SZ_BITS; + constant EHI_AHI_BIT : natural := EHI_ALO_BIT + PPN_BITS - 1; + + constant ELO_G_BIT : natural := 0; + constant ELO_V_BIT : natural := 1; + constant ELO_D_BIT : natural := 2; + constant ELO_CLO_BIT : natural := 3; + constant ELO_CHI_BIT : natural := 5; + constant ELO_ALO_BIT : natural := 6; + constant ELO_AHI_BIT : natural := ELO_ALO_BIT + PPN_BITS - 1; + + constant TAG_ASIDLO_BIT : natural := 0; + constant TAG_ASIDHI_BIT : natural := 7; + constant TAG_G_BIT : natural := 8; + constant TAG_Z_BIT : natural := 9; + constant TAG_AHI_BIT : natural := 31; + constant TAG_ALO_BIT : natural := TAG_AHI_BIT - PPN_BITS + 1; + + constant DAT_G_BIT : natural := 0; + constant DAT_V_BIT : natural := 1; + constant DAT_D_BIT : natural := 2; + constant DAT_CLO_BIT : natural := 3; + constant DAT_CHI_BIT : natural := 5; + constant DAT_ALO_BIT : natural := 6; + constant DAT_AHI_BIT : natural := DAT_ALO_BIT + PPN_BITS - 1; + + + subtype MMU_idx_bits is std_logic_vector(MMU_CAPACITY_BITS-1 downto 0); + constant MMU_idx_0s : std_logic_vector(30 downto MMU_CAPACITY_BITS) := + (others => '0'); + constant MMU_IDX_BIT : natural := 31; -- probe hit=1, miss=0 + + constant mmu_PageMask : reg32 := x"00000000"; -- pg 68, 1k pages only + -- constant mmu_PageMask : reg32 := x"00001800"; -- pg 68, 4k pages only + end p_MEMORY;