Line 26... |
Line 26... |
`define IRQ_VECTOR 64'hFFFF_FFFF_FFFF_FFD0
|
`define IRQ_VECTOR 64'hFFFF_FFFF_FFFF_FFD0
|
`define TRAP_VECTOR 64'h0000_0000_0000_0000
|
`define TRAP_VECTOR 64'h0000_0000_0000_0000
|
|
|
`define TLBMissPage 52'hFFFF_FFFF_FFFF_F
|
`define TLBMissPage 52'hFFFF_FFFF_FFFF_F
|
`define ITLB_MissHandler 64'hFFFF_FFFF_FFFF_FFC0
|
`define ITLB_MissHandler 64'hFFFF_FFFF_FFFF_FFC0
|
|
`define DTLB_MissHandler 64'hFFFF_FFFF_FFFF_FFB0
|
|
|
|
`define GEN_TRAP_OFFSET 13'h0200
|
|
`define DBZ_TRAP_OFFSET 13'h0050
|
|
`define OFL_TRAP_OFFSET 13'h0070
|
|
|
`define EX_NON 8'd0
|
`define EX_NON 8'd0
|
`define EX_RST 8'd1
|
`define EX_RST 8'd1
|
`define EX_NMI 8'd2
|
`define EX_NMI 8'd2
|
`define EX_IRQ 8'd3
|
`define EX_IRQ 8'd3
|
|
`define EX_TRAP 8'd4
|
`define EX_OFL 8'd16 // overflow
|
`define EX_OFL 8'd16 // overflow
|
`define EX_DBZ 8'd17 // divide by zero
|
`define EX_DBZ 8'd17 // divide by zero
|
`define EX_TLBI 8'd19 // TLB exception - ifetch
|
`define EX_TLBI 8'd19 // TLB exception - ifetch
|
|
`define EX_TLBD 8'd20 // TLB exception - data
|
|
|
`define EXCEPT_Int 5'd00
|
`define EXCEPT_Int 5'd00
|
`define EXCEPT_Mod 5'd01 // TLB modification
|
`define EXCEPT_Mod 5'd01 // TLB modification
|
`define EXCEPT_TLBL 5'd02 // TLB exception - load or ifetch
|
`define EXCEPT_TLBL 5'd02 // TLB exception - load or ifetch
|
`define EXCEPT_TLBS 5'd03 // TLB exception - store
|
`define EXCEPT_TLBS 5'd03 // TLB exception - store
|
Line 58... |
Line 65... |
|
|
|
|
`define MISC 7'd0
|
`define MISC 7'd0
|
`define BRK 7'd0
|
`define BRK 7'd0
|
`define IRQ 7'd1
|
`define IRQ 7'd1
|
|
`define FIP 7'd20
|
`define IRET 7'd32
|
`define IRET 7'd32
|
|
`define ERET 7'd33
|
`define WAIT 7'd40
|
`define WAIT 7'd40
|
`define TLBR 7'd50
|
`define TLBR 7'd50
|
`define TLBWI 7'd51
|
`define TLBWI 7'd51
|
`define TLBWR 7'd52
|
`define TLBWR 7'd52
|
`define CLI 7'd64
|
`define CLI 7'd64
|
Line 82... |
Line 91... |
`define SQRT 7'd24
|
`define SQRT 7'd24
|
`define REDOR 7'd30
|
`define REDOR 7'd30
|
`define REDAND 7'd31
|
`define REDAND 7'd31
|
`define MFSPR 7'd40
|
`define MFSPR 7'd40
|
`define MTSPR 7'd41
|
`define MTSPR 7'd41
|
`define TLBIndex 5'd01
|
`define TLBIndex 6'd01
|
`define TLBRandom 5'd02
|
`define TLBRandom 6'd02
|
`define PageTableAddr 5'd04
|
`define PageTableAddr 6'd04
|
`define BadVAddr 5'd08
|
`define BadVAddr 6'd08
|
`define TLBPhysPage 5'd10
|
`define TLBPhysPage 6'd10
|
`define TLBVirtPage 5'd11
|
`define TLBVirtPage 6'd11
|
`define TLBPageMask 5'd12
|
`define TLBPageMask 6'd12
|
`define TLBASID 5'd13
|
`define TLBASID 6'd13
|
`define ASID 5'd14
|
`define ASID 6'd14
|
`define Wired 5'd15
|
`define Wired 6'd15
|
`define EP0 5'd16
|
`define EP0 6'd16
|
`define EP1 5'd17
|
`define EP1 6'd17
|
`define EP2 5'd18
|
`define EP2 6'd18
|
`define EP3 5'd19
|
`define EP3 6'd19
|
`define AXC 5'd20
|
`define AXC 6'd20
|
`define MFTICK 7'd56
|
`define Tick 6'd21
|
`define MFEPC 7'd57
|
`define EPC 6'd22
|
|
`define CauseCode 6'd23
|
|
`define TBA 6'd24
|
|
`define OMG 7'd50
|
|
`define CMG 7'd51
|
|
`define OMGI 7'd52
|
|
`define CMGI 7'd53
|
`define MFTBA 7'd58
|
`define MFTBA 7'd58
|
`define MTTBA 7'd59
|
`define MTTBA 7'd59
|
`define MTREGSET 7'd60
|
|
`define MFREGSET 7'd61
|
|
`define RR 7'd2
|
`define RR 7'd2
|
`define ADD 7'd4
|
`define ADD 7'd2
|
`define SUB 7'd5
|
`define ADDU 7'd3
|
|
`define SUB 7'd4
|
|
`define SUBU 7'd5
|
`define CMP 7'd6
|
`define CMP 7'd6
|
`define CMPU 7'd7
|
`define CMPU 7'd7
|
`define AND 7'd8
|
`define AND 7'd8
|
`define OR 7'd9
|
`define OR 7'd9
|
`define XOR 7'd10
|
`define XOR 7'd10
|
Line 126... |
Line 141... |
`define DIVS 7'd27
|
`define DIVS 7'd27
|
`define MOD 7'd28
|
`define MOD 7'd28
|
`define MOVZ 7'd30
|
`define MOVZ 7'd30
|
`define MOVNZ 7'd31
|
`define MOVNZ 7'd31
|
|
|
`define ASL 7'd40
|
`define SHL 7'd40
|
`define LSR 7'd41
|
`define SHRU 7'd41
|
`define ROL 7'd42
|
`define ROL 7'd42
|
`define ROR 7'd43
|
`define ROR 7'd43
|
`define ASR 7'd44
|
`define SHR 7'd44
|
`define ROLAM 7'd45
|
`define ROLAM 7'd45
|
|
|
`define NOP 7'd60
|
`define NOP 7'd60
|
|
|
`define BLT 7'd80
|
|
`define BGE 7'd81
|
|
`define BLE 7'd82
|
|
`define BGT 7'd83
|
|
`define BLTU 7'd84
|
|
`define BGEU 7'd85
|
|
`define BLEU 7'd86
|
|
`define BGTU 7'd87
|
|
`define BEQ 7'd88
|
|
`define BNE 7'd89
|
|
`define BRA 7'd90
|
|
`define BRN 7'd91
|
|
`define BAND 7'd92
|
|
`define BOR 7'd93
|
|
|
|
`define SLT 7'd96
|
`define SLT 7'd96
|
`define SLE 7'd97
|
`define SLE 7'd97
|
`define SGT 7'd98
|
`define SGT 7'd98
|
`define SGE 7'd99
|
`define SGE 7'd99
|
`define SLTU 7'd100
|
`define SLTU 7'd100
|
Line 165... |
Line 165... |
|
|
`define BCD_ADD 7'd110
|
`define BCD_ADD 7'd110
|
`define BCD_SUB 7'd111
|
`define BCD_SUB 7'd111
|
|
|
`define SHFTI 7'd3
|
`define SHFTI 7'd3
|
`define ASLI 7'd0
|
`define SHLI 7'd0
|
`define LSRI 7'd1
|
`define SHRUI 7'd1
|
`define ROLI 7'd2
|
`define ROLI 7'd2
|
`define ASRI 7'd3
|
`define SHRI 7'd3
|
`define RORI 7'd4
|
`define RORI 7'd4
|
`define ROLAMI 7'd5
|
`define ROLAMI 7'd5
|
`define BFINS 7'd8
|
`define BFINS 7'd8
|
`define BFSET 7'd9
|
`define BFSET 7'd9
|
`define BFCLR 7'd10
|
`define BFCLR 7'd10
|
`define BFCHG 7'd11
|
`define BFCHG 7'd11
|
|
|
`define ADDI 7'd4
|
`define ADDI 7'd4
|
`define SUBI 7'd5
|
`define ADDUI 7'd5
|
`define CMPI 7'd6
|
`define SUBI 7'd6
|
`define CMPUI 7'd7
|
`define CMPI 7'd7
|
`define ANDI 7'd8
|
`define CMPUI 7'd8
|
`define ORI 7'd9
|
`define ANDI 7'd9
|
`define XORI 7'd10
|
`define ORI 7'd10
|
|
`define XORI 7'd11
|
|
|
`define MULUI 7'd12
|
`define MULUI 7'd12
|
`define MULSI 7'd13
|
`define MULSI 7'd13
|
`define DIVUI 7'd14
|
`define DIVUI 7'd14
|
`define DIVSI 7'd15
|
`define DIVSI 7'd15
|
|
|
`define BRr 7'd16
|
|
`define BEQZ 5'd0
|
|
`define BNEZ 5'd1
|
|
`define BLTZ 5'd2
|
|
`define BLEZ 5'd3
|
|
`define BGTZ 5'd4
|
|
`define BGEZ 5'd5
|
|
`define BRAZ 5'd6
|
|
`define BNR 5'd7
|
|
`define BEQZD 5'd8
|
|
`define BNEZD 5'd9
|
|
`define BLTZD 5'd10
|
|
`define BLEZD 5'd11
|
|
`define BGTZD 5'd12
|
|
`define BGEZD 5'd13
|
|
`define BRAD 5'd14
|
|
`define BEQZR 5'd16
|
|
`define BNEZR 5'd17
|
|
`define BLTZR 5'd18
|
|
`define BLEZR 5'd19
|
|
`define BGTZR 5'd20
|
|
`define BGEZR 5'd21
|
|
`define BEQZRD 5'd24
|
|
`define BNEZRD 5'd25
|
|
`define BLTZRD 5'd26
|
|
`define BLEZRD 5'd27
|
|
`define BGTZRD 5'd28
|
|
`define BGEZRD 5'd29
|
|
`define TRAPcc 7'd17
|
`define TRAPcc 7'd17
|
`define TEQ 7'd0
|
`define TEQ 7'd0
|
`define TNE 7'd1
|
`define TNE 7'd1
|
`define TLT 7'd2
|
`define TLT 7'd2
|
`define TLE 7'd3
|
`define TLE 7'd3
|
Line 270... |
Line 243... |
`define SB 7'd48
|
`define SB 7'd48
|
`define SC 7'd49
|
`define SC 7'd49
|
`define SH 7'd50
|
`define SH 7'd50
|
`define SW 7'd51
|
`define SW 7'd51
|
`define SP 7'd52
|
`define SP 7'd52
|
|
`define MEMNDX 7'd53
|
`define SSH 7'd56
|
`define SSH 7'd56
|
`define SSW 7'd57
|
`define SSW 7'd57
|
`define SF 7'd58
|
`define SF 7'd58
|
`define SFD 7'd59
|
`define SFD 7'd59
|
`define SFP 7'd60
|
`define SFP 7'd60
|
Line 287... |
Line 261... |
`define OUTB 7'd72
|
`define OUTB 7'd72
|
`define OUTC 7'd73
|
`define OUTC 7'd73
|
`define OUTH 7'd74
|
`define OUTH 7'd74
|
`define OUTW 7'd75
|
`define OUTW 7'd75
|
|
|
`define BEQI 7'd80
|
`define BLTI 7'd80
|
`define BNEI 7'd81
|
`define BGEI 7'd81
|
`define BLTI 7'd82
|
`define BLEI 7'd82
|
`define BLEI 7'd83
|
`define BGTI 7'd83
|
`define BGTI 7'd84
|
`define BLTUI 7'd84
|
`define BGEI 7'd85
|
`define BGEUI 7'd85
|
`define BLTUI 7'd86
|
`define BLEUI 7'd86
|
`define BLEUI 7'd87
|
`define BGTUI 7'd87
|
`define BGTUI 7'd88
|
`define BEQI 7'd88
|
`define BGEUI 7'd89
|
`define BNEI 7'd89
|
`define BRAI 7'd90
|
`define BRAI 7'd90
|
`define BRNI 7'd91
|
`define BRNI 7'd91
|
|
|
|
`define BTRI 7'd94
|
|
`define BLTRI 5'd0
|
|
`define BGERI 5'd1
|
|
`define BLERI 5'd2
|
|
`define BGTRI 5'd3
|
|
`define BLTURI 5'd4
|
|
`define BGEURI 5'd5
|
|
`define BLEURI 5'd6
|
|
`define BGTURI 5'd7
|
|
`define BEQRI 5'd8
|
|
`define BNERI 5'd9
|
|
`define BRARI 5'd10
|
|
`define BRNRI 5'd11
|
|
`define BANDRI 5'd12
|
|
`define BORRI 5'd13
|
|
`define BTRR 7'd95
|
|
`define BLT 5'd0
|
|
`define BGE 5'd1
|
|
`define BLE 5'd2
|
|
`define BGT 5'd3
|
|
`define BLTU 5'd4
|
|
`define BGEU 5'd5
|
|
`define BLEU 5'd6
|
|
`define BGTU 5'd7
|
|
`define BEQ 5'd8
|
|
`define BNE 5'd9
|
|
`define BRA 5'd10
|
|
`define BRN 5'd11
|
|
`define BAND 5'd12
|
|
`define BOR 5'd13
|
|
`define BNR 5'd14
|
|
`define BLTR 5'd16
|
|
`define BGER 5'd17
|
|
`define BLER 5'd18
|
|
`define BGTR 5'd19
|
|
`define BLTUR 5'd20
|
|
`define BGEUR 5'd21
|
|
`define BLEUR 5'd22
|
|
`define BGTUR 5'd23
|
|
`define BEQR 5'd24
|
|
`define BNER 5'd25
|
|
`define BRAR 5'd26
|
|
`define BRNR 5'd27
|
|
|
|
|
`define SLTI 7'd96
|
`define SLTI 7'd96
|
`define SLEI 7'd97
|
`define SLEI 7'd97
|
`define SGTI 7'd98
|
`define SGTI 7'd98
|
`define SGEI 7'd99
|
`define SGEI 7'd99
|
Line 317... |
Line 335... |
`define FPLOO 7'd109
|
`define FPLOO 7'd109
|
`define FPZL 7'd110
|
`define FPZL 7'd110
|
`define NOPI 7'd111
|
`define NOPI 7'd111
|
|
|
`define IMM 3'd7
|
`define IMM 3'd7
|
|
`define SETLO 7'b11110xx
|
|
`define SETHI 7'b11111xx
|
|
|
`define NOP_INSN 42'b1101111_000_00000000_00000000_00000000_00000000
|
`define NOP_INSN 42'b1101111_000_00000000_00000000_00000000_00000000
|
|
|
module Raptor64(rst_i, clk_i, nmi_i, irq_i,
|
module Raptor64(rst_i, clk_i, nmi_i, irq_i,
|
bte_o, cti_o, cyc_o, stb_o, ack_i, we_o, sel_o, rsv_o, adr_o, dat_i, dat_o, sys_adv, sys_adr,
|
bte_o, cti_o, cyc_o, stb_o, ack_i, we_o, sel_o, rsv_o, adr_o, dat_i, dat_o, sys_adv, sys_adr,
|
Line 353... |
Line 373... |
|
|
input rst_i;
|
input rst_i;
|
input clk_i;
|
input clk_i;
|
input nmi_i;
|
input nmi_i;
|
input irq_i;
|
input irq_i;
|
|
|
output [1:0] bte_o;
|
output [1:0] bte_o;
|
reg [1:0] bte_o;
|
reg [1:0] bte_o;
|
output [2:0] cti_o;
|
output [2:0] cti_o;
|
reg [2:0] cti_o;
|
reg [2:0] cti_o;
|
output cyc_o;
|
output cyc_o;
|
Line 364... |
Line 385... |
output stb_o;
|
output stb_o;
|
reg stb_o;
|
reg stb_o;
|
input ack_i;
|
input ack_i;
|
output we_o;
|
output we_o;
|
reg we_o;
|
reg we_o;
|
output [7:0] sel_o;
|
output [3:0] sel_o;
|
reg [7:0] sel_o;
|
reg [3:0] sel_o;
|
output rsv_o;
|
output rsv_o;
|
reg rsv_o;
|
reg rsv_o;
|
output [63:0] adr_o;
|
output [31:0] adr_o;
|
reg [63:0] adr_o;
|
reg [31:0] adr_o;
|
input [31:0] dat_i;
|
input [31:0] dat_i;
|
output [31:0] dat_o;
|
output [31:0] dat_o;
|
reg [31:0] dat_o;
|
reg [31:0] dat_o;
|
|
|
input sys_adv;
|
input sys_adv;
|
input [63:5] sys_adr;
|
input [63:5] sys_adr;
|
|
|
output cmd_en;
|
output cmd_en;
|
reg cmd_en;
|
reg cmd_en;
|
Line 404... |
Line 426... |
reg im; // interrupt mask
|
reg im; // interrupt mask
|
reg [1:0] rm; // fp rounding mode
|
reg [1:0] rm; // fp rounding mode
|
reg [41:0] dIR;
|
reg [41:0] dIR;
|
reg [41:0] xIR;
|
reg [41:0] xIR;
|
reg [4:0] epcnt;
|
reg [4:0] epcnt;
|
reg [3:0] dAXC,AXC,xAXC;
|
reg [3:0] dAXC,AXC,xAXC,m1AXC;
|
reg [31:0] EP [3:0];
|
reg [31:0] EP [3:0];
|
reg [63:0] pc [15:0];
|
reg [63:0] pc [15:0];
|
|
reg [63:0] ErrorEPC,EPC[15:0];
|
wire [63:0] pc_axc = pc[AXC];
|
wire [63:0] pc_axc = pc[AXC];
|
reg [63:0] dpc,m1pc,m2pc,m3pc,m4pc,wpc;
|
reg [63:0] dpc,m1pc,m2pc,m3pc,m4pc,wpc;
|
reg [63:0] xpc;
|
reg [63:0] xpc;
|
reg [63:0] tlbra; // return address for a TLB exception
|
reg [63:0] tlbra; // return address for a TLB exception
|
reg [8:0] dRa,dRb;
|
reg [8:0] dRa,dRb,dRc;
|
reg [8:0] wRt,mRt,m1Rt,m2Rt,m3Rt,m4Rt,tRt,dRt;
|
reg [8:0] wRt,mRt,m1Rt,m2Rt,m3Rt,m4Rt,tRt,dRt;
|
reg [8:0] xRt;
|
reg [8:0] xRt;
|
reg [63:0] dImm;
|
reg [63:0] dImm;
|
reg [63:0] ea;
|
reg [63:0] ea;
|
reg [63:0] iadr_o;
|
reg [63:0] iadr_o;
|
reg [31:0] idat;
|
reg [31:0] idat;
|
reg [4:0] cstate;
|
reg [4:0] cstate;
|
reg dbranch_taken,xbranch_taken;
|
reg dbranch_taken,xbranch_taken;
|
|
reg [63:0] mutex_gate;
|
|
reg [63:0] TBA;
|
|
|
//reg wr_icache;
|
//reg wr_icache;
|
reg dccyc;
|
reg dccyc;
|
wire [63:0] cdat;
|
wire [63:0] cdat;
|
reg [63:0] wr_addr;
|
reg [63:0] wr_addr;
|
wire [41:0] insn;
|
wire [41:0] insn;
|
reg [3:0] regset;
|
reg [3:0] regset;
|
wire [63:0] rfoa,rfob;
|
wire [63:0] rfoa,rfob;
|
reg clk_en;
|
reg clk_en;
|
reg cpu_clk_en;
|
reg cpu_clk_en;
|
reg StatusEXL; // 1= in exception processing
|
reg [15:0] StatusERL; // 1= in error processing
|
reg StatusTLB; // 1= in TLB miss handling
|
reg [15:0] StatusEXL; // 1= in exception processing
|
|
reg [7:0] CauseCode[15:0];
|
reg [7:0] ASID; // address space identifier (process ID)
|
reg [7:0] ASID; // address space identifier (process ID)
|
integer n;
|
integer n;
|
reg [63:13] BadVAddr;
|
reg [63:13] BadVAddr [15:0];
|
reg [63:13] PageTableAddr;
|
reg [63:13] PageTableAddr;
|
reg [24:13] TLBPageMask;
|
reg [24:13] TLBPageMask;
|
reg [63:13] TLBVirtPage;
|
reg [63:13] TLBVirtPage;
|
reg [63:13] TLBPhysPage;
|
reg [63:13] TLBPhysPage;
|
reg [7:0] TLBASID;
|
reg [7:0] TLBASID;
|
|
reg TLBG;
|
reg [3:0] Index;
|
reg [3:0] Index;
|
reg [3:0] Random;
|
reg [3:0] Random;
|
reg [3:0] Wired;
|
reg [3:0] Wired;
|
reg [15:0] IMatch,DMatch;
|
reg [15:0] IMatch,DMatch;
|
|
|
|
function [63:0] fnIncPC;
|
|
input [63:0] fpc;
|
|
begin
|
|
case(fpc[3:2])
|
|
2'd0: fnIncPC = {fpc[63:4],4'b0100};
|
|
2'd1: fnIncPC = {fpc[63:4],4'b1000};
|
|
2'd2: fnIncPC = {fpc[63:4]+60'd1,4'b0000};
|
|
2'd3: fnIncPC = {fpc[63:4]+60'd1,4'b0000};
|
|
endcase
|
|
end
|
|
endfunction
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Instruction TLB
|
// Instruction TLB
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
reg [4:0] m;
|
reg [4:0] m;
|
Line 456... |
Line 496... |
reg [63:13] ITLBVirtPage [15:0];
|
reg [63:13] ITLBVirtPage [15:0];
|
reg [63:13] ITLBPhysPage [15:0];
|
reg [63:13] ITLBPhysPage [15:0];
|
reg [15:0] ITLBG;
|
reg [15:0] ITLBG;
|
reg [7:0] ITLBASID [15:0];
|
reg [7:0] ITLBASID [15:0];
|
reg [15:0] ITLBValid;
|
reg [15:0] ITLBValid;
|
|
initial begin
|
|
for (n = 0; n < 16; n = n + 1)
|
|
begin
|
|
ITLBPageMask[n] = 0;
|
|
ITLBVirtPage[n] = 0;
|
|
ITLBPhysPage[n] = 0;
|
|
ITLBG[n] = 0;
|
|
ITLBASID[n] = 0;
|
|
ITLBValid[n] = 0;
|
|
end
|
|
end
|
always @*
|
always @*
|
for (n = 0; n < 16; n = n + 1)
|
for (n = 0; n < 16; n = n + 1)
|
IMatch[n] = ((pc_axc[63:13]|ITLBPageMask[n])==(ITLBVirtPage[n]|ITLBPageMask[n])) &&
|
IMatch[n] = ((pc_axc[63:13]|ITLBPageMask[n])==(ITLBVirtPage[n]|ITLBPageMask[n])) &&
|
((ITLBASID[n]==ASID) || ITLBG[n]) &&
|
((ITLBASID[n]==ASID) || ITLBG[n]) &&
|
ITLBValid[n];
|
ITLBValid[n];
|
Line 498... |
Line 549... |
reg [63:13] DTLBVirtPage [15:0];
|
reg [63:13] DTLBVirtPage [15:0];
|
reg [63:13] DTLBPhysPage [15:0];
|
reg [63:13] DTLBPhysPage [15:0];
|
reg [15:0] DTLBG;
|
reg [15:0] DTLBG;
|
reg [7:0] DTLBASID [15:0];
|
reg [7:0] DTLBASID [15:0];
|
reg [15:0] DTLBValid;
|
reg [15:0] DTLBValid;
|
|
initial begin
|
|
for (n = 0; n < 16; n = n + 1)
|
|
begin
|
|
DTLBPageMask[n] = 0;
|
|
DTLBVirtPage[n] = 0;
|
|
DTLBPhysPage[n] = 0;
|
|
DTLBG[n] = 0;
|
|
DTLBASID[n] = 0;
|
|
DTLBValid[n] = 0;
|
|
end
|
|
end
|
always @(ea)
|
always @(ea)
|
for (n = 0; n < 16; n = n + 1)
|
for (n = 0; n < 16; n = n + 1)
|
DMatch[n] = ((ea[63:13]|DTLBPageMask[n])==(DTLBVirtPage[n]|DTLBPageMask[n])) &&
|
DMatch[n] = ((ea[63:13]|DTLBPageMask[n])==(DTLBVirtPage[n]|DTLBPageMask[n])) &&
|
((DTLBASID[n]==ASID) || DTLBG[n]) &&
|
((DTLBASID[n]==ASID) || DTLBG[n]) &&
|
DTLBValid[n];
|
DTLBValid[n];
|
Line 553... |
Line 615... |
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Instruction Cache
|
// Instruction Cache
|
// 8kB
|
// 8kB
|
//
|
//
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg icaccess;
|
reg icaccess, iciaccess;
|
wire wr_icache = !rd_empty & icaccess;
|
wire wr_icache = (!rd_empty & icaccess) | (iciaccess & ack_i);
|
|
|
Raptor64_icache_ram_x32 u1
|
Raptor64_icache_ram_x32 u1
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
.wr(wr_icache),
|
.wr(wr_icache),
|
.adr_i(iadr_o[12:0]),
|
.adr_i(iadr_o[12:0]),
|
.dat_i(rd_data),
|
.dat_i(icaccess ?rd_data : dat_i),
|
.pc(pc_axc),
|
.pc(pc_axc),
|
.insn(insn)
|
.insn(insn)
|
);
|
);
|
|
|
reg [63:13] tmem [127:0];
|
reg [63:13] tmem [127:0];
|
Line 635... |
Line 697... |
reg [64:0] xData;
|
reg [64:0] xData;
|
wire xisCacheElement = xData[63:52] != 12'hFFD;
|
wire xisCacheElement = xData[63:52] != 12'hFFD;
|
reg m1IsCacheElement;
|
reg m1IsCacheElement;
|
|
|
reg nopI;
|
reg nopI;
|
|
wire [6:0] iFunc = insn[6:0];
|
wire [6:0] dFunc = dIR[6:0];
|
wire [6:0] dFunc = dIR[6:0];
|
wire [6:0] xFunc = xIR[6:0];
|
wire [6:0] xFunc = xIR[6:0];
|
|
wire [6:0] iOpcode = insn[41:35];
|
wire [6:0] xOpcode = xIR[41:35];
|
wire [6:0] xOpcode = xIR[41:35];
|
wire [6:0] dOpcode = dIR[41:35];
|
wire [6:0] dOpcode = dIR[41:35];
|
reg [6:0] m1Opcode,m2Opcode,m3Opcode,m4Opcode;
|
reg [6:0] m1Opcode,m2Opcode,m3Opcode,m4Opcode;
|
reg [6:0] m1Func,m2Func,m3Func,m4Func;
|
reg [6:0] m1Func,m2Func,m3Func,m4Func;
|
reg [63:0] m1Data,m2Data,m3Data,m4Data,wData,tData;
|
reg [63:0] m1Data,m2Data,m3Data,m4Data,wData,tData;
|
reg [63:0] m2Addr,m3Addr,m4Addr;
|
reg [63:0] m2Addr,m3Addr,m4Addr;
|
reg [63:0] tick;
|
reg [63:0] tick;
|
reg [63:0] tba;
|
reg [63:0] tba;
|
reg [63:0] exception_address,ipc;
|
reg [63:0] exception_address,ipc;
|
reg [63:0] a,b,imm;
|
reg [63:0] a,b,c,imm,m1b;
|
reg prev_ihit;
|
reg prev_ihit;
|
reg rsf;
|
reg rsf;
|
reg [63:5] resv_address;
|
reg [63:5] resv_address;
|
reg dirqf,rirqf,m1irqf,m2irqf,m3irqf,m4irqf,wirqf,tirqf;
|
reg dirqf,rirqf,m1irqf,m2irqf,m3irqf,m4irqf,wirqf,tirqf;
|
reg xirqf;
|
reg xirqf;
|
Line 689... |
Line 753... |
wire isDivs = (xOpcode==`RR && xFunc==`DIVS) || xOpcode==`DIVSI;
|
wire isDivs = (xOpcode==`RR && xFunc==`DIVS) || xOpcode==`DIVSI;
|
wire isDivi = xOpcode==`DIVSI || xOpcode==`DIVUI;
|
wire isDivi = xOpcode==`DIVSI || xOpcode==`DIVUI;
|
wire isDiv = xOpcode==`DIVSI || xOpcode==`DIVUI || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU));
|
wire isDiv = xOpcode==`DIVSI || xOpcode==`DIVUI || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU));
|
|
|
wire disRRShift = dOpcode==`RR && (
|
wire disRRShift = dOpcode==`RR && (
|
dFunc==`ASL || dFunc==`ROL || dFunc==`ASR ||
|
dFunc==`SHL || dFunc==`ROL || dFunc==`SHR ||
|
dFunc==`LSR || dFunc==`ROR || dFunc==`ROLAM
|
dFunc==`SHRU || dFunc==`ROR || dFunc==`ROLAM
|
);
|
);
|
wire disRightShift = dOpcode==`RR && (
|
wire disRightShift = dOpcode==`RR && (
|
dFunc==`ASR || dFunc==`LSR || dFunc==`ROR
|
dFunc==`SHR || dFunc==`SHRU || dFunc==`ROR
|
);
|
);
|
|
|
Raptor64Mult u18
|
Raptor64Mult u18
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
Line 824... |
Line 888... |
end
|
end
|
endfunction
|
endfunction
|
|
|
wire [63:0] jmp_tgt = dOpcode[6:4]==`IMM ? {dIR[26:0],insn[34:0],2'b00} : {pc_axc[63:37],insn[34:0],2'b00};
|
wire [63:0] jmp_tgt = dOpcode[6:4]==`IMM ? {dIR[26:0],insn[34:0],2'b00} : {pc_axc[63:37],insn[34:0],2'b00};
|
|
|
//---------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Branch history table.
|
// Branch history table.
|
// The history table is updated by the EX stage
|
// The history table is updated by the EX stage and read in
|
//---------------------------------------------------------
|
// both the EX and IF stages.
|
|
//-----------------------------------------------------------------------------
|
reg [2:0] gbl_branch_hist;
|
reg [2:0] gbl_branch_hist;
|
reg [1:0] branch_history_table [255:0];
|
reg [1:0] branch_history_table [255:0];
|
wire [7:0] bht_wa = {xpc[5:0],gbl_branch_hist[2:1]}; // write address
|
wire [7:0] bht_wa = {xpc[5:0],gbl_branch_hist[2:1]}; // write address
|
wire [7:0] bht_ra1 = {xpc[5:0],gbl_branch_hist[2:1]}; // read address (EX stage)
|
wire [7:0] bht_ra1 = {xpc[5:0],gbl_branch_hist[2:1]}; // read address (EX stage)
|
wire [7:0] bht_ra2 = {pc_axc[5:0],gbl_branch_hist[2:1]}; // read address (IF stage)
|
wire [7:0] bht_ra2 = {pc_axc[5:0],gbl_branch_hist[2:1]}; // read address (IF stage)
|
wire [1:0] bht_xbits = branch_history_table[bht_ra1];
|
wire [1:0] bht_xbits = branch_history_table[bht_ra1];
|
wire [1:0] bht_ibits = branch_history_table[bht_ra2];
|
wire [1:0] bht_ibits = branch_history_table[bht_ra2];
|
wire predict_taken = bht_ibits==2'd0 || bht_ibits==2'd1;
|
wire predict_taken = bht_ibits==2'd0 || bht_ibits==2'd1;
|
|
|
wire isxRRBranch = xOpcode==`RR && (xFunc==`BRA || xFunc==`BRN || xFunc==`BEQ || xFunc==`BNE ||
|
|
xFunc==`BLT || xFunc==`BLE || xFunc==`BGT || xFunc==`BGE ||
|
|
xFunc==`BLTU || xFunc==`BLEU || xFunc==`BGTU || xFunc==`BGEU ||
|
|
xFunc==`BOR || xFunc==`BAND)
|
|
;
|
|
wire isxBranchI = (xOpcode==`BRAI || xOpcode==`BRNI || xOpcode==`BEQI || xOpcode==`BNEI ||
|
wire isxBranchI = (xOpcode==`BRAI || xOpcode==`BRNI || xOpcode==`BEQI || xOpcode==`BNEI ||
|
xOpcode==`BLTI || xOpcode==`BLEI || xOpcode==`BGTI || xOpcode==`BGEI ||
|
xOpcode==`BLTI || xOpcode==`BLEI || xOpcode==`BGTI || xOpcode==`BGEI ||
|
xOpcode==`BLTUI || xOpcode==`BLEUI || xOpcode==`BGTUI || xOpcode==`BGEUI)
|
xOpcode==`BLTUI || xOpcode==`BLEUI || xOpcode==`BGTUI || xOpcode==`BGEUI)
|
;
|
;
|
wire isxBranch = isxRRBranch || isxBranchI || xOpcode==`TRAPcc || xOpcode==`TRAPcci || xOpcode==`BRr;
|
wire isxBranch = isxBranchI || xOpcode==`TRAPcc || xOpcode==`TRAPcci || xOpcode==`BTRI || xOpcode==`BTRR;
|
|
|
reg [1:0] xbits_new;
|
reg [1:0] xbits_new;
|
|
|
always @(takb or bht_xbits)
|
always @(takb or bht_xbits)
|
if (takb) begin
|
if (takb) begin
|
Line 864... |
Line 924... |
xbits_new <= bht_xbits - 2'd1;
|
xbits_new <= bht_xbits - 2'd1;
|
else
|
else
|
xbits_new <= bht_xbits;
|
xbits_new <= bht_xbits;
|
end
|
end
|
|
|
//---------------------------------------------------------
|
// For simulation only, initialize the history table to zeros.
|
|
// In the real world we don't care.
|
|
initial begin
|
|
for (n = 0; n < 256; n = n + 1)
|
|
branch_history_table[n] = 0;
|
|
end
|
|
|
|
//-----------------------------------------------------------------------------
|
// Evaluate branch conditions.
|
// Evaluate branch conditions.
|
//---------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
wire signed [63:0] as = a;
|
wire signed [63:0] as = a;
|
wire signed [63:0] bs = b;
|
wire signed [63:0] bs = b;
|
wire signed [63:0] imms = imm;
|
wire signed [63:0] imms = imm;
|
wire aeqz = a==64'd0;
|
wire aeqz = a==64'd0;
|
wire beqz = b==64'd0;
|
wire beqz = b==64'd0;
|
Line 882... |
Line 949... |
wire ltu = a < b;
|
wire ltu = a < b;
|
wire ltui = a < imm;
|
wire ltui = a < imm;
|
|
|
always @(xOpcode or xFunc or a or eq or eqi or lt or lti or ltu or ltui or aeqz or beqz or rsf or xIR)
|
always @(xOpcode or xFunc or a or eq or eqi or lt or lti or ltu or ltui or aeqz or beqz or rsf or xIR)
|
case (xOpcode)
|
case (xOpcode)
|
`RR:
|
`BTRR:
|
case(xFunc)
|
case(xFunc)
|
`BRA: takb = 1'b1;
|
`BRA: takb = 1'b1;
|
`BRN: takb = 1'b0;
|
`BRN: takb = 1'b0;
|
`BEQ: takb = eq;
|
`BEQ: takb = eq;
|
`BNE: takb = !eq;
|
`BNE: takb = !eq;
|
Line 898... |
Line 965... |
`BLEU: takb = ltu|eq;
|
`BLEU: takb = ltu|eq;
|
`BGTU: takb = !(ltu|eq);
|
`BGTU: takb = !(ltu|eq);
|
`BGEU: takb = !ltu;
|
`BGEU: takb = !ltu;
|
`BOR: takb = !aeqz || !beqz;
|
`BOR: takb = !aeqz || !beqz;
|
`BAND: takb = !aeqz && !beqz;
|
`BAND: takb = !aeqz && !beqz;
|
|
`BNR: takb = !rsf;
|
|
`BEQR: takb = eq;
|
|
`BNER: takb = !eq;
|
|
`BLTR: takb = lt;
|
|
`BLER: takb = lt|eq;
|
|
`BGTR: takb = !(lt|eq);
|
|
`BGER: takb = !lt;
|
|
`BLTUR: takb = ltu;
|
|
`BLEUR: takb = ltu|eq;
|
|
`BGTUR: takb = !(ltu|eq);
|
|
`BGEUR: takb = !ltu;
|
default: takb = 1'b0;
|
default: takb = 1'b0;
|
endcase
|
endcase
|
`BRAI: takb = 1'b1;
|
`BRAI: takb = 1'b1;
|
`BRNI: takb = 1'b0;
|
`BRNI: takb = 1'b0;
|
`BEQI: takb = eqi;
|
`BEQI: takb = eqi;
|
Line 912... |
Line 990... |
`BGEI: takb = !lti;
|
`BGEI: takb = !lti;
|
`BLTUI: takb = ltui;
|
`BLTUI: takb = ltui;
|
`BLEUI: takb = ltui|eqi;
|
`BLEUI: takb = ltui|eqi;
|
`BGTUI: takb = !(ltui|eqi);
|
`BGTUI: takb = !(ltui|eqi);
|
`BGEUI: takb = !ltui;
|
`BGEUI: takb = !ltui;
|
|
`BTRI:
|
|
case(xIR[24:18])
|
|
`BRA: takb = 1'b1;
|
|
`BRN: takb = 1'b0;
|
|
`BEQ: takb = eqi;
|
|
`BNE: takb = !eqi;
|
|
`BLT: takb = lti;
|
|
`BLE: takb = lti|eqi;
|
|
`BGT: takb = !(lti|eqi);
|
|
`BGE: takb = !lti;
|
|
`BLTU: takb = ltui;
|
|
`BLEU: takb = ltui|eqi;
|
|
`BGTU: takb = !(ltui|eqi);
|
|
`BGEU: takb = !ltui;
|
|
default: takb = 1'b0;
|
|
endcase
|
`TRAPcc:
|
`TRAPcc:
|
case(xFunc)
|
case(xFunc)
|
`TEQ: takb = eq;
|
`TEQ: takb = eq;
|
`TNE: takb = !eq;
|
`TNE: takb = !eq;
|
`TLT: takb = lt;
|
`TLT: takb = lt;
|
Line 940... |
Line 1034... |
`TLSI: takb = ltui|eqi;
|
`TLSI: takb = ltui|eqi;
|
`THII: takb = !(ltui|eqi);
|
`THII: takb = !(ltui|eqi);
|
`THSI: takb = !ltui;
|
`THSI: takb = !ltui;
|
default: takb = 1'b0;
|
default: takb = 1'b0;
|
endcase
|
endcase
|
`BRr:
|
|
case(xIR[29:25])
|
|
`BRAZ: takb = 1'b1;
|
|
`BEQZ: takb = aeqz;
|
|
`BNEZ: takb = !aeqz;
|
|
`BLTZ: takb = a[63];
|
|
`BLEZ: takb = a[63] || aeqz;
|
|
`BGTZ: takb = !a[63] && !aeqz;
|
|
`BGEZ: takb = !a[63];
|
|
`BRAD: takb = 1;
|
|
`BNR: takb = !rsf;
|
|
`BEQZD: takb = a==64'd0;
|
|
`BNEZD: takb = a!=64'd0;
|
|
`BLTZD: takb = a[63];
|
|
`BLEZD: takb = a[63] || aeqz;
|
|
`BGTZD: takb = !a[63] && !aeqz;
|
|
`BGEZD: takb = !a[63];
|
|
`BEQZR: takb = a==64'd0;
|
|
`BNEZR: takb = a!=64'd0;
|
|
`BLTZR: takb = a[63];
|
|
`BLEZR: takb = a[63] || aeqz;
|
|
`BGTZR: takb = !a[63] && !aeqz;
|
|
`BGEZR: takb = !a[63];
|
|
`BEQZRD: takb = a==64'd0;
|
|
`BNEZRD: takb = a!=64'd0;
|
|
`BLTZRD: takb = a[63];
|
|
`BLEZRD: takb = a[63] || aeqz;
|
|
`BGTZRD: takb = !a[63] && !aeqz;
|
|
`BGEZRD: takb = !a[63];
|
|
default: takb = 1'b0;
|
|
endcase
|
|
default:
|
default:
|
takb = 1'b0;
|
takb = 1'b0;
|
endcase
|
endcase
|
|
|
|
|
//---------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Datapath (ALU) operations.
|
// Datapath (ALU) operations.
|
//---------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
wire [6:0] cntlzo,cntloo;
|
wire [6:0] cntlzo,cntloo;
|
cntlz64 u12 ( .i(a), .o(cntlzo) );
|
cntlz64 u12 ( .i(a), .o(cntlzo) );
|
cntlo64 u13 ( .i(a), .o(cntloo) );
|
cntlo64 u13 ( .i(a), .o(cntloo) );
|
|
|
reg [1:0] shftop;
|
reg [1:0] shftop;
|
wire [63:0] shfto;
|
wire [63:0] shfto;
|
always @(xFunc)
|
always @(xFunc)
|
if (xFunc==`ASL)
|
if (xFunc==`SHL)
|
shftop = 2'b00;
|
shftop = 2'b00;
|
else if (xFunc==`ROL || xFunc==`ROR)
|
else if (xFunc==`ROL || xFunc==`ROR)
|
shftop = 2'b01;
|
shftop = 2'b01;
|
else if (xFunc==`LSR)
|
else if (xFunc==`SHRU)
|
shftop = 2'b10;
|
shftop = 2'b10;
|
else if (xFunc==`ASR)
|
else if (xFunc==`SHR)
|
shftop = 2'b11;
|
shftop = 2'b11;
|
else
|
else
|
shftop = 2'b01;
|
shftop = 2'b01;
|
|
|
wire [63:0] masko;
|
wire [63:0] masko;
|
Line 1010... |
Line 1073... |
.me(xIR[18:13]),
|
.me(xIR[18:13]),
|
.o(shfto),
|
.o(shfto),
|
.mo(masko)
|
.mo(masko)
|
);
|
);
|
|
|
function [63:0] fnIncPC;
|
|
input [63:0] fpc;
|
|
begin
|
|
case(fpc[3:2])
|
|
2'd0: fnIncPC = {fpc[63:4],4'b0100};
|
|
2'd1: fnIncPC = {fpc[63:4],4'b1000};
|
|
2'd2: fnIncPC = {fpc[63:4]+60'd1,4'b0000};
|
|
2'd3: fnIncPC = {fpc[63:4]+60'd1,4'b0000};
|
|
endcase
|
|
end
|
|
endfunction
|
|
|
|
always @(xOpcode or xFunc or a or b or imm or as or bs or imms or xpc or
|
always @(xOpcode or xFunc or a or b or imm or as or bs or imms or xpc or
|
sqrt_out or cntlzo or cntloo or tick or ipc or tba or regset or
|
sqrt_out or cntlzo or cntloo or tick or ipc or tba or regset or
|
lt or eq or ltu or mult_out or lti or eqi or ltui or xIR or div_q or div_r or
|
lt or eq or ltu or mult_out or lti or eqi or ltui or xIR or div_q or div_r or
|
shfto or masko or bcdaddo or bcdsubo or fpLooOut or fpZLOut or
|
shfto or masko or bcdaddo or bcdsubo or fpLooOut or fpZLOut or
|
Wired or Index or Random or TLBPhysPage or TLBVirtPage or TLBASID or
|
Wired or Index or Random or TLBPhysPage or TLBVirtPage or TLBASID or
|
PageTableAddr or BadVAddr or ASID or TLBPageMask
|
PageTableAddr or BadVAddr or ASID or TLBPageMask
|
)
|
)
|
case(xOpcode)
|
case(xOpcode)
|
`R:
|
`R:
|
case(xFunc)
|
casex(xFunc)
|
|
`SETLO: xData = imm;
|
|
`SETHI: xData = {imm[63:32],a[31:0]};
|
`COM: xData = ~a;
|
`COM: xData = ~a;
|
`NOT: xData = ~|a;
|
`NOT: xData = ~|a;
|
`NEG: xData = -a;
|
`NEG: xData = -a;
|
`ABS: xData = a[63] ? -a : a;
|
`ABS: xData = a[63] ? -a : a;
|
`SQRT: xData = sqrt_out;
|
`SQRT: xData = sqrt_out;
|
Line 1061... |
Line 1114... |
`SEXT8: xData = {{56{a[7]}},a[7:0]};
|
`SEXT8: xData = {{56{a[7]}},a[7:0]};
|
`SEXT16: xData = {{48{a[15]}},a[15:0]};
|
`SEXT16: xData = {{48{a[15]}},a[15:0]};
|
`SEXT32: xData = {{32{a[31]}},a[31:0]};
|
`SEXT32: xData = {{32{a[31]}},a[31:0]};
|
|
|
`MFSPR:
|
`MFSPR:
|
case(xIR[34:30])
|
case(xIR[12:7])
|
`Wired: xData = Wired;
|
`Wired: xData = Wired;
|
`TLBIndex: xData = Index;
|
`TLBIndex: xData = Index;
|
`TLBRandom: xData = Random;
|
`TLBRandom: xData = Random;
|
`TLBPhysPage: xData = {TLBPhysPage,13'd0};
|
`TLBPhysPage: xData = {TLBPhysPage,13'd0};
|
`TLBVirtPage: xData = {TLBVirtPage,13'd0};
|
`TLBVirtPage: xData = {TLBVirtPage,13'd0};
|
`TLBPageMask: xData = {TLBPageMask,13'd0};
|
`TLBPageMask: xData = {TLBPageMask,13'd0};
|
`TLBASID: xData = TLBASID;
|
`TLBASID: xData = TLBASID;
|
`PageTableAddr: xData = {PageTableAddr,13'd0};
|
`PageTableAddr: xData = {PageTableAddr,13'd0};
|
`BadVAddr: xData = {BadVAddr,13'd0};
|
`BadVAddr: xData = {BadVAddr[xAXC],13'd0};
|
`ASID: xData = ASID;
|
`ASID: xData = ASID;
|
`EP0: xData = EP[0];
|
`EP0: xData = EP[0];
|
`EP1: xData = EP[1];
|
`EP1: xData = EP[1];
|
`EP2: xData = EP[2];
|
`EP2: xData = EP[2];
|
`EP3: xData = EP[3];
|
`EP3: xData = EP[3];
|
`AXC: xData = xAXC;
|
`AXC: xData = xAXC;
|
|
`Tick: xData = tick;
|
|
`EPC: xData = EPC[xAXC];
|
|
`CauseCode: xData = CauseCode[xAXC];
|
|
`TBA: xData = TBA;
|
default: xData = 65'd0;
|
default: xData = 65'd0;
|
endcase
|
endcase
|
`MFTICK: xData = tick;
|
`OMG: xData = mutex_gate[a[5:0]];
|
`MFEPC: xData = ipc;
|
`CMG: xData = mutex_gate[a[5:0]];
|
`MFTBA: xData = tba;
|
`OMGI: xData = mutex_gate[xIR[12:7]];
|
`MTTBA: xData = a;
|
`CMGI: xData = mutex_gate[xIR[12:7]];
|
`MTREGSET: xData = a;
|
|
`MFREGSET: xData = regset;
|
|
default: xData = 65'd0;
|
default: xData = 65'd0;
|
endcase
|
endcase
|
`RR:
|
`RR:
|
case(xFunc)
|
case(xFunc)
|
`ADD: xData = a + b;
|
`ADD: xData = a + b;
|
|
`ADDU: xData = a + b;
|
`SUB: xData = a - b;
|
`SUB: xData = a - b;
|
|
`SUBU: xData = a - b;
|
`CMP: xData = lt ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
|
`CMP: xData = lt ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
|
`CMPU: xData = ltu ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
|
`CMPU: xData = ltu ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
|
`SEQ: xData = eq;
|
`SEQ: xData = eq;
|
`SNE: xData = !eq;
|
`SNE: xData = !eq;
|
`SLT: xData = lt;
|
`SLT: xData = lt;
|
Line 1121... |
Line 1178... |
`MULU: xData = mult_out[63:0];
|
`MULU: xData = mult_out[63:0];
|
`DIVS: xData = div_q;
|
`DIVS: xData = div_q;
|
`DIVU: xData = div_q;
|
`DIVU: xData = div_q;
|
`MOD: xData = div_r;
|
`MOD: xData = div_r;
|
|
|
`ASL: xData = shfto;
|
`SHL: xData = shfto;
|
`LSR: xData = shfto;
|
`SHRU: xData = shfto;
|
`ROL: xData = shfto;
|
`ROL: xData = shfto;
|
`ROR: xData = {a[0],a[63:1]};
|
`ROR: xData = {a[0],a[63:1]};
|
`ASR: xData = shfto;
|
`SHR: xData = shfto;
|
`ROLAM: xData = shfto & masko;
|
`ROLAM: xData = shfto & masko;
|
|
|
`BCD_ADD: xData = bcdaddo;
|
`BCD_ADD: xData = bcdaddo;
|
`BCD_SUB: xData = bcdsubo;
|
`BCD_SUB: xData = bcdsubo;
|
|
|
default: xData = 65'd0;
|
default: xData = 65'd0;
|
endcase
|
endcase
|
`SHFTI:
|
`SHFTI:
|
case(xFunc)
|
case(xFunc)
|
`ASLI: xData = shfto;
|
`SHLI: xData = shfto;
|
`LSRI: xData = shfto;
|
`SHRUI: xData = shfto;
|
`ROLI: xData = shfto;
|
`ROLI: xData = shfto;
|
`RORI: xData = {a[0],a[63:1]};
|
`RORI: xData = {a[0],a[63:1]};
|
`ASRI: xData = shfto;
|
`SHRI: xData = shfto;
|
`ROLAMI: xData = shfto & masko;
|
`ROLAMI: xData = shfto & masko;
|
`BFINS: for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? shfto[n] : b[n];
|
`BFINS: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? shfto[n] : b[n]; xData[64] = 1'b0; end
|
`BFSET: for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b1 : b[n];
|
`BFSET: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b1 : b[n]; xData[64] = 1'b0; end
|
`BFCLR: for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b0 : b[n];
|
`BFCLR: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b0 : b[n]; xData[64] = 1'b0; end
|
`BFCHG: for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? ~b[n] : b[n];
|
`BFCHG: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? ~b[n] : b[n]; xData[64] = 1'b0; end
|
default: xData = 65'd0;
|
default: xData = 65'd0;
|
endcase
|
endcase
|
`ADDI: xData = a + imm;
|
`ADDI: xData = a + imm;
|
|
`ADDUI: xData = a + imm;
|
`SUBI: xData = a - imm;
|
`SUBI: xData = a - imm;
|
`CMPI: xData = lti ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
|
`CMPI: xData = lti ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
|
`CMPUI: xData = ltui ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
|
`CMPUI: xData = ltui ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
|
`MULSI: xData = mult_out[63:0];
|
`MULSI: xData = mult_out[63:0];
|
`MULUI: xData = mult_out[63:0];
|
`MULUI: xData = mult_out[63:0];
|
Line 1176... |
Line 1234... |
xData = a + imm;
|
xData = a + imm;
|
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LWR:
|
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LWR:
|
xData = a + imm;
|
xData = a + imm;
|
`SW,`SH,`SC,`SB,`SWC:
|
`SW,`SH,`SC,`SB,`SWC:
|
xData = a + imm;
|
xData = a + imm;
|
|
`MEMNDX:
|
|
xData = a + b + imm;
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BOR,`BAND:
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BOR,`BAND:
|
xData = 64'd0;
|
xData = 64'd0;
|
`TRAPcc: xData = fnIncPC(xpc);
|
`TRAPcc: xData = fnIncPC(xpc);
|
`TRAPcci: xData = fnIncPC(xpc);
|
`TRAPcci: xData = fnIncPC(xpc);
|
`CALL: xData = fnIncPC(xpc);
|
`CALL: xData = fnIncPC(xpc);
|
Line 1188... |
Line 1248... |
`FPLOO: xData = fpLooOut;
|
`FPLOO: xData = fpLooOut;
|
`FPZL: xData = fpZLOut;
|
`FPZL: xData = fpZLOut;
|
default: xData = 65'd0;
|
default: xData = 65'd0;
|
endcase
|
endcase
|
|
|
|
wire dbz_error = (xOpcode==`DIVSI||xOpcode==`DIVUI) && b==64'd0;
|
|
wire ovr_error = (xOpcode==`ADDI || xOpcode==`SUBI) && (xData[64]!=xData[63]);
|
|
|
wire xIsSqrt = xOpcode==`R && xFunc==`SQRT;
|
wire xIsSqrt = xOpcode==`R && xFunc==`SQRT;
|
wire xIsMult = (xOpcode==`RR && (xFunc==`MULU || xFunc==`MULS)) ||
|
wire xIsMult = (xOpcode==`RR && (xFunc==`MULU || xFunc==`MULS)) ||
|
xOpcode==`MULSI || xOpcode==`MULUI;
|
xOpcode==`MULSI || xOpcode==`MULUI;
|
wire xIsDiv = (xOpcode==`RR && (xFunc==`DIVU || xFunc==`DIVS)) ||
|
wire xIsDiv = (xOpcode==`RR && (xFunc==`DIVU || xFunc==`DIVS)) ||
|
xOpcode==`DIVSI || xOpcode==`DIVUI;
|
xOpcode==`DIVSI || xOpcode==`DIVUI;
|
Line 1302... |
Line 1365... |
1'b1);
|
1'b1);
|
wire advanceR = advanceX & !xStall & !m1Stall && !m2Stall && !m3Stall && !m4Stall;
|
wire advanceR = advanceX & !xStall & !m1Stall && !m2Stall && !m3Stall && !m4Stall;
|
wire advanceI = advanceR & ihit;
|
wire advanceI = advanceR & ihit;
|
|
|
wire triggerDCacheLoad = (m1IsLoad & m1IsCacheElement & !dhit) && // there is a miss
|
wire triggerDCacheLoad = (m1IsLoad & m1IsCacheElement & !dhit) && // there is a miss
|
!(icaccess | dcaccess) && // caches are not active
|
!(icaccess | dcaccess | iciaccess) && // caches are not active
|
m2Opcode==`NOPI && // and the pipeline is free of memory-ops
|
m2Opcode==`NOPI && // and the pipeline is free of memory-ops
|
m3Opcode==`NOPI &&
|
m3Opcode==`NOPI &&
|
m4Opcode==`NOPI &&
|
m4Opcode==`NOPI &&
|
wr_empty // and the write buffer is empty
|
wr_empty // and the write buffer is empty
|
;
|
;
|
wire triggerICacheLoad = !ihit & !triggerDCacheLoad; ;
|
// Since IMM is "sticky" we have to check for it.
|
|
wire triggerICacheLoad = !ihit & !triggerDCacheLoad & // There is a miss
|
|
(dOpcode==`NOPI || dOpcode[6:4]==`IMM) && // and the pipeline is flushed
|
|
(xOpcode==`NOPI || xOpcode[6:4]==`IMM) &&
|
|
m1Opcode==`NOPI &&
|
|
m2Opcode==`NOPI &&
|
|
m3Opcode==`NOPI &&
|
|
m4Opcode==`NOPI
|
|
;
|
|
|
wire xWillLoadStore = (xIsLoad||xIsStore) & advanceX;
|
wire xWillLoadStore = (xIsLoad||xIsStore) & advanceX;
|
wire stallCacheLoad = xWillLoadStore;
|
wire stallCacheLoad = xWillLoadStore;
|
|
|
reg prev_nmi,nmi_edge;
|
reg prev_nmi,nmi_edge;
|
Line 1320... |
Line 1391... |
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Register file.
|
// Register file.
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
|
|
syncRam512x64_1rw2r u5
|
syncRam512x64_1rw3r u5
|
(
|
(
|
.wrst(1'b0),
|
.wrst(1'b0),
|
.wclk(clk),
|
.wclk(clk),
|
.wce(advanceW),
|
.wce(advanceW),
|
.we(1'b1),
|
.we(1'b1),
|
Line 1340... |
Line 1411... |
|
|
.rrstb(1'b0),
|
.rrstb(1'b0),
|
.rclkb(~clk),
|
.rclkb(~clk),
|
.rceb(advanceR),
|
.rceb(advanceR),
|
.radrb(dRb),
|
.radrb(dRb),
|
.rob(rfob)
|
.rob(rfob),
|
|
|
|
.rrstc(1'b0),
|
|
.rclkc(~clk),
|
|
.rcec(advanceR),
|
|
.radrc(dRc),
|
|
.roc(rfoc)
|
);
|
);
|
|
|
|
|
reg m1clkoff,m2clkoff,m3clkoff,m4clkoff,wclkoff;
|
reg m1clkoff,m2clkoff,m3clkoff,m4clkoff,wclkoff;
|
|
reg dFip,xFip,m1Fip,m2Fip,m3Fip,m4Fip,wFip;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst_i) begin
|
if (rst_i) begin
|
bte_o <= 2'b00;
|
bte_o <= 2'b00;
|
cti_o <= 3'b000;
|
cti_o <= 3'b000;
|
Line 1394... |
Line 1472... |
wirqf <= 1'b0;
|
wirqf <= 1'b0;
|
m1irqf <= 1'b0;
|
m1irqf <= 1'b0;
|
m2irqf <= 1'b0;
|
m2irqf <= 1'b0;
|
m3irqf <= 1'b0;
|
m3irqf <= 1'b0;
|
m4irqf <= 1'b0;
|
m4irqf <= 1'b0;
|
|
wFip <= 1'b0;
|
|
m4Fip <= 1'b0;
|
|
m3Fip <= 1'b0;
|
|
m2Fip <= 1'b0;
|
|
m1Fip <= 1'b0;
|
|
xFip <= 1'b0;
|
|
dFip <= 1'b0;
|
dirqf <= 1'b0;
|
dirqf <= 1'b0;
|
tick <= 32'd0;
|
tick <= 32'd0;
|
cstate <= IDLE;
|
cstate <= IDLE;
|
dImm <= 64'd0;
|
dImm <= 64'd0;
|
regset <= 4'd0;
|
regset <= 4'd0;
|
Line 1410... |
Line 1495... |
imm <= 64'd0;
|
imm <= 64'd0;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
clk_en <= 1'b1;
|
clk_en <= 1'b1;
|
Random <= 4'hF;
|
Random <= 4'hF;
|
Wired <= 4'd0;
|
Wired <= 4'd0;
|
StatusTLB <= 1'b0;
|
StatusEXL <= 16'b0;
|
StatusEXL <= 1'b0;
|
|
epcnt <= 5'd0;
|
epcnt <= 5'd0;
|
EP[0] <= 32'd0;
|
EP[0] <= 32'h00000000;
|
EP[1] <= 32'd0;
|
EP[1] <= 32'h00000000;
|
EP[2] <= 32'd0;
|
EP[2] <= 32'h00000000;
|
EP[3] <= 32'd0;
|
EP[3] <= 32'h00000000;
|
AXC <= 4'd0;
|
AXC <= 4'd0;
|
dAXC <= 4'd0;
|
dAXC <= 4'd0;
|
xAXC <= 4'd0;
|
xAXC <= 4'd0;
|
resetA <= 1'b1;
|
resetA <= 1'b1;
|
|
gbl_branch_hist <= 3'b000;
|
end
|
end
|
else begin
|
else begin
|
|
|
|
//---------------------------------------------------------
|
|
// Initialize program counters
|
|
//---------------------------------------------------------
|
|
if (resetA) begin
|
|
pc[xAXC] <= `RESET_VECTOR;
|
|
xAXC <= xAXC + 4'd1;
|
|
if (xAXC==4'hF)
|
|
resetA <= 1'b0;
|
|
end
|
|
|
|
cmd_en <= 1'b0; // allow this signal only to pulse for a single clock cycle
|
|
wr_en <= 1'b0; // allow this signal to only pulse for a single cycle
|
if (Random==Wired)
|
if (Random==Wired)
|
Random <= 4'hF;
|
Random <= 4'hF;
|
else
|
else
|
Random <= Random - 4'd1;
|
Random <= Random - 4'd1;
|
|
|
Line 1460... |
Line 1557... |
// - record exception address and type
|
// - record exception address and type
|
// - jump to exception handler routine (below)
|
// - jump to exception handler routine (below)
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceW) begin
|
if (advanceW) begin
|
textype <= wextype;
|
textype <= wextype;
|
|
wextype <= `EX_NON;
|
tRt <= wRt;
|
tRt <= wRt;
|
tData <= wData;
|
tData <= wData;
|
// regfile[wRt] <= wData; <- regfile.v
|
// regfile[wRt] <= wData; <- regfile.v
|
$display("Writing regfile[%d:%d] with %h", wRt[8:5],wRt[4:0], wData);
|
$display("Writing regfile[%d:%d] with %h", wRt[8:5],wRt[4:0], wData);
|
wRt <= 9'd0;
|
wRt <= 9'd0;
|
Line 1474... |
Line 1572... |
m2irqf <= 1'b0;
|
m2irqf <= 1'b0;
|
m3irqf <= 1'b0;
|
m3irqf <= 1'b0;
|
m4irqf <= 1'b0;
|
m4irqf <= 1'b0;
|
xirqf <= 1'b0;
|
xirqf <= 1'b0;
|
dirqf <= 1'b0;
|
dirqf <= 1'b0;
|
ipc <= wpc;
|
|
exception_type <= wextype;
|
exception_type <= wextype;
|
end
|
end
|
clk_en <= 1'b1;
|
clk_en <= 1'b1;
|
if (wclkoff)
|
if (wclkoff)
|
clk_en <= 1'b0;
|
clk_en <= 1'b0;
|
wclkoff <= 1'b0;
|
wclkoff <= 1'b0;
|
m1clkoff <= 1'b0;
|
m1clkoff <= 1'b0;
|
m2clkoff <= 1'b0;
|
m2clkoff <= 1'b0;
|
m3clkoff <= 1'b0;
|
m3clkoff <= 1'b0;
|
m4clkoff <= 1'b0;
|
m4clkoff <= 1'b0;
|
|
if (wFip) begin
|
|
wFip <= 1'b0;
|
|
m4Fip <= 1'b0;
|
|
m3Fip <= 1'b0;
|
|
m2Fip <= 1'b0;
|
|
m1Fip <= 1'b0;
|
|
xFip <= 1'b0;
|
|
dFip <= 1'b0;
|
|
end
|
end
|
end
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
// - merge word load data into pipeline.
|
// - merge word load data into pipeline.
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceM4) begin
|
if (advanceM4) begin
|
wirqf <= m4irqf;
|
wirqf <= m4irqf;
|
|
wFip <= m4Fip;
|
wextype <= m4extype;
|
wextype <= m4extype;
|
wRt <= m4Rt;
|
wRt <= m4Rt;
|
wpc <= m4pc;
|
wpc <= m4pc;
|
wclkoff <= m4clkoff;
|
wclkoff <= m4clkoff;
|
wData <= m4Data;
|
wData <= m4Data;
|
|
|
m4Rt <= 9'd0;
|
m4Rt <= 9'd0;
|
m4Opcode <= `NOPI;
|
m4Opcode <= `NOPI;
|
m4Data <= 64'd0;
|
m4Data <= 64'd0;
|
m4clkoff <= 1'b0;
|
m4clkoff <= 1'b0;
|
m4Opcode <= `NOPI;
|
m4Opcode <= `NOPI;
|
|
m4extype <= `EX_NON;
|
|
if (m4extype==`EX_NON) begin
|
case(m4Opcode)
|
case(m4Opcode)
|
`LW,`LWR: begin
|
`LW,`LWR: begin
|
wData <= {rd_data,m4Data[31:0]};
|
wData <= {rd_data,m4Data[31:0]};
|
rd_en <= 1'b0; // only if LW/LWR
|
rd_en <= 1'b0; // only if LW/LWR
|
end
|
end
|
default: wData <= m4Data;
|
default: wData <= m4Data;
|
endcase
|
endcase
|
end
|
end
|
|
end
|
|
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceM3) begin
|
if (advanceM3) begin
|
m4Opcode <= m3Opcode;
|
m4Opcode <= m3Opcode;
|
m4Func <= m3Func;
|
m4Func <= m3Func;
|
m4irqf <= m3irqf;
|
m4irqf <= m3irqf;
|
|
m4Fip <= m3Fip;
|
m4extype <= m3extype;
|
m4extype <= m3extype;
|
m4Rt <= m3Rt;
|
m4Rt <= m3Rt;
|
m4pc <= m3pc;
|
m4pc <= m3pc;
|
m4clkoff <= m3clkoff;
|
m4clkoff <= m3clkoff;
|
|
|
m3Rt <= 9'd0;
|
m3Rt <= 9'd0;
|
m3Opcode <= `NOPI;
|
m3Opcode <= `NOPI;
|
m3Func <= 7'd0;
|
m3Func <= 7'd0;
|
m3clkoff <= 1'b0;
|
m3clkoff <= 1'b0;
|
m3pc <= 64'd0;
|
m3pc <= 64'd0;
|
m4Data <= m3Data;
|
m4Data <= m3Data;
|
m3Addr <= 64'd0;
|
m3Addr <= 64'd0;
|
m3Data <= 64'd0;
|
m3Data <= 64'd0;
|
|
m3extype <= `EX_NON;
|
|
if (m3extype==`EX_NON) begin
|
case(m3Opcode)
|
case(m3Opcode)
|
`INW:
|
`INW:
|
begin
|
begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
Line 1608... |
Line 1723... |
cmd_byte_addr <= {m3Addr[29:3],3'b000};
|
cmd_byte_addr <= {m3Addr[29:3],3'b000};
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
|
end
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceM2) begin
|
if (advanceM2) begin
|
Line 1622... |
Line 1738... |
m3irqf <= m2irqf;
|
m3irqf <= m2irqf;
|
m3extype <= m2extype;
|
m3extype <= m2extype;
|
m3Rt <= m2Rt;
|
m3Rt <= m2Rt;
|
m3pc <= m2pc;
|
m3pc <= m2pc;
|
m3clkoff <= m2clkoff;
|
m3clkoff <= m2clkoff;
|
|
m3Fip <= m2Fip;
|
|
|
m2Rt <= 9'd0;
|
m2Rt <= 9'd0;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m2Func <= 7'd0;
|
m2Func <= 7'd0;
|
m2Addr <= 64'd0;
|
m2Addr <= 64'd0;
|
m2Data <= 64'd0;
|
m2Data <= 64'd0;
|
m2clkoff <= 1'b0;
|
m2clkoff <= 1'b0;
|
m2pc <= 64'd0;
|
m2pc <= 64'd0;
|
|
m2extype <= `EX_NON;
|
|
if (m2extype==`EX_NON) begin
|
case(m2Opcode)
|
case(m2Opcode)
|
`INW:
|
`INW:
|
begin
|
begin
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'hF;
|
sel_o <= 4'hF;
|
Line 1667... |
Line 1787... |
rd_en <= 1'b1;
|
rd_en <= 1'b1;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
|
end
|
|
|
wrhit <= 1'b0;
|
wrhit <= 1'b0;
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
// On a data cache hit for a load, the load is essentially
|
// On a data cache hit for a load, the load is essentially
|
Line 1686... |
Line 1807... |
m2irqf <= m1irqf;
|
m2irqf <= m1irqf;
|
m2extype <= m1extype;
|
m2extype <= m1extype;
|
m2Rt <= m1Rt;
|
m2Rt <= m1Rt;
|
m2pc <= m1pc;
|
m2pc <= m1pc;
|
m2clkoff <= m1clkoff;
|
m2clkoff <= m1clkoff;
|
|
m2Fip <= m1Fip;
|
|
|
m1Rt <= 9'd0;
|
m1Rt <= 9'd0;
|
m1Opcode <= `NOPI;
|
m1Opcode <= `NOPI;
|
m1Func <= 7'd0;
|
m1Func <= 7'd0;
|
m1Data <= 64'd0;
|
m1Data <= 64'd0;
|
m1clkoff <= 1'b0;
|
m1clkoff <= 1'b0;
|
m1pc <= 64'd0;
|
m1pc <= 64'd0;
|
m1IsCacheElement <= 1'b0;
|
m1IsCacheElement <= 1'b0;
|
|
m1extype <= `EX_NON;
|
|
|
|
if (m1extype == `EX_NON) begin
|
case(m1Opcode)
|
case(m1Opcode)
|
`MISC:
|
`MISC:
|
case(m1Func)
|
case(m1Func)
|
`TLBR:
|
`TLBR:
|
begin
|
begin
|
|
TLBPageMask <= ITLBPageMask[i];
|
TLBVirtPage <= ITLBVirtPage[i];
|
TLBVirtPage <= ITLBVirtPage[i];
|
TLBPhysPage <= ITLBPhysPage[i];
|
TLBPhysPage <= ITLBPhysPage[i];
|
|
TLBASID <= ITLBASID[i];
|
|
TLBG <= ITLBG[i];
|
end
|
end
|
`TLBWI,`TLBWR:
|
`TLBWI,`TLBWR:
|
begin
|
begin
|
ITLBValid[i] <= 1'b1;
|
ITLBValid[i] <= 1'b1;
|
ITLBVirtPage[i] <= TLBVirtPage;
|
ITLBVirtPage[i] <= TLBVirtPage;
|
Line 1894... |
Line 2023... |
end
|
end
|
`SW,`SH:
|
`SW,`SH:
|
begin
|
begin
|
wrhit <= dhit;
|
wrhit <= dhit;
|
wr_en <= 1'b1;
|
wr_en <= 1'b1;
|
wr_data <= b[31:0];
|
wr_data <= m1b[31:0];
|
wr_mask <= 4'h0;
|
wr_mask <= 4'h0;
|
wr_addr <= {pea[63:3],3'b000};
|
wr_addr <= {pea[63:3],3'b000};
|
m2Addr <= {pea[63:3],3'b000};
|
m2Addr <= {pea[63:3],3'b000};
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= 59'd0;
|
resv_address <= 59'd0;
|
end
|
end
|
`SC:
|
`SC:
|
begin
|
begin
|
|
$display("Storing char to %h, ea=%h",pea,ea);
|
wrhit <= dhit;
|
wrhit <= dhit;
|
wr_en <= 1'b1;
|
wr_en <= 1'b1;
|
wr_data <= {2{b[15:0]}};
|
wr_data <= {2{m1b[15:0]}};
|
wr_mask <= pea[1] ? 4'b0011 : 4'b1100;
|
wr_mask <= pea[1] ? 4'b0011 : 4'b1100;
|
wr_addr <= {pea[63:2],2'b00};
|
wr_addr <= {pea[63:2],2'b00};
|
m2Addr <= {pea[63:2],2'b00};
|
m2Addr <= {pea[63:2],2'b00};
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= 59'd0;
|
resv_address <= 59'd0;
|
end
|
end
|
`SB:
|
`SB:
|
begin
|
begin
|
wrhit <= dhit;
|
wrhit <= dhit;
|
wr_en <= 1'b1;
|
wr_en <= 1'b1;
|
wr_data <= {4{b[7:0]}};
|
wr_data <= {4{m1b[7:0]}};
|
wr_addr <= {pea[63:2],2'b00};
|
wr_addr <= {pea[63:2],2'b00};
|
m2Addr <= {pea[63:2],2'b00};
|
m2Addr <= {pea[63:2],2'b00};
|
case(pea[1:0])
|
case(pea[1:0])
|
2'd0: wr_mask <= 4'b1110;
|
2'd0: wr_mask <= 4'b1110;
|
2'd1: wr_mask <= 4'b1101;
|
2'd1: wr_mask <= 4'b1101;
|
Line 1934... |
Line 2064... |
begin
|
begin
|
rsf <= 1'b0;
|
rsf <= 1'b0;
|
if (resv_address==pea[63:5]) begin
|
if (resv_address==pea[63:5]) begin
|
wrhit <= dhit;
|
wrhit <= dhit;
|
wr_en <= 1'b1;
|
wr_en <= 1'b1;
|
wr_data <= b[31:0];
|
wr_data <= m1b[31:0];
|
wr_mask <= 4'h0;
|
wr_mask <= 4'h0;
|
wr_addr <= {pea[63:3],3'b000};
|
wr_addr <= {pea[63:3],3'b000};
|
m2Addr <= {pea[63:3],3'b000};
|
m2Addr <= {pea[63:3],3'b000};
|
resv_address <= 59'd0;
|
resv_address <= 59'd0;
|
rsf <= 1'b1;
|
rsf <= 1'b1;
|
Line 1946... |
Line 2076... |
else
|
else
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
end
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// EXECUTE:
|
// EXECUTE:
|
// - perform datapath operation
|
// - perform datapath operation
|
// - Stores always initiate a bus cycle
|
// - Stores always initiate a bus cycle
|
// - Loads initiate a bus cycle only from non-cacheable
|
// - Loads initiate a bus cycle only from non-cacheable
|
// addresses
|
// addresses
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceX) begin
|
if (advanceX) begin
|
m1irqf <= xirqf;
|
m1irqf <= xirqf;
|
|
m1Fip <= xFip;
|
m1extype <= xextype;
|
m1extype <= xextype;
|
m1Opcode <= xOpcode;
|
m1Opcode <= xOpcode;
|
m1Func <= xFunc;
|
m1Func <= xFunc;
|
m1Rt <= xRt;
|
m1Rt <= xRt;
|
m1Data <= xData;
|
m1Data <= xData;
|
m1IsCacheElement <= xisCacheElement;
|
m1IsCacheElement <= xisCacheElement;
|
|
m1AXC <= xAXC;
|
if (xOpcode==`MOVZ && !aeqz) begin
|
if (xOpcode==`MOVZ && !aeqz) begin
|
m1Rt <= 9'd0;
|
m1Rt <= 9'd0;
|
m1Data <= 64'd0;
|
m1Data <= 64'd0;
|
end
|
end
|
if (xOpcode==`MOVNZ && aeqz) begin
|
if (xOpcode==`MOVNZ && aeqz) begin
|
Line 1975... |
Line 2108... |
m1pc <= xpc;
|
m1pc <= xpc;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
a <= 64'd0;
|
a <= 64'd0;
|
b <= 64'd0;
|
b <= 64'd0;
|
imm <= 64'd0;
|
imm <= 64'd0;
|
|
xextype <= `EX_NON;
|
if (xOpcode[6:4]!=`IMM) begin
|
if (xOpcode[6:4]!=`IMM) begin
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
// xpc <= 64'd0;
|
// xpc <= 64'd0;
|
case(xOpcode)
|
case(xOpcode)
|
Line 1996... |
Line 2130... |
default: ;
|
default: ;
|
endcase
|
endcase
|
`R:
|
`R:
|
case(xFunc)
|
case(xFunc)
|
`MTSPR:
|
`MTSPR:
|
case(xIR[29:25])
|
case(xIR[12:7])
|
`Wired: Wired <= xData[3:0];
|
`Wired: Wired <= xData[3:0];
|
`ASID: ASID <= xData[7:0];
|
`ASID: ASID <= xData[7:0];
|
`TLBIndex: Index <= xData[3:0];
|
`TLBIndex: Index <= xData[3:0];
|
`TLBVirtPage: TLBVirtPage <= xData[63:13];
|
`TLBVirtPage: TLBVirtPage <= xData[63:13];
|
`TLBPhysPage: TLBPhysPage <= xData[63:13];
|
`TLBPhysPage: TLBPhysPage <= xData[63:13];
|
`TLBPageMask: TLBPageMask <= xData[24:13];
|
`TLBPageMask: TLBPageMask <= xData[24:13];
|
`TLBASID: TLBASID <= xData[7:0];
|
`TLBASID: TLBASID <= xData[7:0];
|
`PageTableAddr: PageTableAddr <= xData[63:13];
|
`PageTableAddr: PageTableAddr <= xData[63:13];
|
`BadVAddr: BadVAddr <= xData[63:13];
|
`BadVAddr: BadVAddr[xAXC] <= xData[63:13];
|
`EP0: EP[0] <= xData[31:0];
|
`EP0: EP[0] <= {xData[31:4],4'd0};
|
`EP1: EP[1] <= xData[31:0];
|
`EP1: EP[1] <= xData[31:0];
|
`EP2: EP[2] <= xData[31:0];
|
`EP2: EP[2] <= xData[31:0];
|
`EP3: EP[3] <= xData[31:0];
|
`EP3: EP[3] <= xData[31:0];
|
|
`EPC: EPC[xAXC] <= xData;
|
|
`TBA: TBA <= xData;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`MTTBA: tba <= {xData[63:2],2'b00};
|
`MTTBA: tba <= {xData[63:2],2'b00};
|
|
`OMG: mutex_gate[a[5:0]] <= 1'b1;
|
|
`CMG: mutex_gate[a[5:0]] <= 1'b0;
|
|
`OMGI: mutex_gate[xIR[12:7]] <= 1'b1;
|
|
`CMGI: mutex_gate[xIR[12:7]] <= 1'b0;
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`CALL: m1Data <= fnIncPC(xpc);
|
`CALL: m1Data <= fnIncPC(xpc);
|
`INW:
|
`INW:
|
begin
|
begin
|
Line 2097... |
Line 2237... |
endcase
|
endcase
|
adr_o <= xData;
|
adr_o <= xData;
|
dat_o <= {4{b[7:0]}};
|
dat_o <= {4{b[7:0]}};
|
end
|
end
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWR,`SW,`SH,`SC,`SB,`SWC:
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWR,`SW,`SH,`SC,`SB,`SWC:
|
|
begin
|
|
m1b <= b;
|
ea <= xData;
|
ea <= xData;
|
|
end
|
|
`MEMNDX:
|
|
begin
|
|
m1Opcode <= xFunc;
|
|
m1b <= c;
|
|
ea <= xData;
|
|
end
|
`DIVSI,`DIVUI:
|
`DIVSI,`DIVUI:
|
if (b==64'd0) begin
|
if (b==64'd0) begin
|
if (xextype == 8'h00)
|
|
xextype <= `EX_DBZ;
|
xextype <= `EX_DBZ;
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
// Update the branch history
|
// Update the branch history
|
Line 2118... |
Line 2266... |
// RFETCH:
|
// RFETCH:
|
// Register fetch stage
|
// Register fetch stage
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceR) begin
|
if (advanceR) begin
|
xirqf <= dirqf;
|
xirqf <= dirqf;
|
|
xFip <= dFip;
|
xextype <= dextype;
|
xextype <= dextype;
|
xAXC <= dAXC;
|
xAXC <= dAXC;
|
xIR <= dIR;
|
xIR <= dIR;
|
xpc <= dpc;
|
xpc <= dpc;
|
xbranch_taken <= dbranch_taken;
|
xbranch_taken <= dbranch_taken;
|
dbranch_taken <= 1'b0;
|
dbranch_taken <= 1'b0;
|
|
dextype <= `EX_NON;
|
if (dOpcode[6:4]!=`IMM) // IMM is "sticky"
|
if (dOpcode[6:4]!=`IMM) // IMM is "sticky"
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
dRa <= 9'd0;
|
dRa <= 9'd0;
|
dRb <= 9'd0;
|
dRb <= 9'd0;
|
|
|
|
// Result forward muxes
|
casex(dRa)
|
casex(dRa)
|
9'bxxxx00000: a <= 64'd0;
|
9'bxxxx00000: a <= 64'd0;
|
xRt: a <= xData;
|
xRt: a <= xData;
|
m1Rt: a <= m1Data;
|
m1Rt: a <= m1Data;
|
m2Rt: a <= m2Data;
|
m2Rt: a <= m2Data;
|
Line 2152... |
Line 2304... |
tRt: b <= disRightShift ? -tData[5:0] : tData;
|
tRt: b <= disRightShift ? -tData[5:0] : tData;
|
default: b <= disRightShift ? -rfob[5:0] : rfob;
|
default: b <= disRightShift ? -rfob[5:0] : rfob;
|
endcase
|
endcase
|
if (dOpcode==`SHFTI)
|
if (dOpcode==`SHFTI)
|
case(dFunc)
|
case(dFunc)
|
`ROLI,`ASLI,`ROLAMI: b <= {58'd0,dIR[24:19]};
|
`RORI: b <= {58'd0,~dIR[24:19]+6'd1};
|
`RORI,`ASRI,`LSRI: b <= {58'd0,~dIR[24:19]+6'd1};
|
default: b <= {58'd0,dIR[24:19]};
|
|
endcase
|
|
casex(dRc)
|
|
9'bxxxx00000: c <= 64'd0;
|
|
xRt: c <= xData;
|
|
m1Rt: c <= m1Data;
|
|
m2Rt: c <= m2Data;
|
|
m3Rt: c <= m3Data;
|
|
m4Rt: c <= m4Data;
|
|
wRt: c <= wData;
|
|
tRt: c <= tData;
|
|
default: c <= rfoc;
|
endcase
|
endcase
|
|
|
|
// Set the target register
|
case(dOpcode)
|
case(dOpcode)
|
`RR:
|
`RR: xRt <= {dAXC,dIR[24:20]};
|
|
`BTRI: xRt <= 9'd0;
|
|
`BTRR: xRt <= 9'd0;
|
|
`TRAPcc: xRt <= 9'd0;
|
|
`TRAPcci: xRt <= 9'd0;
|
|
`JMP: xRt <= 9'd00;
|
|
`CALL: xRt <= {dAXC,5'd31};
|
|
`RET: xRt <= {dAXC,dIR[24:20]};
|
|
`MEMNDX:
|
case(dFunc)
|
case(dFunc)
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BRA,`BRN,`BAND,`BOR:
|
`SW,`SH,`SC,`SB,`OUTW,`OUTH,`OUTC,`OUTB:
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
default: xRt <= {dAXC,dIR[24:20]};
|
default: xRt <= {dAXC,dIR[24:20]};
|
endcase
|
endcase
|
`RET: xRt <= {dAXC,dIR[24:20]};
|
|
`BRr: xRt <= 9'd0;
|
|
`TRAPcc: xRt <= {dAXC,5'd30};
|
|
`TRAPcci: xRt <= {dAXC,5'd30};
|
|
`JMP: xRt <= 9'd00;
|
|
`CALL: xRt <= {dAXC,5'd31};
|
|
`SW,`SH,`SC,`SB,`OUTW,`OUTH,`OUTC,`OUTB:
|
`SW,`SH,`SC,`SB,`OUTW,`OUTH,`OUTC,`OUTB:
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
`NOPI: xRt <= 9'd0;
|
`NOPI: xRt <= 9'd0;
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
default: xRt <= {dAXC,dIR[29:25]};
|
default: xRt <= {dAXC,dIR[29:25]};
|
endcase
|
endcase
|
|
if (dOpcode[6:4]==`IMM)
|
|
xRt <= 9'd0;
|
|
|
|
// Set immediate value
|
if (xOpcode[6:4]==`IMM) begin
|
if (xOpcode[6:4]==`IMM) begin
|
imm <= {xIR[38:0],dIR[24:0]};
|
imm <= {xIR[38:0],dIR[24:0]};
|
end
|
end
|
else
|
else
|
case(dOpcode)
|
case(dOpcode)
|
|
`BTRI: imm <= {{44{dIR[19]}},dIR[19:0]};
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
imm <= {{46{dIR[17]}},dIR[17:0]};
|
imm <= {{46{dIR[17]}},dIR[17:0]};
|
`SHFTI:
|
|
case(dFunc)
|
|
`RORI,`ASRI,`LSRI:
|
|
imm <= {58'd0,~dIR[24:19]+6'd1};
|
|
default: imm <= {58'd0,dIR[24:19]};
|
|
endcase
|
|
`ANDI: imm <= {39'h7FFFFFFFFF,dIR[24:0]};
|
`ANDI: imm <= {39'h7FFFFFFFFF,dIR[24:0]};
|
`ORI: imm <= {39'h0000000000,dIR[24:0]};
|
`ORI: imm <= {39'h0000000000,dIR[24:0]};
|
`XORI: imm <= {39'h0000000000,dIR[24:0]};
|
`XORI: imm <= {39'h0000000000,dIR[24:0]};
|
`JMP: imm <= {dpc[63:37],dIR[34:0],2'b00};
|
|
`CALL: imm <= {dpc[63:37],dIR[34:0],2'b00};
|
|
`RET: imm <= {44'h00000000000,dIR[19:0]};
|
`RET: imm <= {44'h00000000000,dIR[19:0]};
|
|
`MEMNDX: imm <= {{51{dIR[19]}},dIR[19:7]};
|
default: imm <= {{39{dIR[24]}},dIR[24:0]};
|
default: imm <= {{39{dIR[24]}},dIR[24:0]};
|
endcase
|
endcase
|
if (dOpcode[6:4]==`IMM)
|
|
xRt <= 9'd0;
|
|
case(dOpcode)
|
case(dOpcode)
|
|
|
`MISC:
|
`MISC:
|
case(dFunc)
|
case(dFunc)
|
`SEI: im <= 1'b1;
|
`SEI: im <= 1'b1;
|
`CLI: im <= 1'b0;
|
`CLI: im <= 1'b0;
|
endcase
|
endcase
|
Line 2216... |
Line 2380... |
// - fetch instruction
|
// - fetch instruction
|
// - increment PC
|
// - increment PC
|
// - set special register defaults for some instructions
|
// - set special register defaults for some instructions
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceI) begin
|
if (advanceI) begin
|
if (dOpcode[6:4]!=`IMM) begin
|
dextype <= `EX_NON;
|
|
if (iOpcode[6:4]!=`IMM) begin
|
epcnt <= epcnt + 5'd1;
|
epcnt <= epcnt + 5'd1;
|
case(epcnt)
|
case(epcnt)
|
5'd0: AXC <= EP[0][ 3: 0];
|
5'd0: AXC <= EP[0][ 3: 0];
|
5'd1: AXC <= EP[0][ 7: 4];
|
5'd1: AXC <= EP[0][ 7: 4];
|
5'd2: AXC <= EP[0][11: 8];
|
5'd2: AXC <= EP[0][11: 8];
|
Line 2265... |
Line 2430... |
else if (irq_i & !im) begin
|
else if (irq_i & !im) begin
|
dirqf <= 1'b1;
|
dirqf <= 1'b1;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
dextype <= `EX_IRQ;
|
dextype <= `EX_IRQ;
|
end
|
end
|
else if (dirqf) begin
|
// Are we filling the pipeline with NOP's as a result of a previous
|
|
// hardware interrupt ?
|
|
else if (dirqf|dFip) begin
|
|
AXC <= 4'd0;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
else begin
|
else begin
|
dIR <= insn;
|
dIR <= insn;
|
`include "insn_dump.v"
|
`include "insn_dump.v"
|
Line 2279... |
Line 2447... |
dpc <= pc_axc;
|
dpc <= pc_axc;
|
end
|
end
|
dAXC <= AXC;
|
dAXC <= AXC;
|
dRa <= {AXC,insn[34:30]};
|
dRa <= {AXC,insn[34:30]};
|
dRb <= {AXC,insn[29:25]};
|
dRb <= {AXC,insn[29:25]};
|
|
dRc <= {AXC,insn[24:20]};
|
if (ITLBMiss) begin
|
if (ITLBMiss) begin
|
dextype <= `EX_TLBI;
|
CauseCode[AXC] <= `EX_TLBI;
|
StatusTLB <= 1'b1;
|
StatusEXL[AXC] <= 1'b1;
|
StatusEXL <= 1'b1;
|
BadVAddr[AXC] <= pc_axc[63:13];
|
BadVAddr <= pc_axc[63:13];
|
|
pc[AXC] <= `ITLB_MissHandler;
|
pc[AXC] <= `ITLB_MissHandler;
|
tlbra <= pc_axc;
|
EPC[AXC] <= pc_axc;
|
end
|
end
|
else begin
|
else begin
|
dbranch_taken <= 1'b0;
|
dbranch_taken <= 1'b0;
|
pc[AXC] <= fnIncPC(pc_axc);
|
pc[AXC] <= fnIncPC(pc_axc);
|
case(insn[41:35])
|
case(iOpcode)
|
|
`MISC:
|
|
case(iFunc)
|
|
`FIP: dFip <= 1'b1;
|
|
default: ;
|
|
endcase
|
`JMP,`CALL:
|
`JMP,`CALL:
|
begin
|
begin
|
dbranch_taken <= 1'b1;
|
dbranch_taken <= 1'b1;
|
pc[AXC] <= jmp_tgt;
|
pc[AXC] <= jmp_tgt;
|
end
|
end
|
`RR:
|
`BTRR:
|
case(insn[6:0])
|
case(insn[4:0])
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU:
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR:
|
if (predict_taken) begin
|
if (predict_taken) begin
|
|
$display("Taking predicted branch: %h",{pc_axc[63:4] + {{42{insn[24]}},insn[24:7]},insn[6:5],2'b00});
|
dbranch_taken <= 1'b1;
|
dbranch_taken <= 1'b1;
|
pc[AXC] <= {pc_axc[63:4] + {{44{insn[17]}},insn[17:2]},insn[1:0],2'b00};
|
pc[AXC] <= {pc_axc[63:4] + {{42{insn[24]}},insn[24:7]},insn[6:5],2'b00};
|
end
|
end
|
|
default: ;
|
endcase
|
endcase
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
begin
|
begin
|
if (predict_taken) begin
|
if (predict_taken) begin
|
dbranch_taken <= 1'b1;
|
dbranch_taken <= 1'b1;
|
pc[AXC] <= {pc_axc[63:4] + {{50{insn[29]}},insn[29:20]},insn[19:18],2'b00};
|
pc[AXC] <= {pc_axc[63:4] + {{50{insn[29]}},insn[29:20]},insn[19:18],2'b00};
|
end
|
end
|
end
|
end
|
`TRAPcc: if (predict_taken) begin pc[AXC] <= `TRAP_VECTOR; dbranch_taken <= 1'b1; end
|
`TRAPcc: if (predict_taken) begin pc[AXC] <= {TBA[63:13],`GEN_TRAP_OFFSET}; dbranch_taken <= 1'b1; end
|
`TRAPcci: if (predict_taken) begin pc[AXC] <= `TRAP_VECTOR; dbranch_taken <= 1'b1; end
|
`TRAPcci: if (predict_taken) begin pc[AXC] <= {TBA[63:13],`GEN_TRAP_OFFSET}; dbranch_taken <= 1'b1; end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
//---------------------------------------------------------
|
|
// Initialize program counters
|
|
//---------------------------------------------------------
|
|
if (resetA) begin
|
|
pc[xAXC] <= `RESET_VECTOR;
|
|
xAXC <= xAXC + 4'd1;
|
|
if (xAXC==4'hF)
|
|
resetA <= 1'b0;
|
|
end
|
|
|
|
//`include "RPSTAGE.v"
|
//`include "RPSTAGE.v"
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// EXECUTE - part two:
|
// EXECUTE - part two:
|
// - override the default program counter increment for
|
// - override the default program counter increment for
|
// control flow instructions
|
// control flow instructions
|
Line 2340... |
Line 2505... |
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceX) begin
|
if (advanceX) begin
|
case(xOpcode)
|
case(xOpcode)
|
`MISC:
|
`MISC:
|
case(xFunc)
|
case(xFunc)
|
`IRET: begin
|
`ERET: begin
|
if (StatusTLB) begin
|
if (StatusEXL[xAXC]) begin
|
pc[xAXC] <= tlbra;
|
pc[xAXC] <= EPC[xAXC];
|
if (xAXC==AXC)
|
if (xAXC==AXC) begin
|
dpc[63:2] <= tlbra[63:2];
|
dpc <= EPC[xAXC];
|
if (xAXC==dAXC)
|
dIR <= `NOP_INSN;
|
xpc[63:2] <= tlbra[63:2];
|
|
StatusTLB <= 1'b0;
|
|
end
|
|
else if (StatusEXL) begin
|
|
pc[xAXC] <= ipc;
|
|
if (xAXC==AXC)
|
|
dpc[63:2] <= ipc[63:2];
|
|
if (xAXC==dAXC)
|
|
xpc[63:2] <= ipc[63:2];
|
|
end
|
end
|
StatusEXL <= 1'b0;
|
if (xAXC==dAXC) begin
|
|
xpc <= EPC[xAXC];
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
|
end
|
|
StatusEXL[xAXC] <= 1'b0;
|
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`RR:
|
`BTRR:
|
case(xFunc)
|
case(xIR[4:0])
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR:
|
// BEQ r1,r2,label
|
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR:
|
if (takb & !xbranch_taken) begin
|
if (takb & !xbranch_taken) begin
|
pc[xAXC][63:4] <= xpc[63:4] + {{44{xIR[24]}},xIR[24:9]};
|
$display("Taking branch %h",xpc[63:4] + {{42{xIR[24]}},xIR[24:7]});
|
pc[xAXC][3:2] <= xIR[8:7];
|
pc[xAXC][63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
|
|
pc[xAXC][3:2] <= xIR[6:5];
|
if (xAXC==AXC) begin
|
if (xAXC==AXC) begin
|
dpc[63:4] <= xpc[63:4] + {{44{xIR[24]}},xIR[24:9]};
|
dpc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
|
dpc[3:2] <= xIR[8:7];
|
dpc[3:2] <= xIR[6:5];
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
if (xAXC==dAXC) begin
|
if (xAXC==dAXC) begin
|
xpc[63:4] <= xpc[63:4] + {{44{xIR[24]}},xIR[24:9]};
|
xpc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
|
xpc[3:2] <= xIR[8:7];
|
xpc[3:2] <= xIR[6:5];
|
|
xIR <= `NOP_INSN;
|
|
xRt <= 9'd0;
|
|
end
|
|
end
|
|
// BEQ r1,r2,r10
|
|
`BEQR,`BNER,`BLTR,`BLER,`BGTR,`BGER,`BLTUR,`BLEUR,`BGTUR,`BGEUR://,`BANDR,`BORR,`BNRR:
|
|
if (takb) begin
|
|
pc[xAXC][63:2] <= c[63:2];
|
|
pc[xAXC][1:0] <= 2'b00;
|
|
if (xAXC==AXC) begin
|
|
dpc[63:2] <= c[63:2];
|
|
dpc[1:0] <= 2'b00;
|
|
dIR <= `NOP_INSN;
|
|
end
|
|
if (dAXC==xAXC) begin
|
|
xpc[63:2] <= c[63:2];
|
|
xpc[1:0] <= 2'b00;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
|
default: ;
|
endcase
|
endcase
|
// JMP and CALL change the program counter immediately in the IF stage.
|
// JMP and CALL change the program counter immediately in the IF stage.
|
// There's no work to do here. The pipeline does not need to be cleared.
|
// There's no work to do here. The pipeline does not need to be cleared.
|
`JMP: ;
|
`JMP: ;
|
`CALL: ;
|
`CALL: ;
|
Line 2411... |
Line 2590... |
xpc[63:2] <= b[63:2];
|
xpc[63:2] <= b[63:2];
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
|
// BEQ r1,#3,r10
|
|
`BTRI:
|
|
if (takb) begin
|
|
pc[xAXC][63:2] <= b[63:2];
|
|
pc[xAXC][1:0] <= 2'b00;
|
|
if (xAXC==AXC) begin
|
|
dpc[63:2] <= b[63:2];
|
|
dpc[1:0] <= 2'b00;
|
|
dIR <= `NOP_INSN;
|
|
end
|
|
if (dAXC==xAXC) begin
|
|
xpc[63:2] <= b[63:2];
|
|
xpc[1:0] <= 2'b00;
|
|
xIR <= `NOP_INSN;
|
|
xRt <= 9'd0;
|
|
end
|
|
end
|
|
// BEQI r1,#3,label
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
if (takb) begin
|
if (takb) begin
|
if (!xbranch_taken) begin
|
if (!xbranch_taken) begin
|
pc[xAXC][63:4] <= xpc[63:4] + {{50{xIR[29]}},xIR[29:20]};
|
pc[xAXC][63:4] <= xpc[63:4] + {{50{xIR[29]}},xIR[29:20]};
|
pc[xAXC][3:2] <= xIR[19:18];
|
pc[xAXC][3:2] <= xIR[19:18];
|
Line 2429... |
Line 2626... |
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
end
|
end
|
`BRr:
|
`TRAPcc:
|
case(xIR[29:25])
|
if (takb) begin
|
`BRAZ:
|
StatusEXL[xAXC] <= 1'b1;
|
begin
|
CauseCode[xAXC] <= `EX_TRAP;
|
pc[xAXC][63:4] <= xpc[63:4] + imm[63:4];
|
EPC[xAXC] <= xpc;
|
pc[xAXC][3:2] <= imm[3:2];
|
if (!xbranch_taken) begin
|
if (AXC==xAXC) begin
|
pc[xAXC] <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
dpc[63:4] <= xpc[63:4] + imm[63:4];
|
if (xAXC==AXC) begin
|
dpc[3:2] <= imm[3:2];
|
dpc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
if (dAXC==xAXC) begin
|
if (xAXC==dAXC) begin
|
xpc[63:4] <= xpc[63:4] + imm[63:4];
|
xpc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
xpc[3:2] <= imm[3:2];
|
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
`BEQZ,`BNEZ,`BLTZ,`BLEZ,`BGTZ,`BGEZ,`BNR:
|
end
|
|
`TRAPcci:
|
if (takb) begin
|
if (takb) begin
|
pc[xAXC][63:4] <= xpc[63:4] + imm[63:4];
|
CauseCode[xAXC] <= `EX_TRAP;
|
pc[xAXC][3:2] <= imm[3:2];
|
StatusEXL[xAXC] <= 1'b1;
|
if (AXC==xAXC) begin
|
EPC[xAXC] <= xpc;
|
dpc[63:4] <= xpc[63:4] + imm[63:4];
|
if (!xbranch_taken) begin
|
dpc[3:2] <= imm[3:2];
|
pc[xAXC] <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
|
if (xAXC==AXC) begin
|
|
dpc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
if (dAXC==xAXC) begin
|
if (xAXC==dAXC) begin
|
xpc[63:4] <= xpc[63:4] + imm[63:4];
|
xpc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
xpc[3:2] <= imm[3:2];
|
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
`BRAD,`BEQZD,`BNEZD,`BLTZD,`BLEZD,`BGTZD,`BGEZD:
|
|
if (takb) begin
|
|
pc[xAXC][63:4] <= xpc[63:4] + imm[63:4];
|
|
pc[xAXC][3:2] <= imm[3:2];
|
|
if (AXC==xAXC) begin
|
|
dpc[63:4] <= xpc[63:4] + imm[63:4];
|
|
dpc[3:2] <= imm[3:2];
|
|
dIR <= `NOP_INSN;
|
|
end
|
|
end
|
end
|
`BEQZR,`BNEZR,`BLTZR,`BLEZR,`BGTZR,`BGEZR:
|
default: ;
|
if (takb) begin
|
endcase
|
pc[xAXC][63:2] <= b[63:2];
|
if (dbz_error) begin
|
|
$display("Divide by zero error");
|
|
CauseCode[xAXC] <= `EX_DBZ;
|
|
StatusEXL[xAXC] <= 1'b1;
|
|
EPC[xAXC] <= xpc;
|
|
pc[xAXC] <= {TBA[63:13],`DBZ_TRAP_OFFSET};
|
if (xAXC==AXC) begin
|
if (xAXC==AXC) begin
|
dpc[63:2] <= b[63:2];
|
dpc <= {TBA[63:13],`DBZ_TRAP_OFFSET};
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
if (dAXC==xAXC) begin
|
if (xAXC==dAXC) begin
|
xpc[63:2] <= b[63:2];
|
xpc <= {TBA[63:13],`DBZ_TRAP_OFFSET};
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
`BEQZRD,`BNEZRD,`BLTZRD,`BLEZRD,`BGTZRD,`BGEZRD:
|
if (ovr_error) begin
|
if (takb) begin
|
$display("Overflow error");
|
pc[xAXC][63:2] <= b[63:2];
|
CauseCode[xAXC] <= `EX_OFL;
|
if (xAXC==AXC) begin
|
StatusEXL[xAXC] <= 1'b1;
|
dpc[63:2] <= b[63:2];
|
EPC[xAXC] <= xpc;
|
dIR <= `NOP_INSN;
|
pc[xAXC] <= {TBA[63:13],`OFL_TRAP_OFFSET};
|
end
|
|
end
|
|
endcase
|
|
`TRAPcc:
|
|
if (takb) begin
|
|
if (!xbranch_taken) begin
|
|
pc[xAXC] <= `TRAP_VECTOR;
|
|
if (xAXC==AXC) begin
|
if (xAXC==AXC) begin
|
dpc <= `TRAP_VECTOR;
|
dpc <= {TBA[63:13],`OFL_TRAP_OFFSET};
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
if (xAXC==dAXC) begin
|
if (xAXC==dAXC) begin
|
xpc <= `TRAP_VECTOR;
|
xpc <= {TBA[63:13],`OFL_TRAP_OFFSET};
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
end
|
end
|
`TRAPcci:
|
|
if (takb) begin
|
//---------------------------------------------------------
|
if (!xbranch_taken) begin
|
// MEMORY1 (M1') - part two:
|
pc[xAXC] <= `TRAP_VECTOR;
|
// Check for a TLB miss.
|
if (xAXC==AXC) begin
|
//---------------------------------------------------------
|
dpc <= `TRAP_VECTOR;
|
if (advanceM1) begin
|
dIR <= `NOP_INSN;
|
if (m1IsLoad|m1IsStore) begin
|
|
if (DTLBMiss) begin
|
|
$display("DTLB miss on address: %h",ea);
|
|
m1extype <= `EX_TLBD;
|
|
CauseCode[m1AXC] <= `EX_TLBD;
|
|
StatusEXL[m1AXC] <= 1'b1;
|
|
BadVAddr[m1AXC] <= ea[63:13];
|
|
EPC[m1AXC] <= m1pc;
|
|
pc[m1AXC] <= `DTLB_MissHandler;
|
|
if (m1AXC==xAXC) begin
|
|
m1pc <= `DTLB_MissHandler;
|
|
m1Opcode <= `NOPI;
|
|
m1Rt <= 9'd0;
|
end
|
end
|
if (xAXC==dAXC) begin
|
if (m1AXC==dAXC) begin
|
xpc <= `TRAP_VECTOR;
|
xpc <= `DTLB_MissHandler;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
|
if (m1AXC==AXC) begin
|
|
dpc <= `DTLB_MissHandler;
|
|
dIR <= `NOP_INSN;
|
|
end
|
end
|
end
|
end
|
end
|
default: ;
|
|
endcase
|
|
end
|
end
|
|
|
|
//---------------------------------------------------------
|
|
// MEMORY2 (M2')
|
|
//---------------------------------------------------------
|
|
if (advanceM2) begin
|
|
end
|
|
|
|
//---------------------------------------------------------
|
|
// MEMORY4 (M3')
|
|
//---------------------------------------------------------
|
|
if (advanceM3) begin
|
|
end
|
|
|
|
//---------------------------------------------------------
|
|
// MEMORY4 (M4')
|
|
// - no exceptions
|
|
//---------------------------------------------------------
|
|
if (advanceM4) begin
|
|
end
|
|
|
//((xOpcode==`TRAPcci) && takb)
|
//((xOpcode==`TRAPcci) && takb)
|
//
|
//
|
//if (xOpcode==`TRAPcci || xOpcode==`TRAPcc)
|
//if (xOpcode==`TRAPcci || xOpcode==`TRAPcc)
|
// pc_src <= `TRAP_VECTOR;
|
// pc_src <= `TRAP_VECTOR;
|
Line 2548... |
Line 2767... |
//end
|
//end
|
//else if (branchToReg)
|
//else if (branchToReg)
|
// pc_src <= b;
|
// pc_src <= b;
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// WRITEBACK - part two:
|
// WRITEBACK (WB') - part two:
|
// - vector to exception handler address
|
// - vector to exception handler address
|
|
// In the case of a hardware interrupt (NMI/IRQ) we know
|
|
// the pipeline following the interrupt is filled with
|
|
// NOP instructions. This means there is no need to
|
|
// invalidate the pipeline.
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceW) begin
|
if (advanceW) begin
|
if (wirqf) begin
|
if (wextype!=`EX_NON) begin
|
case(wextype)
|
case(wextype)
|
`EX_NON: ; // Dont' vector without an exception!
|
`EX_RST:
|
`EX_RST: pc[AXC] <= `RESET_VECTOR;
|
begin
|
`EX_NMI: pc[AXC] <= `NMI_VECTOR;
|
StatusEXL[0] <= 1'b1;
|
`EX_IRQ: pc[AXC] <= `IRQ_VECTOR;
|
EPC[0] <= pc[0];
|
|
pc[0] <= `RESET_VECTOR;
|
|
AXC <= 4'd0;
|
|
end
|
|
`EX_NMI:
|
|
begin
|
|
StatusEXL[0] <= 1'b1;
|
|
EPC[0] <= pc[0];
|
|
pc[0] <= `NMI_VECTOR;
|
|
AXC <= 4'd0;
|
|
end
|
|
`EX_IRQ:
|
|
begin
|
|
StatusEXL[0] <= 1'b1;
|
|
EPC[0] <= pc[0];
|
|
pc[0] <= `IRQ_VECTOR;
|
|
AXC <= 4'd0;
|
|
end
|
default: ;//pc[63:2] <= exception_address[63:2];
|
default: ;//pc[63:2] <= exception_address[63:2];
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
|
|
|
//---------------------------------------------------------
|
|
// Trailer (TR')
|
|
// - no exceptions
|
|
//---------------------------------------------------------
|
|
if (advanceT) begin
|
|
end
|
|
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Cache loader
|
// Cache loader
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (rst_i) begin
|
if (rst_i) begin
|
cstate <= IDLE;
|
cstate <= IDLE;
|
// wr_icache <= 1'b0;
|
// wr_icache <= 1'b0;
|
wr_dcache <= 1'b0;
|
wr_dcache <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
cmd_en <= 1'b0; // allow this signal only to pulse for a single clock cycle
|
|
//wr_icache <= 1'b0;
|
//wr_icache <= 1'b0;
|
wr_dcache <= 1'b0;
|
wr_dcache <= 1'b0;
|
case(cstate)
|
case(cstate)
|
IDLE:
|
IDLE:
|
// we can't do anything until the command buffer is available
|
// we can't do anything until the command buffer is available
|
Line 2590... |
Line 2838... |
dadr_o <= {pea[63:5],5'b00000};
|
dadr_o <= {pea[63:5],5'b00000};
|
cmd_bl <= 6'd8; // Eight words per cache line
|
cmd_bl <= 6'd8; // Eight words per cache line
|
cstate <= DCACT;
|
cstate <= DCACT;
|
end
|
end
|
else if (triggerICacheLoad) begin
|
else if (triggerICacheLoad) begin
|
|
if (!ppc[63]) begin
|
icaccess <= 1'b1;
|
icaccess <= 1'b1;
|
cmd_en <= 1'b1; // the command fifo should always be available
|
cmd_en <= 1'b1; // the command fifo should always be available
|
cmd_instr <= 3'b001; // READ
|
cmd_instr <= 3'b001; // READ
|
cmd_byte_addr <= {ppc[29:6],6'h00};
|
cmd_byte_addr <= {ppc[29:6],6'h00};
|
iadr_o <= {ppc[63:6],6'h00};
|
iadr_o <= {ppc[63:6],6'h00};
|
cmd_bl <= 6'd16; // Sixteen words per cache line
|
cmd_bl <= 6'd16; // Sixteen words per cache line
|
cstate <= ICACT;
|
cstate <= ICACT;
|
end
|
end
|
|
else begin
|
|
iciaccess <= 1'b1;
|
|
bte_o <= 2'b00; // linear burst
|
|
cti_o <= 3'b010; // burst access
|
|
cyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
adr_o <= {ppc[63:6],6'h00};
|
|
iadr_o <= {ppc[63:6],6'h00};
|
|
cstate <= ICACT1;
|
|
end
|
|
end
|
end
|
end
|
// Sometime after the read command is issued, the read fifo will begin to fill
|
// Sometime after the read command is issued, the read fifo will begin to fill
|
ICACT:
|
ICACT:
|
begin
|
begin
|
rd_en <= 1'b1;
|
rd_en <= 1'b1;
|
Line 2636... |
Line 2896... |
else begin
|
else begin
|
icaccess <= 1'b0;
|
icaccess <= 1'b0;
|
rd_en <= 1'b0;
|
rd_en <= 1'b0;
|
cstate <= IDLE;
|
cstate <= IDLE;
|
end
|
end
|
// Sometime after the read command is issued, the read fifo will begin to fill
|
|
|
// WISHBONE burst accesses
|
|
//
|
|
ICACT1:
|
|
if (ack_i) begin
|
|
adr_o[5:2] <= adr_o[5:2] + 4'd1;
|
|
iadr_o[5:2] <= iadr_o[5:2] + 4'd1;
|
|
if (adr_o[5:2]==4'hE)
|
|
cti_o <= 3'b111; // Last cycle ahead
|
|
if (adr_o[5:2]==4'hF) begin
|
|
cti_o <= 3'b000; // back to non-burst mode
|
|
cyc_o <= 1'b0;
|
|
stb_o <= 1'b0;
|
|
tmem[iadr_o[12:6]] <= {1'b1,iadr_o[63:13]}; // This will cause ihit to go high
|
|
tvalid[iadr_o[12:6]] <= 1'b1;
|
|
iciaccess <= 1'b0;
|
|
cstate <= IDLE;
|
|
end
|
|
end
|
|
|
DCACT:
|
DCACT:
|
begin
|
begin
|
rd_en <= 1'b1; // Data should be available on the next clock cycle
|
rd_en <= 1'b1; // Data should be available on the next clock cycle
|
cstate <= DCACT0;
|
cstate <= DCACT0;
|
end
|
end
|