Line 31... |
Line 31... |
`define DTLB_MissHandler 64'hFFFF_FFFF_FFFF_FFB0
|
`define DTLB_MissHandler 64'hFFFF_FFFF_FFFF_FFB0
|
|
|
`define GEN_TRAP_OFFSET 13'h0200
|
`define GEN_TRAP_OFFSET 13'h0200
|
`define DBZ_TRAP_OFFSET 13'h0050
|
`define DBZ_TRAP_OFFSET 13'h0050
|
`define OFL_TRAP_OFFSET 13'h0070
|
`define OFL_TRAP_OFFSET 13'h0070
|
|
`define PRIV_OFFSET 13'h0080
|
|
|
`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_TRAP 8'd4
|
|
`define EX_PRIV 8'd5 // priviledge violation
|
`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 EX_TLBD 8'd20 // TLB exception - data
|
|
|
Line 69... |
Line 71... |
`define IRQ 7'd1
|
`define IRQ 7'd1
|
`define FIP 7'd20
|
`define FIP 7'd20
|
`define IRET 7'd32
|
`define IRET 7'd32
|
`define ERET 7'd33
|
`define ERET 7'd33
|
`define WAIT 7'd40
|
`define WAIT 7'd40
|
|
`define TLBP 7'd49
|
`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
|
`define SEI 7'd65
|
`define SEI 7'd65
|
Line 95... |
Line 98... |
`define MTSPR 7'd41
|
`define MTSPR 7'd41
|
`define TLBIndex 6'd01
|
`define TLBIndex 6'd01
|
`define TLBRandom 6'd02
|
`define TLBRandom 6'd02
|
`define PageTableAddr 6'd04
|
`define PageTableAddr 6'd04
|
`define BadVAddr 6'd08
|
`define BadVAddr 6'd08
|
`define TLBPhysPage 6'd10
|
`define TLBPhysPage0 6'd10
|
`define TLBVirtPage 6'd11
|
`define TLBPhysPage1 6'd11
|
`define TLBPageMask 6'd12
|
`define TLBVirtPage 6'd12
|
`define TLBASID 6'd13
|
`define TLBPageMask 6'd13
|
`define ASID 6'd14
|
`define TLBASID 6'd14
|
`define Wired 6'd15
|
`define ASID 6'd15
|
`define EP0 6'd16
|
`define Wired 6'd16
|
`define EP1 6'd17
|
`define EP0 6'd17
|
`define EP2 6'd18
|
`define EP1 6'd18
|
`define EP3 6'd19
|
`define EP2 6'd19
|
`define AXC 6'd20
|
`define EP3 6'd20
|
`define Tick 6'd21
|
`define AXC 6'd21
|
`define EPC 6'd22
|
`define Tick 6'd22
|
`define CauseCode 6'd23
|
`define EPC 6'd23
|
`define TBA 6'd24
|
`define CauseCode 6'd24
|
|
`define TBA 6'd25
|
`define OMG 7'd50
|
`define OMG 7'd50
|
`define CMG 7'd51
|
`define CMG 7'd51
|
`define OMGI 7'd52
|
`define OMGI 7'd52
|
`define CMGI 7'd53
|
`define CMGI 7'd53
|
`define MFTBA 7'd58
|
`define MFTBA 7'd58
|
Line 179... |
Line 183... |
`define BFCHG 7'd11
|
`define BFCHG 7'd11
|
|
|
`define ADDI 7'd4
|
`define ADDI 7'd4
|
`define ADDUI 7'd5
|
`define ADDUI 7'd5
|
`define SUBI 7'd6
|
`define SUBI 7'd6
|
`define CMPI 7'd7
|
`define SUBUI 7'd7
|
`define CMPUI 7'd8
|
`define CMPI 7'd8
|
`define ANDI 7'd9
|
`define CMPUI 7'd9
|
`define ORI 7'd10
|
`define ANDI 7'd10
|
`define XORI 7'd11
|
`define ORI 7'd11
|
|
`define XORI 7'd12
|
`define MULUI 7'd12
|
|
`define MULSI 7'd13
|
`define MULUI 7'd13
|
`define DIVUI 7'd14
|
`define MULSI 7'd14
|
`define DIVSI 7'd15
|
`define DIVUI 7'd15
|
|
`define DIVSI 7'd16
|
|
|
`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 TGE 7'd3
|
`define TGT 7'd4
|
`define TLE 7'd4
|
`define TGE 7'd5
|
`define TGT 7'd5
|
`define TLO 7'd6
|
`define TLTU 7'd6
|
`define TLS 7'd7
|
`define TGEU 7'd7
|
`define THI 7'd8
|
`define TLEU 7'd8
|
`define THS 7'd9
|
`define TGTU 7'd9
|
`define TRAP 7'd10
|
`define TRAP 7'd10
|
`define TRN 7'd11
|
`define TRN 7'd11
|
`define TRAPcci 7'd18
|
`define TRAPcci 7'd18
|
`define TEQI 5'd0
|
`define TEQI 5'd0
|
`define TNEI 5'd1
|
`define TNEI 5'd1
|
`define TLTI 5'd2
|
`define TLTI 5'd2
|
`define TLEI 5'd3
|
`define TGEI 5'd3
|
`define TGTI 5'd4
|
`define TLEI 5'd4
|
`define TGEI 5'd5
|
`define TGTI 5'd5
|
`define TLOI 5'd6
|
`define TLTUI 5'd6
|
`define TLSI 5'd7
|
`define TGEUI 5'd7
|
`define THII 5'd8
|
`define TLEUI 5'd8
|
`define THSI 5'd9
|
`define TGTUI 5'd9
|
`define TRAI 5'd10
|
`define TRAI 5'd10
|
`define TRNI 5'd11
|
`define TRNI 5'd11
|
|
// SETLO=20 to 23
|
|
`define SETLO 7'b00101xx
|
`define CALL 7'd24
|
`define CALL 7'd24
|
`define JMP 7'd25
|
`define JMP 7'd25
|
`define JAL 7'd26
|
`define JAL 7'd26
|
`define RET 7'd27
|
`define RET 7'd27
|
|
// SETLO=28 to 31
|
|
`define SETHI 7'b00111xx
|
`define LB 7'd32
|
`define LB 7'd32
|
`define LC 7'd33
|
`define LC 7'd33
|
`define LH 7'd34
|
`define LH 7'd34
|
`define LW 7'd35
|
`define LW 7'd35
|
`define LP 7'd36
|
`define LP 7'd36
|
Line 256... |
Line 264... |
|
|
`define INB 7'd64
|
`define INB 7'd64
|
`define INCH 7'd65
|
`define INCH 7'd65
|
`define INH 7'd66
|
`define INH 7'd66
|
`define INW 7'd67
|
`define INW 7'd67
|
|
`define INBU 7'd68
|
|
`define INCU 7'd69
|
|
`define INHU 7'd70
|
`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
|
|
|
Line 335... |
Line 346... |
`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 Raptor64sc(rst_i, clk_i, nmi_i, irq_i,
|
module Raptor64sc(rst_i, clk_i, nmi_i, irq_i, bte_o, cti_o, bl_o,
|
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,
|
cyc_o, stb_o, ack_i, we_o, sel_o, rsv_o, adr_o, dat_i, dat_o, sys_adv, sys_adr
|
cmd_en, cmd_instr, cmd_bl, cmd_byte_addr, cmd_full,
|
|
wr_en, wr_data, wr_mask, wr_full, wr_empty,
|
|
rd_en, rd_data, rd_empty
|
|
);
|
);
|
parameter IDLE = 5'd1;
|
parameter IDLE = 5'd1;
|
parameter ICACT = 5'd2;
|
parameter ICACT = 5'd2;
|
parameter ICACT0 = 5'd3;
|
parameter ICACT0 = 5'd3;
|
parameter ICACT1 = 5'd4;
|
parameter ICACT1 = 5'd4;
|
Line 378... |
Line 384... |
|
|
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 [4:0] bl_o;
|
|
reg [4:0] bl_o;
|
output cyc_o;
|
output cyc_o;
|
reg cyc_o;
|
reg cyc_o;
|
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 [3:0] sel_o;
|
output [7:0] sel_o;
|
reg [3:0] sel_o;
|
reg [7:0] sel_o;
|
output rsv_o;
|
output rsv_o;
|
reg rsv_o;
|
reg rsv_o;
|
output [31:0] adr_o;
|
output [63:0] adr_o;
|
reg [31:0] adr_o;
|
reg [63:0] adr_o;
|
input [31:0] dat_i;
|
input [63:0] dat_i;
|
output [31:0] dat_o;
|
output [63:0] dat_o;
|
reg [31:0] dat_o;
|
reg [63:0] dat_o;
|
|
|
input sys_adv;
|
input sys_adv;
|
input [63:5] sys_adr;
|
input [63:5] sys_adr;
|
|
|
output cmd_en;
|
|
reg cmd_en;
|
|
output [2:0] cmd_instr;
|
|
reg [2:0] cmd_instr;
|
|
output [5:0] cmd_bl;
|
|
reg [5:0] cmd_bl;
|
|
output [29:0] cmd_byte_addr;
|
|
reg [29:0] cmd_byte_addr;
|
|
input cmd_full;
|
|
output wr_en;
|
|
reg wr_en;
|
|
output [31:0] wr_data;
|
|
reg [31:0] wr_data;
|
|
output [3:0] wr_mask;
|
|
reg [3:0] wr_mask;
|
|
input wr_full;
|
|
input wr_empty;
|
|
output rd_en;
|
|
reg rd_en;
|
|
input [31:0] rd_data;
|
|
input rd_empty;
|
|
|
|
reg resetA;
|
reg resetA;
|
reg im; // interrupt mask
|
reg im,bu_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 [63:0] pc;
|
reg [63:0] pc;
|
reg [63:0] ErrorEPC,EPC;
|
reg [63:0] ErrorEPC,EPC,IPC;
|
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,dRc;
|
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;
|
Line 441... |
Line 427... |
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] mutex_gate;
|
reg [63:0] TBA;
|
reg [63:0] TBA;
|
|
reg [1:0] dhwxtype,xhwxtype,m1hwxtype,m2hwxtype,m3hwxtype,m4hwxtype,whwxtype;
|
|
reg [3:0] AXC,dAXC,xAXC;
|
|
reg dtinit;
|
|
|
//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;
|
reg [41:0] insn;
|
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 StatusERL; // 1= in error processing
|
reg StatusERL; // 1= in error processing
|
reg StatusEXL; // 1= in exception processing
|
reg StatusEXL; // 1= in exception processing
|
|
reg StatusHWI; // 1= in interrupt processing
|
|
reg StatusUM; // 1= user mode
|
reg [7:0] CauseCode;
|
reg [7:0] CauseCode;
|
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;
|
reg [63:13] PageTableAddr;
|
reg [63:13] PageTableAddr;
|
reg [24:13] TLBPageMask;
|
|
reg [63:13] TLBVirtPage;
|
|
reg [63:13] TLBPhysPage;
|
|
reg [7:0] TLBASID;
|
|
reg TLBG;
|
|
reg [3:0] Index;
|
|
reg [3:0] Random;
|
|
reg [3:0] Wired;
|
|
reg [15:0] IMatch,DMatch;
|
|
|
|
function [63:0] fnIncPC;
|
function [63:0] fnIncPC;
|
input [63:0] fpc;
|
input [63:0] fpc;
|
begin
|
begin
|
case(fpc[3:2])
|
case(fpc[3:2])
|
Line 480... |
Line 461... |
2'd3: fnIncPC = {fpc[63:4]+60'd1,4'b0000};
|
2'd3: fnIncPC = {fpc[63:4]+60'd1,4'b0000};
|
endcase
|
endcase
|
end
|
end
|
endfunction
|
endfunction
|
|
|
|
wire KernelMode = StatusEXL;
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Instruction TLB
|
// TLB
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
|
reg [24:13] TLBPageMask;
|
|
reg [63:13] TLBVirtPage;
|
|
reg [63:13] TLBPhysPage0;
|
|
reg [63:13] TLBPhysPage1;
|
|
reg [7:0] TLBASID;
|
|
reg TLBG;
|
|
reg TLBD;
|
|
reg TLBValid;
|
|
reg [63:0] Index;
|
|
reg [3:0] Random;
|
|
reg [3:0] Wired;
|
|
reg [15:0] IMatch,DMatch;
|
|
|
reg [4:0] m;
|
reg [4:0] m;
|
reg [3:0] i;
|
reg [3:0] i;
|
reg [24:13] ITLBPageMask [15:0];
|
reg [24:13] ITLBPageMask [15:0];
|
reg [63:13] ITLBVirtPage [15:0];
|
reg [63:13] ITLBVirtPage [15:0];
|
reg [63:13] ITLBPhysPage [15:0];
|
reg [63:13] ITLBPhysPage0 [15:0];
|
|
reg [63:13] ITLBPhysPage1 [15:0];
|
reg [15:0] ITLBG;
|
reg [15:0] ITLBG;
|
|
reg [15:0] ITLBD;
|
reg [7:0] ITLBASID [15:0];
|
reg [7:0] ITLBASID [15:0];
|
reg [15:0] ITLBValid;
|
reg [15:0] ITLBValid;
|
initial begin
|
initial begin
|
for (n = 0; n < 16; n = n + 1)
|
for (n = 0; n < 16; n = n + 1)
|
begin
|
begin
|
ITLBPageMask[n] = 0;
|
ITLBPageMask[n] = 0;
|
ITLBVirtPage[n] = 0;
|
ITLBVirtPage[n] = 0;
|
ITLBPhysPage[n] = 0;
|
ITLBPhysPage0[n] = 0;
|
|
ITLBPhysPage1[n] = 0;
|
ITLBG[n] = 0;
|
ITLBG[n] = 0;
|
ITLBASID[n] = 0;
|
ITLBASID[n] = 0;
|
ITLBValid[n] = 0;
|
ITLBValid[n] = 0;
|
end
|
end
|
end
|
end
|
Line 527... |
Line 526... |
else if (IMatch[13]) m <= 5'd13;
|
else if (IMatch[13]) m <= 5'd13;
|
else if (IMatch[14]) m <= 5'd14;
|
else if (IMatch[14]) m <= 5'd14;
|
else if (IMatch[15]) m <= 5'd15;
|
else if (IMatch[15]) m <= 5'd15;
|
else m <= 5'd31;
|
else m <= 5'd31;
|
|
|
|
wire ioddpage = |({ITLBPageMask[q]+19'd1,13'd0}&pc);
|
|
wire [63:13] IPFN = ioddpage ? ITLBPhysPage1[q] : ITLBPhysPage0[q];
|
|
|
wire unmappedArea = pc[63:52]==12'hFFD || pc[63:52]==12'hFFE || pc[63:52]==12'hFFF;
|
wire unmappedArea = pc[63:52]==12'hFFD || pc[63:52]==12'hFFE || pc[63:52]==12'hFFF;
|
wire [63:0] ppc;
|
wire [63:0] ppc;
|
wire ITLBMiss = !unmappedArea & m[4];
|
wire ITLBMiss = !unmappedArea & m[4];
|
|
|
assign ppc[63:13] = unmappedArea ? pc[63:13] : m[4] ? `TLBMissPage: ITLBPhysPage[m];
|
assign ppc[63:13] = unmappedArea ? pc[63:13] : m[4] ? `TLBMissPage: IPFN;
|
assign ppc[12:0] = pc[12:0];
|
assign ppc[12:0] = pc[12:0];
|
|
|
//-----------------------------------------------------------------------------
|
|
// Data TLB
|
|
//-----------------------------------------------------------------------------
|
|
|
|
reg [4:0] q;
|
reg [4:0] q;
|
reg [24:13] DTLBPageMask [15:0];
|
|
reg [63:13] DTLBVirtPage [15:0];
|
|
reg [63:13] DTLBPhysPage [15:0];
|
|
reg [15:0] DTLBG;
|
|
reg [7:0] DTLBASID [15:0];
|
|
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]|ITLBPageMask[n])==(ITLBVirtPage[n]|ITLBPageMask[n])) &&
|
((DTLBASID[n]==ASID) || DTLBG[n]) &&
|
((ITLBASID[n]==ASID) || ITLBG[n]) &&
|
DTLBValid[n];
|
ITLBValid[n];
|
always @(DMatch)
|
always @(DMatch)
|
if (DMatch[0]) q <= 5'd0;
|
if (DMatch[0]) q <= 5'd0;
|
else if (DMatch[1]) q <= 5'd1;
|
else if (DMatch[1]) q <= 5'd1;
|
else if (DMatch[2]) q <= 5'd2;
|
else if (DMatch[2]) q <= 5'd2;
|
else if (DMatch[3]) q <= 5'd3;
|
else if (DMatch[3]) q <= 5'd3;
|
Line 580... |
Line 561... |
else if (DMatch[13]) q <= 5'd13;
|
else if (DMatch[13]) q <= 5'd13;
|
else if (DMatch[14]) q <= 5'd14;
|
else if (DMatch[14]) q <= 5'd14;
|
else if (DMatch[15]) q <= 5'd15;
|
else if (DMatch[15]) q <= 5'd15;
|
else q <= 5'd31;
|
else q <= 5'd31;
|
|
|
|
wire doddpage = |({ITLBPageMask[q]+19'd1,13'd0}&ea);
|
|
wire [63:13] DPFN = doddpage ? ITLBPhysPage1[q] : ITLBPhysPage0[q];
|
|
|
wire unmappedDataArea = ea[63:52]==12'hFFD || ea[63:52]==12'hFFE || ea[63:52]==12'hFFF;
|
wire unmappedDataArea = ea[63:52]==12'hFFD || ea[63:52]==12'hFFE || ea[63:52]==12'hFFF;
|
wire DTLBMiss = !unmappedDataArea & q[4];
|
wire DTLBMiss = !unmappedDataArea & q[4];
|
|
wire m1UnmappedDataArea = pea[63:13]>=12'hFFD;
|
|
|
wire [63:0] pea;
|
wire [63:0] pea;
|
assign pea[63:13] = unmappedDataArea ? ea[63:13] : q[4] ? `TLBMissPage: DTLBPhysPage[q];
|
assign pea[63:13] = unmappedDataArea ? ea[63:13] : q[4] ? `TLBMissPage: DPFN;
|
assign pea[12:0] = ea[12:0];
|
assign pea[12:0] = ea[12:0];
|
|
wire dram_bus = !pea[63];
|
|
wire m2_dram_bus = !m2Addr[63];
|
|
wire m3_dram_bus = !m3Addr[63];
|
|
wire m4_dram_bus = !m4Addr[63];
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Clock control
|
// Clock control
|
// - reset or NMI reenables the clock
|
// - reset or NMI reenables the clock
|
// - this circuit must be under the clk_i domain
|
// - this circuit must be under the clk_i domain
|
Line 611... |
Line 600... |
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Instruction Cache
|
// Instruction Cache
|
// 8kB
|
// 8kB
|
//
|
//
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg icaccess, iciaccess;
|
reg icaccess;
|
wire wr_icache = (!rd_empty & icaccess) | (iciaccess & ack_i);
|
|
|
//Raptor64_icache_ram_x32 u1
|
|
//(
|
|
// .clk(clk),
|
|
// .wr(icaccess & ack_i),
|
|
// .adr_i(adr_o[12:0]),
|
|
// .dat_i(dat_i),
|
|
// .pc(pc),
|
|
// .insn(insn)
|
|
//);
|
|
wire [127:0] insnbundle;
|
|
|
Raptor64_icache_ram_x32 u1
|
Raptor64_icache_ram u1
|
(
|
(
|
.clk(clk),
|
.clka(clk), // input clka
|
.wr(wr_icache),
|
.wea(icaccess & ack_i), // input [0 : 0] wea
|
.adr_i(iadr_o[12:0]),
|
.addra(adr_o[12:3]), // input [9 : 0] addra
|
.dat_i(icaccess ?rd_data : dat_i),
|
.dina(dat_i), // input [63 : 0] dina
|
.pc(pc),
|
.clkb(~clk), // input clkb
|
.insn(insn)
|
.addrb(pc[12:4]), // input [9 : 0] addrb
|
|
.doutb(insnbundle) // output [63 : 0] doutb
|
);
|
);
|
|
|
|
always @(pc or insnbundle)
|
|
begin
|
|
case(pc[3:2])
|
|
2'd0: insn <= insnbundle[ 41: 0];
|
|
2'd1: insn <= insnbundle[ 83:42];
|
|
2'd2: insn <= insnbundle[125:84];
|
|
2'd3: insn <= 42'h37800000000; // NOP instruction
|
|
endcase
|
|
end
|
|
|
|
|
reg [63:13] tmem [127:0];
|
reg [63:13] tmem [127:0];
|
reg [127:0] tvalid;
|
reg [127:0] tvalid;
|
|
|
initial begin
|
initial begin
|
for (n=0; n < 128; n = n + 1)
|
for (n=0; n < 128; n = n + 1)
|
Line 645... |
Line 656... |
// Data Cache
|
// Data Cache
|
// No-allocate on write
|
// No-allocate on write
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg dcaccess;
|
reg dcaccess;
|
wire dhit;
|
wire dhit;
|
wire [13:0] dtign;
|
wire [64:15] dtgout;
|
wire [64:14] dtgout;
|
|
reg wrhit;
|
reg wrhit;
|
reg [7:0] dsel_o;
|
reg [7:0] dsel_o;
|
reg [63:0] dadr_o;
|
reg [63:0] dadr_o;
|
reg [31:0] ddat;
|
reg [31:0] ddat;
|
reg wr_dcache;
|
reg wr_dcache;
|
|
|
// cache RAM 16Kb
|
// cache RAM 16Kb
|
|
/*Raptor64_dcache_ram u10
|
|
(
|
|
.clk(clk),
|
|
.wr(dcaccess ? wr_dcache : wrhit ? (dram_bus ? wr_en: we_o): 1'b0),
|
|
.sel(dcaccess ? 4'b1111 : wrhit ? ~wr_mask : 4'b0000),
|
|
.wadr(dcaccess ? dadr_o[13:2] : wr_addr[13:2]),
|
|
.i(dcaccess ? ddat : wr_data),
|
|
.radr(pea[13:3]),
|
|
.o(cdat)
|
|
);
|
|
*/
|
Raptor64_dcache_ram u10
|
Raptor64_dcache_ram u10
|
(
|
(
|
.clk(clk),
|
.clka(clk), // input clka
|
.wr(dcaccess ? wr_dcache : wrhit ? wr_en : 1'b0),
|
.ena(1'b1),
|
.sel(dcaccess ? 4'b1111 : wrhit ? ~wr_mask : 4'b0000),
|
.wea(dcaccess ? {8{ack_i}} : wrhit ? sel_o : 8'h00), // input [7 : 0] wea
|
.wadr(dcaccess ? dadr_o[13:2] : wr_addr[13:2]),
|
.addra(adr_o[14:3]), // input [11 : 0] addra
|
.i(dcaccess ? ddat : wr_data),
|
.dina(dcaccess ? dat_i : dat_o), // input [63 : 0] dina
|
.radr(pea[13:3]),
|
|
.o(cdat)
|
.clkb(~clk), // input clkb
|
|
.addrb(adr_o[14:3]), // input [11 : 0] addrb
|
|
.doutb(cdat) // output [63 : 0] doutb
|
);
|
);
|
|
|
// tag ram
|
|
syncRam512x64_1rw1r u11
|
|
(
|
|
.wrst(1'b0),
|
|
.wclk(clk),
|
|
.wce(dadr_o[4:2]==3'b111),
|
|
.we(wr_dcache),
|
|
.wadr(dadr_o[13:5]),
|
|
.i({14'h3FFF,dadr_o[63:14]}),
|
|
.wo(),
|
|
|
|
.rrst(1'b0),
|
Raptor64_dcache_tagram u11
|
.rclk(~clk),
|
(
|
.rce(1'b1),
|
.clka(clk), // input clka
|
.radr(pea[13:5]),
|
.ena(dtinit | (adr_o[5:3]==3'b111)), // input ena
|
.ro({dtign,dtgout})
|
.wea(dtinit | (dcaccess & ack_i)), // input [0 : 0] wea
|
|
.addra({1'b0,adr_o[14:6]}), // input [9 : 0] addra
|
|
.dina(dtinit ? {1'b0,adr_o[63:15]} : {1'b1,adr_o[63:15]}), // input [48 : 0] dina
|
|
|
|
.clkb(~clk), // input clkb
|
|
.addrb({1'b0,pea[14:6]}), // input [9 : 0] addrb
|
|
.doutb(dtgout) // output [48 : 0] doutb
|
);
|
);
|
|
// tag ram
|
|
//syncRam512x64_1rw1r u11
|
|
//(
|
|
// .wrst(1'b0),
|
|
// .wclk(clk),
|
|
// .wce(adr_o[4:2]==3'b111),
|
|
// .we(ack_i),
|
|
// .wadr(adr_o[14:5]),
|
|
// .i({14'h3FFF,dadr_o[63:14]}),
|
|
// .wo(),
|
|
//
|
|
// .rrst(1'b0),
|
|
// .rclk(~clk),
|
|
// .rce(1'b1),
|
|
// .radr(pea[13:5]),
|
|
// .ro({dtign,dtgout})
|
|
//);
|
|
|
assign dhit = (dtgout=={1'b1,pea[63:14]});
|
assign dhit = (dtgout=={1'b1,pea[63:15]});
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
reg [64:0] xData;
|
reg [64:0] xData;
|
Line 946... |
Line 982... |
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)
|
`BTRR:
|
`BTRR:
|
case(xFunc)
|
case(xIR[4:0])
|
`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;
|
`BLT: takb = lt;
|
`BLT: takb = lt;
|
Line 1010... |
Line 1046... |
`TNE: takb = !eq;
|
`TNE: takb = !eq;
|
`TLT: takb = lt;
|
`TLT: takb = lt;
|
`TLE: takb = lt|eq;
|
`TLE: takb = lt|eq;
|
`TGT: takb = !(lt|eq);
|
`TGT: takb = !(lt|eq);
|
`TGE: takb = !lt;
|
`TGE: takb = !lt;
|
`TLO: takb = ltu;
|
`TLTU: takb = ltu;
|
`TLS: takb = ltu|eq;
|
`TLEU: takb = ltu|eq;
|
`THI: takb = !(ltu|eq);
|
`TGTU: takb = !(ltu|eq);
|
`THS: takb = !ltu;
|
`TGEU: takb = !ltu;
|
default: takb = 1'b0;
|
default: takb = 1'b0;
|
endcase
|
endcase
|
`TRAPcci:
|
`TRAPcci:
|
case(xIR[29:25])
|
case(xIR[29:25])
|
`TEQI: takb = eqi;
|
`TEQI: takb = eqi;
|
`TNEI: takb = !eqi;
|
`TNEI: takb = !eqi;
|
`TLTI: takb = lti;
|
`TLTI: takb = lti;
|
`TLEI: takb = lti|eqi;
|
`TLEI: takb = lti|eqi;
|
`TGTI: takb = !(lti|eqi);
|
`TGTI: takb = !(lti|eqi);
|
`TGEI: takb = !lti;
|
`TGEI: takb = !lti;
|
`TLOI: takb = ltui;
|
`TLTUI: takb = ltui;
|
`TLSI: takb = ltui|eqi;
|
`TLEUI: takb = ltui|eqi;
|
`THII: takb = !(ltui|eqi);
|
`TGTUI: takb = !(ltui|eqi);
|
`THSI: takb = !ltui;
|
`TGEUI: takb = !ltui;
|
default: takb = 1'b0;
|
default: takb = 1'b0;
|
endcase
|
endcase
|
default:
|
default:
|
takb = 1'b0;
|
takb = 1'b0;
|
endcase
|
endcase
|
Line 1070... |
Line 1106... |
.o(shfto),
|
.o(shfto),
|
.mo(masko)
|
.mo(masko)
|
);
|
);
|
|
|
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 AXC 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 TLBPhysPage0 or TLBPhysPage1 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:
|
casex(xFunc)
|
casex(xFunc)
|
Line 1114... |
Line 1150... |
`MFSPR:
|
`MFSPR:
|
case(xIR[12:7])
|
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};
|
`TLBPhysPage0: xData = {TLBPhysPage0,13'd0};
|
|
`TLBPhysPage1: xData = {TLBPhysPage1,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: begin
|
|
xData = 65'd0;
|
|
xData[0] = TLBValid;
|
|
xData[1] = TLBD;
|
|
xData[2] = TLBG;
|
|
xData[15:8] = TLBASID;
|
|
end
|
`PageTableAddr: xData = {PageTableAddr,13'd0};
|
`PageTableAddr: xData = {PageTableAddr,13'd0};
|
`BadVAddr: xData = {BadVAddr,13'd0};
|
`BadVAddr: xData = {BadVAddr,13'd0};
|
`ASID: xData = ASID;
|
`ASID: xData = ASID;
|
`Tick: xData = tick;
|
`Tick: xData = tick;
|
`EPC: xData = EPC;
|
`EPC: xData = EPC;
|
`CauseCode: xData = CauseCode;
|
`CauseCode: xData = CauseCode;
|
`TBA: xData = TBA;
|
`TBA: xData = TBA;
|
|
`AXC: xData = xAXC;
|
default: xData = 65'd0;
|
default: xData = 65'd0;
|
endcase
|
endcase
|
`OMG: xData = mutex_gate[a[5:0]];
|
`OMG: xData = mutex_gate[a[5:0]];
|
`CMG: xData = mutex_gate[a[5:0]];
|
`CMG: xData = mutex_gate[a[5:0]];
|
`OMGI: xData = mutex_gate[xIR[12:7]];
|
`OMGI: begin
|
|
xData = mutex_gate[xIR[12:7]];
|
|
$display("mutex_gate[%d]=%d",xIR[12:7],mutex_gate[xIR[12:7]]);
|
|
end
|
`CMGI: xData = mutex_gate[xIR[12:7]];
|
`CMGI: xData = mutex_gate[xIR[12:7]];
|
default: xData = 65'd0;
|
default: xData = 65'd0;
|
endcase
|
endcase
|
`RR:
|
`RR:
|
case(xFunc)
|
case(xFunc)
|
Line 1195... |
Line 1242... |
`BFSET: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b1 : b[n]; xData[64] = 1'b0; end
|
`BFSET: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b1 : b[n]; xData[64] = 1'b0; end
|
`BFCLR: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b0 : b[n]; xData[64] = 1'b0; end
|
`BFCLR: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b0 : b[n]; xData[64] = 1'b0; end
|
`BFCHG: begin for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? ~b[n] : b[n]; xData[64] = 1'b0; end
|
`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
|
|
`SETLO: xData = {{32{xIR[31]}},xIR[31:0]};
|
|
`SETHI: xData = {xIR[31:0],a[31:0]};
|
`ADDI: xData = a + imm;
|
`ADDI: xData = a + imm;
|
`ADDUI: xData = a + imm;
|
`ADDUI: xData = a + imm;
|
`SUBI: xData = a - imm;
|
`SUBI: xData = a - imm;
|
|
`SUBUI: 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];
|
`DIVSI: xData = div_q;
|
`DIVSI: xData = div_q;
|
Line 1239... |
Line 1289... |
`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 v_ri,v_rr;
|
wire ovr_error = (xOpcode==`ADDI || xOpcode==`SUBI) && (xData[64]!=xData[63]);
|
overflow u2 (.op(xOpcode==`SUBI), .a(a[63]), .b(imm[63]), .s(xData[63]), .v(v_ri));
|
|
overflow u3 (.op(xOpcode==`RR && xFunc==`SUB), .a(a[63]), .b(b[63]), .s(xData[63]), .v(v_rr));
|
|
|
|
wire dbz_error = (xOpcode==`DIVSI||xOpcode==`DIVUI) && b==64'd0;
|
|
wire ovr_error = ((xOpcode==`ADDI || xOpcode==`SUBI) || (xOpcode==`RR && (xFunc==`SUB || xFunc==`ADD))) && v_ri;
|
|
wire priv_violation = !KernelMode && (xOpcode==`MISC &&
|
|
(xFunc==`IRET || xFunc==`ERET || xFunc==`CLI || xFunc==`SEI ||
|
|
xFunc==`TLBP || xFunc==`TLBR || xFunc==`TLBWR || xFunc==`TLBWI
|
|
));
|
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 1276... |
Line 1333... |
m1Opcode==`LHU || m1Opcode==`LBU || m1Opcode==`LCU
|
m1Opcode==`LHU || m1Opcode==`LBU || m1Opcode==`LCU
|
;
|
;
|
wire m1IsIn =
|
wire m1IsIn =
|
m1Opcode==`INW || m1Opcode==`INH || m1Opcode==`INCH || m1Opcode==`INB
|
m1Opcode==`INW || m1Opcode==`INH || m1Opcode==`INCH || m1Opcode==`INB
|
;
|
;
|
|
wire m2IsInW = m2Opcode==`INW;
|
wire m1IsStore =
|
wire m1IsStore =
|
m1Opcode==`SW || m1Opcode==`SH || m1Opcode==`SB || m1Opcode==`SC || m1Opcode==`SWC
|
m1Opcode==`SW || m1Opcode==`SH || m1Opcode==`SB || m1Opcode==`SC || m1Opcode==`SWC
|
;
|
;
|
|
wire xIsIO =
|
|
xIsIn ||
|
|
xOpcode==`OUTW || xOpcode==`OUTH || xOpcode==`OUTC || xOpcode==`OUTB
|
|
;
|
wire m1IsIO =
|
wire m1IsIO =
|
m1IsIn ||
|
m1IsIn ||
|
m1Opcode==`OUTW || m1Opcode==`OUTH || m1Opcode==`OUTC || m1Opcode==`OUTB
|
m1Opcode==`OUTW || m1Opcode==`OUTH || m1Opcode==`OUTC || m1Opcode==`OUTB
|
;
|
;
|
wire m3IsIO =
|
|
m3Opcode==`INW || m3Opcode==`INH || m3Opcode==`INCH || m3Opcode==`INB ||
|
|
m3Opcode==`OUTW || m3Opcode==`OUTH || m3Opcode==`OUTC || m3Opcode==`OUTB
|
|
;
|
|
|
|
wire m2IsLoad =
|
wire m2IsLoad =
|
m2Opcode==`LW || m2Opcode==`LH || m2Opcode==`LB || m2Opcode==`LC || m2Opcode==`LWR ||
|
m2Opcode==`LW || m2Opcode==`LH || m2Opcode==`LB || m2Opcode==`LC || m2Opcode==`LWR ||
|
m2Opcode==`LHU || m2Opcode==`LBU || m2Opcode==`LCU
|
m2Opcode==`LHU || m2Opcode==`LBU || m2Opcode==`LCU
|
;
|
;
|
wire m3IsLoad =
|
wire m2IsStore =
|
m3Opcode==`LW || m3Opcode==`LH || m3Opcode==`LB || m3Opcode==`LC || m3Opcode==`LWR ||
|
m2Opcode==`SW || m2Opcode==`SWC || m2Opcode==`SH || m2Opcode==`SC || m2Opcode==`SB;
|
m3Opcode==`LHU || m3Opcode==`LBU || m3Opcode==`LCU
|
|
;
|
|
wire m4IsLoad = m4Opcode==`LW || m4Opcode==`LWR
|
|
;
|
|
|
|
wire xIsFPLoo = xOpcode==`FPLOO;
|
wire xIsFPLoo = xOpcode==`FPLOO;
|
|
|
|
wire xneedBus = xIsIO;
|
|
wire m1needBus = ((m1IsLoad & !dhit)| m1IsStore) || m1IsIO;
|
|
wire m2needBus = (m2IsLoad | m2IsStore);
|
|
|
// Stall on SWC allows rsf flag to be loaded for the next instruction
|
// Stall on SWC allows rsf flag to be loaded for the next instruction
|
// Currently stalls on load of R0, but doesn't need to.
|
// Currently stalls on load of R0, but doesn't need to.
|
wire xStall = ((xIsLoad||xIsIn) && ((xRt==dRa)||(xRt==dRb)||(xRt==dRt))) || xIsSWC;
|
wire StallR = (((xIsLoad||xIsIn) && ((xRt==dRa)||(xRt==dRb)||(xRt==dRt))) || xIsSWC) ||
|
wire m1Stall = ((m1IsLoad||m1IsIn) && ((m1Rt==dRa)||(m1Rt==dRb)||(m1Rt==dRt)));// || mIsSWC;
|
(((m1IsLoad||m1IsIn) && ((m1Rt==dRa)||(m1Rt==dRb)||(m1Rt==dRt)))) ||
|
wire m2Stall = ((m2IsLoad) && ((m2Rt==dRa)||(m2Rt==dRb)||(m2Rt==dRt)));// || mIsSWC;
|
(((m2IsLoad||m2IsInW) && ((m2Rt==dRa)||(m2Rt==dRb)||(m2Rt==dRt))))
|
wire m3Stall = ((m3IsLoad) && ((m3Rt==dRa)||(m3Rt==dRb)||(m3Rt==dRt)));// || mIsSWC;
|
|
wire m4Stall = ((m4IsLoad) && ((m4Rt==dRa)||(m4Rt==dRb)||(m4Rt==dRt)));// || mIsSWC;
|
|
wire eomc = dccyc ? dhit : cyc_o & !icaccess & !dcaccess ? ack_i : 1'b1; // end of memory cycle
|
|
|
|
wire m1needWritePort = m1Opcode==`SW || m1Opcode==`SWC || m1Opcode==`SH || m1Opcode==`SC || m1Opcode==`SB;
|
|
wire m2needWritePort = m2Opcode==`SW||m2Opcode==`SWC;
|
|
wire m1needCmdPort = m1IsLoad && !m1IsCacheElement;
|
|
wire m2needCmdPort = m2Opcode==`SH||m2Opcode==`SC||m2Opcode==`SB;
|
|
wire m3needCmdPort = m3Opcode==`SW || m3Opcode==`SWC;
|
|
wire m2needReadPort = m2IsLoad;
|
|
wire m3needReadPort = m3Opcode==`LW || m3Opcode==`LWR;
|
|
//wire m4needReadPort = m4Opcode==`LW || m4Opcode==`LWR;
|
|
|
|
// Stall for the write port
|
|
wire StallM1 = (m1needWritePort && m2needWritePort) || // Write port collision
|
|
// Stall on the command port
|
|
(m1needCmdPort && (m2needCmdPort||m3needCmdPort)) || // SW,SWC are still using the wr port in M2
|
|
// cache access is taking place
|
|
icaccess || dcaccess
|
|
;
|
;
|
// M3 is using the command port
|
wire StallX = xneedBus & (m1needBus|m2needBus|icaccess|dcaccess);
|
wire StallM2 = (m2needCmdPort & m3needCmdPort) | (m3needReadPort|icaccess|dcaccess);
|
wire StallM1 = m1needBus & (m2needBus|icaccess|dcaccess);
|
wire StallM3 = m3needReadPort & (icaccess|dcaccess);
|
wire StallM2 = icaccess|dcaccess;
|
|
|
wire advanceT = !resetA;
|
wire advanceT = !resetA;
|
wire advanceW = advanceT;
|
wire advanceW = advanceT;
|
wire advanceM4 = advanceW & (m4IsLoad ? !rd_empty : 1'b1);
|
wire advanceM2 = advanceW &&
|
wire advanceM3 = advanceM4 &
|
((m2IsLoad || m2IsStore) ? ack_i : 1'b1) &&
|
(m3IsIO ? ack_i : 1'b1) &
|
!StallM2
|
(m3IsLoad ? !rd_empty : 1'b1) &
|
|
!StallM3
|
|
;
|
;
|
wire advanceM2 = advanceM3 & !StallM2;
|
wire advanceM1 = advanceM2 &
|
wire advanceM1 = advanceM2
|
|
&
|
|
(m1IsIO ? ack_i : 1'b1) &
|
(m1IsIO ? ack_i : 1'b1) &
|
((m1IsLoad & !m1IsCacheElement) ? !cmd_full : 1'b1) &
|
|
((m1IsLoad & m1IsCacheElement) ? dhit : 1'b1) &
|
((m1IsLoad & m1IsCacheElement) ? dhit : 1'b1) &
|
(m1IsStore ? !wr_full : 1'b1) &
|
|
!StallM1
|
!StallM1
|
;
|
;
|
wire advanceX = advanceM1 & !cyc_o & (
|
wire advanceX = advanceM1 & (
|
xIsSqrt ? sqrt_done :
|
xIsSqrt ? sqrt_done :
|
xIsMult ? mult_done :
|
xIsMult ? mult_done :
|
xIsDiv ? div_done :
|
xIsDiv ? div_done :
|
xIsFPLoo ? fpLooDone :
|
xIsFPLoo ? fpLooDone :
|
1'b1);
|
1'b1) &
|
wire advanceR = advanceX & !xStall & !m1Stall && !m2Stall && !m3Stall && !m4Stall;
|
!StallX;
|
|
wire advanceR = advanceX & !StallR;
|
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 | iciaccess) && // caches are not active
|
!(icaccess | dcaccess) && // 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 &&
|
|
m4Opcode==`NOPI &&
|
|
wr_empty // and the write buffer is empty
|
|
;
|
;
|
// Since IMM is "sticky" we have to check for it.
|
// Since IMM is "sticky" we have to check for it.
|
wire triggerICacheLoad = !ihit & !triggerDCacheLoad & // There is a miss
|
wire triggerICacheLoad = !ihit & !triggerDCacheLoad & // There is a miss
|
(dOpcode==`NOPI || dOpcode[6:4]==`IMM) && // and the pipeline is flushed
|
(dOpcode==`NOPI || dOpcode[6:4]==`IMM) && // and the pipeline is flushed
|
(xOpcode==`NOPI || xOpcode[6:4]==`IMM) &&
|
(xOpcode==`NOPI || xOpcode[6:4]==`IMM) &&
|
m1Opcode==`NOPI &&
|
m1Opcode==`NOPI &&
|
m2Opcode==`NOPI &&
|
m2Opcode==`NOPI
|
m3Opcode==`NOPI &&
|
|
m4Opcode==`NOPI
|
|
;
|
;
|
|
wire EXexception_pending = ovr_error || dbz_error || priv_violation || xOpcode==`TRAPcci || xOpcode==`TRAPcc;
|
|
wire M1exception_pending = advanceM1 & (m1IsLoad|m1IsStore) & DTLBMiss;
|
|
wire exception_pending = EXexception_pending | M1exception_pending;
|
|
|
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 1427... |
Line 1460... |
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
adr_o <= 64'd0;
|
adr_o <= 64'd0;
|
dat_o <= 64'd0;
|
dat_o <= 64'd0;
|
dccyc <= 1'b0;
|
dccyc <= 1'b0;
|
|
|
cmd_en <= 1'b0;
|
TBA <= 64'd0;
|
cmd_instr <= 3'b001;
|
pc <= `RESET_VECTOR;
|
cmd_bl <= 6'd1;
|
|
cmd_byte_addr <= 30'd0;
|
|
|
|
rd_en <= 1'b0;
|
|
wr_en <= 1'b0;
|
|
|
|
// pc[0] <= 64'hFFFF_FFFF_FFFF_FFE0;
|
|
m1Opcode <= `NOPI;
|
m1Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m3Opcode <= `NOPI;
|
m3Opcode <= `NOPI;
|
m4Opcode <= `NOPI;
|
m4Opcode <= `NOPI;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
Line 1458... |
Line 1484... |
m4Data <= 64'd0;
|
m4Data <= 64'd0;
|
icaccess <= 1'b0;
|
icaccess <= 1'b0;
|
dcaccess <= 1'b0;
|
dcaccess <= 1'b0;
|
nopI <= 1'b0;
|
nopI <= 1'b0;
|
prev_ihit <= 1'b0;
|
prev_ihit <= 1'b0;
|
wirqf <= 1'b0;
|
dhwxtype <= 2'b00;
|
m1irqf <= 1'b0;
|
xhwxtype <= 2'b00;
|
m2irqf <= 1'b0;
|
m1hwxtype <= 2'b00;
|
m3irqf <= 1'b0;
|
m2hwxtype <= 2'b00;
|
m4irqf <= 1'b0;
|
m3hwxtype <= 2'b00;
|
|
m4hwxtype <= 2'b00;
|
|
whwxtype <= 2'b00;
|
wFip <= 1'b0;
|
wFip <= 1'b0;
|
m4Fip <= 1'b0;
|
m4Fip <= 1'b0;
|
m3Fip <= 1'b0;
|
m3Fip <= 1'b0;
|
m2Fip <= 1'b0;
|
m2Fip <= 1'b0;
|
m1Fip <= 1'b0;
|
m1Fip <= 1'b0;
|
Line 1474... |
Line 1502... |
dFip <= 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;
|
AXC <= 4'd0;
|
|
dAXC <= 4'd0;
|
xirqf <= 1'b0;
|
xirqf <= 1'b0;
|
xextype <= 8'h00;
|
xextype <= 8'h00;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xpc <= 64'd0;
|
xpc <= 64'd0;
|
a <= 64'd0;
|
a <= 64'd0;
|
Line 1486... |
Line 1515... |
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;
|
StatusEXL <= 1'b0;
|
StatusEXL <= 1'b1;
|
|
StatusHWI <= 1'b0;
|
resetA <= 1'b1;
|
resetA <= 1'b1;
|
|
mutex_gate <= 64'h0;
|
gbl_branch_hist <= 3'b000;
|
gbl_branch_hist <= 3'b000;
|
|
m1IsCacheElement <= 1'b0;
|
|
dtinit <= 1'b1;
|
end
|
end
|
else begin
|
else begin
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Initialize program counters
|
// Initialize program counters
|
|
// Initialize data tags to zero.
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (resetA) begin
|
if (resetA) begin
|
pc <= `RESET_VECTOR;
|
pc <= `RESET_VECTOR;
|
|
adr_o[14:6] <= adr_o[14:6]+9'd1;
|
|
if (adr_o[14:6]==9'h1FF) begin
|
|
dtinit <= 1'b0;
|
resetA <= 1'b0;
|
resetA <= 1'b0;
|
end
|
end
|
|
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 1545... |
Line 1581... |
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;
|
wData <= 64'd0;
|
wData <= 64'd0;
|
if (wirqf) begin
|
if (|whwxtype) begin
|
wirqf <= 1'b0;
|
dhwxtype <= 2'b00;
|
m1irqf <= 1'b0;
|
xhwxtype <= 2'b00;
|
m2irqf <= 1'b0;
|
m1hwxtype <= 2'b00;
|
m3irqf <= 1'b0;
|
m2hwxtype <= 2'b00;
|
m4irqf <= 1'b0;
|
m3hwxtype <= 2'b00;
|
xirqf <= 1'b0;
|
m4hwxtype <= 2'b00;
|
dirqf <= 1'b0;
|
whwxtype <= 2'b00;
|
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;
|
Line 1576... |
Line 1611... |
end
|
end
|
end
|
end
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
// - merge word load data into pipeline.
|
|
//---------------------------------------------------------
|
|
if (advanceM4) begin
|
|
wirqf <= m4irqf;
|
|
wFip <= m4Fip;
|
|
wextype <= m4extype;
|
|
wRt <= m4Rt;
|
|
wpc <= m4pc;
|
|
wclkoff <= m4clkoff;
|
|
wData <= m4Data;
|
|
|
|
m4Rt <= 9'd0;
|
|
m4Opcode <= `NOPI;
|
|
m4Data <= 64'd0;
|
|
m4clkoff <= 1'b0;
|
|
m4Opcode <= `NOPI;
|
|
m4extype <= `EX_NON;
|
|
if (m4extype==`EX_NON) begin
|
|
case(m4Opcode)
|
|
`LW,`LWR: begin
|
|
wData <= {rd_data,m4Data[31:0]};
|
|
rd_en <= 1'b0; // only if LW/LWR
|
|
end
|
|
default: wData <= m4Data;
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
//---------------------------------------------------------
|
|
// MEMORY:
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceM3) begin
|
if (advanceM2) begin
|
m4Opcode <= m3Opcode;
|
wData <= m2Data;
|
m4Func <= m3Func;
|
whwxtype <= m2hwxtype;
|
m4irqf <= m3irqf;
|
wextype <= m2extype;
|
m4Fip <= m3Fip;
|
wRt <= m2Rt;
|
m4extype <= m3extype;
|
wpc <= m2pc;
|
m4Rt <= m3Rt;
|
wclkoff <= m2clkoff;
|
m4pc <= m3pc;
|
wFip <= m2Fip;
|
m4clkoff <= m3clkoff;
|
|
|
|
m3Rt <= 9'd0;
|
m2Rt <= 9'd0;
|
m3Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m3Func <= 7'd0;
|
m2Func <= 7'd0;
|
m3clkoff <= 1'b0;
|
m2Addr <= 64'd0;
|
m3pc <= 64'd0;
|
m2Data <= 64'd0;
|
m4Data <= m3Data;
|
m2clkoff <= 1'b0;
|
m3Addr <= 64'd0;
|
m2pc <= 64'd0;
|
m3Data <= 64'd0;
|
m2extype <= `EX_NON;
|
m3extype <= `EX_NON;
|
if (m2extype==`EX_NON) begin
|
if (m3extype==`EX_NON) begin
|
case(m2Opcode)
|
case(m3Opcode)
|
`SH,`SC,`SB,`SW,`SWC:
|
`INW:
|
|
begin
|
begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
|
we_o <= 1'b0;
|
sel_o <= 4'h0;
|
sel_o <= 4'h0;
|
m4Data <= {dat_i,m3Data[31:0]};
|
m3Opcode <= `NOPI;
|
end
|
end
|
`OUTW:
|
`LH:
|
begin
|
begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 8'h00;
|
sel_o <= 4'h0;
|
m3Data <= sel_o[7] ? {{32{dat_i[63]}},dat_i[63:32]}:{{32{dat_i[31]}},dat_i[31: 0]};
|
|
m3Opcode <= `NOPI;
|
end
|
end
|
`LW,`LWR:
|
`LW,`LWR:
|
begin
|
begin
|
rd_en <= 1'b1;
|
cyc_o <= 1'b0;
|
m4Data <= {32'd0,rd_data};
|
stb_o <= 1'b0;
|
end
|
sel_o <= 8'h00;
|
`LH:
|
m3Data <= dat_i;
|
begin
|
m3Opcode <= `NOPI;
|
rd_en <= 1'b0;
|
|
m4Data <= {{32{rd_data[31]}},rd_data};
|
|
end
|
end
|
`LHU:
|
`LHU:
|
begin
|
begin
|
rd_en <= 1'b0;
|
cyc_o <= 1'b0;
|
m4Data <= rd_data;
|
stb_o <= 1'b0;
|
|
sel_o <= 8'h00;
|
|
m3Data <= sel_o[7] ? dat_i[63:32] : dat_i[31: 0];
|
|
m3Opcode <= `NOPI;
|
end
|
end
|
`LC:
|
`LC:
|
begin
|
begin
|
rd_en <= 1'b0;
|
cyc_o <= 1'b0;
|
case(m3Addr[1])
|
stb_o <= 1'b0;
|
1'b0: m4Data <= {{48{rd_data[15]}},rd_data[15:0]};
|
sel_o <= 8'h00;
|
1'b1: m4Data <= {{48{rd_data[31]}},rd_data[31:16]};
|
case(sel_o)
|
|
8'b00000011: m3Data <= {{48{dat_i[15]}},dat_i[15: 0]};
|
|
8'b00001100: m3Data <= {{48{dat_i[31]}},dat_i[31:16]};
|
|
8'b00110000: m3Data <= {{48{dat_i[47]}},dat_i[47:32]};
|
|
8'b11000000: m3Data <= {{48{dat_i[63]}},dat_i[63:48]};
|
|
default: m3Data <= 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
|
m3Opcode <= `NOPI;
|
end
|
end
|
`LCU:
|
`LCU:
|
begin
|
begin
|
rd_en <= 1'b0;
|
cyc_o <= 1'b0;
|
case(m3Addr[1])
|
stb_o <= 1'b0;
|
1'b0: m4Data <= {48'd0,rd_data[15:0]};
|
sel_o <= 8'h00;
|
1'b1: m4Data <= {48'd0,rd_data[31:16]};
|
case(sel_o)
|
|
8'b00000011: m3Data <= dat_i[15: 0];
|
|
8'b00001100: m3Data <= dat_i[31:16];
|
|
8'b00110000: m3Data <= dat_i[47:32];
|
|
8'b11000000: m3Data <= dat_i[63:48];
|
|
default: m3Data <= 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
|
m3Opcode <= `NOPI;
|
end
|
end
|
`LB:
|
`LB:
|
begin
|
begin
|
rd_en <= 1'b0;
|
cyc_o <= 1'b0;
|
case(m3Addr[1:0])
|
stb_o <= 1'b0;
|
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]};
|
sel_o <= 8'h00;
|
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]};
|
case(sel_o)
|
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]};
|
8'b00000001: m3Data <= {{56{dat_i[ 7]}},dat_i[ 7: 0]};
|
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]};
|
8'b00000010: m3Data <= {{56{dat_i[15]}},dat_i[15: 8]};
|
|
8'b00000100: m3Data <= {{56{dat_i[23]}},dat_i[23:16]};
|
|
8'b00001000: m3Data <= {{56{dat_i[31]}},dat_i[31:24]};
|
|
8'b00010000: m3Data <= {{56{dat_i[39]}},dat_i[39:32]};
|
|
8'b00100000: m3Data <= {{56{dat_i[47]}},dat_i[47:40]};
|
|
8'b01000000: m3Data <= {{56{dat_i[55]}},dat_i[55:48]};
|
|
8'b10000000: m3Data <= {{56{dat_i[63]}},dat_i[63:56]};
|
|
default: m3Data <= 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
|
m3Opcode = `NOPI;
|
end
|
end
|
`LBU:
|
`LBU:
|
begin
|
begin
|
case(m3Addr[1:0])
|
cyc_o <= 1'b0;
|
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]};
|
stb_o <= 1'b0;
|
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]};
|
sel_o <= 8'h00;
|
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]};
|
case(sel_o)
|
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]};
|
8'b00000001: m3Data <= dat_i[ 7: 0];
|
endcase
|
8'b00000010: m3Data <= dat_i[15: 8];
|
rd_en <= 1'b0;
|
8'b00000100: m3Data <= dat_i[23:16];
|
end
|
8'b00001000: m3Data <= dat_i[31:24];
|
`SW,`SWC:
|
8'b00010000: m3Data <= dat_i[39:32];
|
begin
|
8'b00100000: m3Data <= dat_i[47:40];
|
cmd_en <= 1'b1;
|
8'b01000000: m3Data <= dat_i[55:48];
|
cmd_instr <= 3'b000; // WRITE
|
8'b10000000: m3Data <= dat_i[63:56];
|
cmd_bl <= 6'd2; // 2-words
|
default: m3Data <= 64'hDEADDEADDEADDEAD;
|
cmd_byte_addr <= {m3Addr[29:3],3'b000};
|
|
end
|
|
default: ;
|
|
endcase
|
endcase
|
end
|
m3Opcode <= `NOPI;
|
end
|
|
|
|
//---------------------------------------------------------
|
|
// MEMORY:
|
|
//---------------------------------------------------------
|
|
if (advanceM2) begin
|
|
m3Opcode <= m2Opcode;
|
|
m3Func <= m2Func;
|
|
m3Addr <= m2Addr;
|
|
m3Data <= m2Data;
|
|
m3irqf <= m2irqf;
|
|
m3extype <= m2extype;
|
|
m3Rt <= m2Rt;
|
|
m3pc <= m2pc;
|
|
m3clkoff <= m2clkoff;
|
|
m3Fip <= m2Fip;
|
|
|
|
m2Rt <= 9'd0;
|
|
m2Opcode <= `NOPI;
|
|
m2Func <= 7'd0;
|
|
m2Addr <= 64'd0;
|
|
m2Data <= 64'd0;
|
|
m2clkoff <= 1'b0;
|
|
m2pc <= 64'd0;
|
|
m2extype <= `EX_NON;
|
|
if (m2extype==`EX_NON) begin
|
|
case(m2Opcode)
|
|
`INW:
|
|
begin
|
|
stb_o <= 1'b1;
|
|
sel_o <= 4'hF;
|
|
adr_o <= {m2Addr[63:3],3'b100};
|
|
end
|
|
`OUTW:
|
|
begin
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
sel_o <= 4'hF;
|
|
adr_o <= {m2Addr[63:3],3'b100};
|
|
dat_o <= m2Data[63:32];
|
|
end
|
|
// Load fifo with upper half of word
|
|
`SW,`SWC:
|
|
begin
|
|
wr_en <= 1'b1;
|
|
wr_data <= m2Data[63:32];
|
|
wr_mask <= 4'h0;
|
|
wr_addr <= {m2Addr[63:3],3'b100};
|
|
end
|
|
`SH,`SC,`SB:
|
|
begin
|
|
cmd_en <= 1'b1;
|
|
cmd_instr <= 3'b000; // WRITE
|
|
cmd_bl <= 6'd1; // 1-word
|
|
cmd_byte_addr <= {m2Addr[29:2],2'b00};
|
|
end
|
|
// Initiate read operation
|
|
`LW,`LWR,`LH,`LC,`LB,`LHU,`LBU,`LCU:
|
|
begin
|
|
rd_en <= 1'b1;
|
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
|
|
wrhit <= 1'b0;
|
wrhit <= 1'b0;
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
|
// - I/O instructions are finished
|
|
// - store instructions are started
|
|
// - missed loads are started
|
// On a data cache hit for a load, the load is essentially
|
// On a data cache hit for a load, the load is essentially
|
// finished in this stage. We switch the opcode to 'LDONE'
|
// finished in this stage. We switch the opcode to 'NOPI'
|
// to cause the pipeline to advance as if a NOPs were
|
// to cause the pipeline to advance as if a NOPs were
|
// present.
|
// present.
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceM1) begin
|
if (advanceM1) begin
|
m2Opcode <= m1Opcode;
|
m2Opcode <= m1Opcode;
|
m2Func <= m1Func;
|
m2Func <= m1Func;
|
m2Addr <= pea;
|
m2Addr <= pea;
|
m2Data <= m1Data;
|
m2Data <= m1Data;
|
m2irqf <= m1irqf;
|
m2hwxtype <= m1hwxtype;
|
m2extype <= m1extype;
|
m2extype <= m1extype;
|
m2Rt <= m1Rt;
|
m2Rt <= m1Rt;
|
m2pc <= m1pc;
|
m2pc <= m1pc;
|
m2clkoff <= m1clkoff;
|
m2clkoff <= m1clkoff;
|
m2Fip <= m1Fip;
|
m2Fip <= m1Fip;
|
Line 1803... |
Line 1768... |
|
|
if (m1extype == `EX_NON) begin
|
if (m1extype == `EX_NON) begin
|
case(m1Opcode)
|
case(m1Opcode)
|
`MISC:
|
`MISC:
|
case(m1Func)
|
case(m1Func)
|
|
`TLBP:
|
|
begin
|
|
Index[63] <= ~|DMatch;
|
|
end
|
`TLBR:
|
`TLBR:
|
begin
|
begin
|
TLBPageMask <= ITLBPageMask[i];
|
TLBPageMask <= ITLBPageMask[i];
|
TLBVirtPage <= ITLBVirtPage[i];
|
TLBVirtPage <= ITLBVirtPage[i];
|
TLBPhysPage <= ITLBPhysPage[i];
|
TLBPhysPage0 <= ITLBPhysPage0[i];
|
|
TLBPhysPage1 <= ITLBPhysPage1[i];
|
TLBASID <= ITLBASID[i];
|
TLBASID <= ITLBASID[i];
|
TLBG <= ITLBG[i];
|
TLBG <= ITLBG[i];
|
|
TLBD <= ITLBD[i];
|
|
TLBValid <= ITLBValid[i];
|
end
|
end
|
`TLBWI,`TLBWR:
|
`TLBWI,`TLBWR:
|
begin
|
begin
|
ITLBValid[i] <= 1'b1;
|
ITLBValid[i] <= TLBValid;
|
ITLBVirtPage[i] <= TLBVirtPage;
|
ITLBVirtPage[i] <= TLBVirtPage;
|
ITLBPhysPage[i] <= TLBPhysPage;
|
ITLBPhysPage0[i] <= TLBPhysPage0;
|
|
ITLBPhysPage1[i] <= TLBPhysPage1;
|
ITLBPageMask[i] <= TLBPageMask;
|
ITLBPageMask[i] <= TLBPageMask;
|
ITLBASID[i] <= TLBASID;
|
ITLBASID[i] <= TLBASID;
|
DTLBValid[i] <= 1'b1;
|
ITLBD[i] <= TLBD;
|
DTLBVirtPage[i] <= TLBVirtPage;
|
ITLBG[i] <= TLBG;
|
DTLBPhysPage[i] <= TLBPhysPage;
|
|
DTLBPageMask[i] <= TLBPageMask;
|
|
DTLBASID[i] <= TLBASID;
|
|
end
|
end
|
endcase
|
endcase
|
`INW:
|
`INW:
|
begin
|
begin
|
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
m2Data <= {32'd0,dat_i};
|
sel_o <= 8'h00;
|
|
m2Data <= dat_i;
|
|
m2Opcode <= `NOPI;
|
end
|
end
|
`INH:
|
`INH:
|
begin
|
begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'd0;
|
sel_o <= 8'h00;
|
m2Data <= {{32{dat_i[31]}},dat_i[31: 0]};
|
m2Data <= sel_o[7] ? {{32{dat_i[63]}},dat_i[63:32]}:{{32{dat_i[31]}},dat_i[31: 0]};
|
|
m2Opcode <= `NOPI;
|
|
end
|
|
`INHU:
|
|
begin
|
|
cyc_o <= 1'b0;
|
|
stb_o <= 1'b0;
|
|
sel_o <= 8'h00;
|
|
m2Data <= sel_o[7] ? dat_i[63:32] : dat_i[31: 0];
|
|
m2Opcode <= `NOPI;
|
end
|
end
|
`INCH:
|
`INCH:
|
begin
|
begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'd0;
|
sel_o <= 8'h00;
|
|
case(sel_o)
|
|
8'b00000011: m2Data <= {{48{dat_i[15]}},dat_i[15: 0]};
|
|
8'b00001100: m2Data <= {{48{dat_i[31]}},dat_i[31:16]};
|
|
8'b00110000: m2Data <= {{48{dat_i[47]}},dat_i[47:32]};
|
|
8'b11000000: m2Data <= {{48{dat_i[63]}},dat_i[63:48]};
|
|
default: m2Data <= 64'hDEADDEADDEADDEAD;
|
|
endcase
|
|
m2Opcode <= `NOPI;
|
|
end
|
|
`INCU:
|
|
begin
|
|
cyc_o <= 1'b0;
|
|
stb_o <= 1'b0;
|
|
sel_o <= 8'h00;
|
case(sel_o)
|
case(sel_o)
|
4'b0011: m2Data <= {{48{dat_i[15]}},dat_i[15: 0]};
|
8'b00000011: m2Data <= dat_i[15: 0];
|
4'b1100: m2Data <= {{48{dat_i[31]}},dat_i[31:16]};
|
8'b00001100: m2Data <= dat_i[31:16];
|
|
8'b00110000: m2Data <= dat_i[47:32];
|
|
8'b11000000: m2Data <= dat_i[63:48];
|
default: m2Data <= 64'hDEADDEADDEADDEAD;
|
default: m2Data <= 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
|
m2Opcode <= `NOPI;
|
end
|
end
|
`INB:
|
`INB:
|
begin
|
begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
sel_o <= 4'd0;
|
sel_o <= 8'h00;
|
case(sel_o)
|
case(sel_o)
|
4'b0001: m2Data <= {{56{dat_i[ 7]}},dat_i[ 7: 0]};
|
8'b00000001: m2Data <= {{56{dat_i[ 7]}},dat_i[ 7: 0]};
|
4'b0010: m2Data <= {{56{dat_i[15]}},dat_i[15: 8]};
|
8'b00000010: m2Data <= {{56{dat_i[15]}},dat_i[15: 8]};
|
4'b0100: m2Data <= {{56{dat_i[23]}},dat_i[23:16]};
|
8'b00000100: m2Data <= {{56{dat_i[23]}},dat_i[23:16]};
|
4'b1000: m2Data <= {{56{dat_i[31]}},dat_i[31:24]};
|
8'b00001000: m2Data <= {{56{dat_i[31]}},dat_i[31:24]};
|
|
8'b00010000: m2Data <= {{56{dat_i[39]}},dat_i[39:32]};
|
|
8'b00100000: m2Data <= {{56{dat_i[47]}},dat_i[47:40]};
|
|
8'b01000000: m2Data <= {{56{dat_i[55]}},dat_i[55:48]};
|
|
8'b10000000: m2Data <= {{56{dat_i[63]}},dat_i[63:56]};
|
default: m2Data <= 64'hDEADDEADDEADDEAD;
|
default: m2Data <= 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
|
m2Opcode <= `NOPI;
|
end
|
end
|
`OUTW:
|
`INBU:
|
begin
|
begin
|
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 8'h00;
|
sel_o <= 4'd0;
|
case(sel_o)
|
|
8'b00000001: m2Data <= dat_i[ 7: 0];
|
|
8'b00000010: m2Data <= dat_i[15: 8];
|
|
8'b00000100: m2Data <= dat_i[23:16];
|
|
8'b00001000: m2Data <= dat_i[31:24];
|
|
8'b00010000: m2Data <= dat_i[39:32];
|
|
8'b00100000: m2Data <= dat_i[47:40];
|
|
8'b01000000: m2Data <= dat_i[55:48];
|
|
8'b10000000: m2Data <= dat_i[63:56];
|
|
default: m2Data <= 64'hDEADDEADDEADDEAD;
|
|
endcase
|
|
m2Opcode <= `NOPI;
|
end
|
end
|
`OUTH,`OUTC,`OUTB:
|
`OUTW,`OUTH,`OUTC,`OUTB:
|
begin
|
begin
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= 1'b0;
|
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 4'd0;
|
sel_o <= 8'h00;
|
|
m2Opcode <= `NOPI;
|
end
|
end
|
|
|
`LW:
|
`LW:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cmd_en <= 1'b1;
|
cyc_o <= 1'b1;
|
cmd_bl <= 6'd2; // 2-words (from 32-bit interface)
|
stb_o <= 1'b1;
|
cmd_instr <= 3'b001; // READ
|
sel_o <= 8'hFF;
|
cmd_byte_addr <= {pea[63:3],3'b000};
|
adr_o <= {pea[63:3],3'b000};
|
|
m2Addr <= {pea[63:3],3'b000};
|
end
|
end
|
else if (dhit) begin
|
else if (dhit) begin
|
m2Opcode <= `LDONE;
|
m2Opcode <= `NOPI;
|
m2Data <= cdat;
|
m2Data <= cdat;
|
end
|
end
|
|
|
`LWR:
|
`LWR:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cmd_en <= 1'b1;
|
|
cmd_bl <= 6'd2; // 2-words (from 32-bit interface)
|
|
cmd_instr <= 3'b001; // READ
|
|
cmd_byte_addr <= {pea[63:3],3'b000};
|
|
rsv_o <= 1'b1;
|
rsv_o <= 1'b1;
|
resv_address <= pea[63:5];
|
resv_address <= pea[63:5];
|
|
cyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
sel_o <= 8'hFF;
|
|
adr_o <= {pea[63:3],3'b000};
|
|
m2Addr <= {pea[63:3],3'b000};
|
end
|
end
|
else if (dhit) begin
|
else if (dhit) begin
|
m2Opcode <= `LDONE;
|
m2Opcode <= `NOPI;
|
m2Data <= cdat;
|
m2Data <= cdat;
|
rsv_o <= 1'b1;
|
rsv_o <= 1'b1;
|
resv_address <= pea[63:5];
|
resv_address <= pea[63:5];
|
end
|
end
|
|
|
`LH:
|
`LH:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cmd_en <= 1'b1;
|
cyc_o <= 1'b1;
|
cmd_bl <= 6'd1; // 1-words (from 32-bit interface)
|
stb_o <= 1'b1;
|
cmd_instr <= 3'b001; // READ
|
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
|
cmd_byte_addr <= {pea[63:2],2'b00};
|
adr_o <= {pea[63:2],2'b00};
|
|
m2Addr <= {pea[63:2],2'b00};
|
end
|
end
|
else if (dhit) begin
|
else if (dhit) begin
|
m2Opcode <= `LDONE;
|
m2Opcode <= `NOPI;
|
if (pea[1])
|
if (pea[1])
|
m2Data <= {{32{cdat[31]}},cdat[31:0]};
|
m2Data <= {{32{cdat[31]}},cdat[31:0]};
|
else
|
else
|
m2Data <= {{32{cdat[63]}},cdat[63:32]};
|
m2Data <= {{32{cdat[63]}},cdat[63:32]};
|
end
|
end
|
|
|
`LHU:
|
`LHU:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cmd_en <= 1'b1;
|
cyc_o <= 1'b1;
|
cmd_bl <= 6'd1; // 1-words (from 32-bit interface)
|
stb_o <= 1'b1;
|
cmd_instr <= 3'b001; // READ
|
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
|
cmd_byte_addr <= {pea[63:2],2'b00};
|
adr_o <= {pea[63:2],2'b00};
|
|
m2Addr <= {pea[63:2],2'b00};
|
end
|
end
|
else if (dhit) begin
|
else if (dhit) begin
|
m2Opcode <= `LDONE;
|
m2Opcode <= `NOPI;
|
if (pea[1])
|
if (pea[1])
|
m2Data <= {32'd0,cdat};
|
m2Data <= {32'd0,cdat};
|
else
|
else
|
m2Data <= {32'd0,cdat[63:32]};
|
m2Data <= {32'd0,cdat[63:32]};
|
end
|
end
|
|
|
`LC:
|
`LC:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cmd_en <= 1'b1;
|
cyc_o <= 1'b1;
|
cmd_bl <= 6'd1; // 1-words (from 32-bit interface)
|
stb_o <= 1'b1;
|
cmd_instr <= 3'b001; // READ
|
case(pea[2:1])
|
cmd_byte_addr <= {pea[63:2],2'b00};
|
2'b00: sel_o <= 8'b00000011;
|
|
2'b01: sel_o <= 8'b00001100;
|
|
2'b10: sel_o <= 8'b00110000;
|
|
2'b11: sel_o <= 8'b11000000;
|
|
endcase
|
|
adr_o <= {pea[63:1],1'b0};
|
|
m2Addr <= {pea[63:1],1'b0};
|
end
|
end
|
else if (dhit) begin
|
else if (dhit) begin
|
m2Opcode <= `LDONE;
|
m2Opcode <= `NOPI;
|
case(pea[2:1])
|
case(pea[2:1])
|
2'd0: m2Data <= {{48{cdat[15]}},cdat[15:0]};
|
2'd0: m2Data <= {{48{cdat[15]}},cdat[15:0]};
|
2'd1: m2Data <= {{48{cdat[31]}},cdat[31:16]};
|
2'd1: m2Data <= {{48{cdat[31]}},cdat[31:16]};
|
2'd2: m2Data <= {{48{cdat[47]}},cdat[47:32]};
|
2'd2: m2Data <= {{48{cdat[47]}},cdat[47:32]};
|
2'd3: m2Data <= {{48{cdat[63]}},cdat[63:48]};
|
2'd3: m2Data <= {{48{cdat[63]}},cdat[63:48]};
|
endcase
|
endcase
|
end
|
end
|
|
|
`LCU:
|
`LCU:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cmd_en <= 1'b1;
|
cyc_o <= 1'b1;
|
cmd_bl <= 6'd1; // 1-words (from 32-bit interface)
|
stb_o <= 1'b1;
|
cmd_instr <= 3'b001; // READ
|
case(pea[2:1])
|
cmd_byte_addr <= {pea[63:2],2'b00};
|
2'b00: sel_o <= 8'b00000011;
|
|
2'b01: sel_o <= 8'b00001100;
|
|
2'b10: sel_o <= 8'b00110000;
|
|
2'b11: sel_o <= 8'b11000000;
|
|
endcase
|
|
adr_o <= {pea[63:1],1'b0};
|
|
m2Addr <= {pea[63:1],1'b0};
|
end
|
end
|
else if (dhit) begin
|
else if (dhit) begin
|
m2Opcode <= `LDONE;
|
m2Opcode <= `NOPI;
|
case(pea[2:1])
|
case(pea[2:1])
|
2'd0: m2Data <= {48'd0,cdat[15: 0]};
|
2'd0: m2Data <= {48'd0,cdat[15: 0]};
|
2'd1: m2Data <= {48'd0,cdat[31:16]};
|
2'd1: m2Data <= {48'd0,cdat[31:16]};
|
2'd2: m2Data <= {48'd0,cdat[47:32]};
|
2'd2: m2Data <= {48'd0,cdat[47:32]};
|
2'd3: m2Data <= {48'd0,cdat[63:48]};
|
2'd3: m2Data <= {48'd0,cdat[63:48]};
|
endcase
|
endcase
|
end
|
end
|
|
|
`LB:
|
`LB:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cmd_en <= 1'b1;
|
$display("Load byte:");
|
cmd_bl <= 6'd1; // 1-words (from 32-bit interface)
|
cyc_o <= 1'b1;
|
cmd_instr <= 3'b001; // READ
|
stb_o <= 1'b1;
|
cmd_byte_addr <= {pea[63:2],2'b00};
|
case(pea[2:0])
|
|
3'b000: sel_o <= 8'b00000001;
|
|
3'b001: sel_o <= 8'b00000010;
|
|
3'b010: sel_o <= 8'b00000100;
|
|
3'b011: sel_o <= 8'b00001000;
|
|
3'b100: sel_o <= 8'b00010000;
|
|
3'b101: sel_o <= 8'b00100000;
|
|
3'b110: sel_o <= 8'b01000000;
|
|
3'b111: sel_o <= 8'b10000000;
|
|
endcase
|
|
adr_o <= pea;
|
|
m2Addr <= pea;
|
end
|
end
|
else if (dhit) begin
|
else if (dhit) begin
|
m2Opcode <= `LDONE;
|
m2Opcode <= `NOPI;
|
case(pea[2:0])
|
case(pea[2:0])
|
3'b000: m2Data <= {{56{cdat[ 7]}},cdat[ 7: 0]};
|
3'b000: m2Data <= {{56{cdat[ 7]}},cdat[ 7: 0]};
|
3'b001: m2Data <= {{56{cdat[15]}},cdat[15: 8]};
|
3'b001: m2Data <= {{56{cdat[15]}},cdat[15: 8]};
|
3'b010: m2Data <= {{56{cdat[23]}},cdat[23:16]};
|
3'b010: m2Data <= {{56{cdat[23]}},cdat[23:16]};
|
3'b011: m2Data <= {{56{cdat[31]}},cdat[31:24]};
|
3'b011: m2Data <= {{56{cdat[31]}},cdat[31:24]};
|
Line 1980... |
Line 2031... |
3'b101: m2Data <= {{56{cdat[47]}},cdat[47:40]};
|
3'b101: m2Data <= {{56{cdat[47]}},cdat[47:40]};
|
3'b110: m2Data <= {{56{cdat[55]}},cdat[55:48]};
|
3'b110: m2Data <= {{56{cdat[55]}},cdat[55:48]};
|
3'b111: m2Data <= {{56{cdat[63]}},cdat[63:56]};
|
3'b111: m2Data <= {{56{cdat[63]}},cdat[63:56]};
|
endcase
|
endcase
|
end
|
end
|
|
|
`LBU:
|
`LBU:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
cmd_en <= 1'b1;
|
cyc_o <= 1'b1;
|
cmd_bl <= 6'd1; // 1-words (from 32-bit interface)
|
stb_o <= 1'b1;
|
cmd_instr <= 3'b001; // READ
|
case(pea[2:0])
|
cmd_byte_addr <= {pea[63:2],2'b00};
|
3'b000: sel_o <= 8'b00000001;
|
|
3'b001: sel_o <= 8'b00000010;
|
|
3'b010: sel_o <= 8'b00000100;
|
|
3'b011: sel_o <= 8'b00001000;
|
|
3'b100: sel_o <= 8'b00010000;
|
|
3'b101: sel_o <= 8'b00100000;
|
|
3'b110: sel_o <= 8'b01000000;
|
|
3'b111: sel_o <= 8'b10000000;
|
|
endcase
|
|
adr_o <= pea;
|
|
m2Addr <= pea;
|
end
|
end
|
else if (dhit) begin
|
else if (dhit) begin
|
m2Opcode <= `LDONE;
|
m2Opcode <= `NOPI;
|
case(pea[2:0])
|
case(pea[2:0])
|
3'b000: m2Data <= {56'd0,cdat[ 7: 0]};
|
3'b000: m2Data <= {56'd0,cdat[ 7: 0]};
|
3'b001: m2Data <= {56'd0,cdat[15: 8]};
|
3'b001: m2Data <= {56'd0,cdat[15: 8]};
|
3'b010: m2Data <= {56'd0,cdat[23:16]};
|
3'b010: m2Data <= {56'd0,cdat[23:16]};
|
3'b011: m2Data <= {56'd0,cdat[31:23]};
|
3'b011: m2Data <= {56'd0,cdat[31:23]};
|
Line 2000... |
Line 2062... |
3'b101: m2Data <= {56'd0,cdat[47:40]};
|
3'b101: m2Data <= {56'd0,cdat[47:40]};
|
3'b110: m2Data <= {56'd0,cdat[55:48]};
|
3'b110: m2Data <= {56'd0,cdat[55:48]};
|
3'b111: m2Data <= {56'd0,cdat[63:56]};
|
3'b111: m2Data <= {56'd0,cdat[63:56]};
|
endcase
|
endcase
|
end
|
end
|
`SW,`SH:
|
|
|
`SW:
|
begin
|
begin
|
wrhit <= dhit;
|
|
wr_en <= 1'b1;
|
|
wr_data <= m1b[31:0];
|
|
wr_mask <= 4'h0;
|
|
wr_addr <= {pea[63:3],3'b000};
|
|
m2Addr <= {pea[63:3],3'b000};
|
m2Addr <= {pea[63:3],3'b000};
|
|
wrhit <= dhit;
|
|
if (!m1UnmappedDataArea & !q[4])
|
|
ITLBD[q] <= 1'b1;
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= 59'd0;
|
resv_address <= 59'd0;
|
|
cyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
sel_o <= 8'hFF;
|
|
adr_o <= {pea[63:3],3'b000};
|
|
dat_o <= m1b;
|
|
end
|
|
|
|
`SH:
|
|
begin
|
|
wrhit <= dhit;
|
|
m2Addr <= {pea[63:2],2'b00};
|
|
if (!m1UnmappedDataArea & !q[4])
|
|
ITLBD[q] <= 1'b1;
|
|
if (resv_address==pea[63:5])
|
|
resv_address <= 59'd0;
|
|
cyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
|
|
adr_o <= {pea[63:2],2'b00};
|
|
dat_o <= {2{m1b[31:0]}};
|
end
|
end
|
|
|
`SC:
|
`SC:
|
begin
|
begin
|
$display("Storing char to %h, ea=%h",pea,ea);
|
$display("Storing char to %h, ea=%h",pea,ea);
|
wrhit <= dhit;
|
wrhit <= dhit;
|
wr_en <= 1'b1;
|
|
wr_data <= {2{m1b[15:0]}};
|
|
wr_mask <= pea[1] ? 4'b0011 : 4'b1100;
|
|
wr_addr <= {pea[63:2],2'b00};
|
|
m2Addr <= {pea[63:2],2'b00};
|
m2Addr <= {pea[63:2],2'b00};
|
|
if (!m1UnmappedDataArea & !q[4])
|
|
ITLBD[q] <= 1'b1;
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= 59'd0;
|
resv_address <= 59'd0;
|
|
cyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
case(pea[2:1])
|
|
2'b00: sel_o <= 8'b00000011;
|
|
2'b01: sel_o <= 8'b00001100;
|
|
2'b10: sel_o <= 8'b00110000;
|
|
2'b11: sel_o <= 8'b11000000;
|
|
endcase
|
|
adr_o <= {pea[63:1],1'b0};
|
|
dat_o <= {4{m1b[15:0]}};
|
end
|
end
|
|
|
`SB:
|
`SB:
|
begin
|
begin
|
wrhit <= dhit;
|
wrhit <= dhit;
|
wr_en <= 1'b1;
|
|
wr_data <= {4{m1b[7:0]}};
|
|
wr_addr <= {pea[63:2],2'b00};
|
|
m2Addr <= {pea[63:2],2'b00};
|
m2Addr <= {pea[63:2],2'b00};
|
case(pea[1:0])
|
|
2'd0: wr_mask <= 4'b1110;
|
|
2'd1: wr_mask <= 4'b1101;
|
|
2'd2: wr_mask <= 4'b1011;
|
|
2'd3: wr_mask <= 4'b0111;
|
|
endcase
|
|
if (resv_address==pea[63:5])
|
if (resv_address==pea[63:5])
|
resv_address <= 59'd0;
|
resv_address <= 59'd0;
|
|
if (!m1UnmappedDataArea & !q[4])
|
|
ITLBD[q] <= 1'b1;
|
|
cyc_o <= 1'b1;
|
|
stb_o <= 1'b1;
|
|
we_o <= 1'b1;
|
|
case(pea[2:0])
|
|
3'b000: sel_o <= 8'b00000001;
|
|
3'b001: sel_o <= 8'b00000010;
|
|
3'b010: sel_o <= 8'b00000100;
|
|
3'b011: sel_o <= 8'b00001000;
|
|
3'b100: sel_o <= 8'b00010000;
|
|
3'b101: sel_o <= 8'b00100000;
|
|
3'b110: sel_o <= 8'b01000000;
|
|
3'b111: sel_o <= 8'b10000000;
|
|
endcase
|
|
adr_o <= {pea[63:2],2'b00};
|
|
dat_o <= {8{m1b[7:0]}};
|
end
|
end
|
|
|
`SWC:
|
`SWC:
|
begin
|
begin
|
rsf <= 1'b0;
|
rsf <= 1'b0;
|
if (resv_address==pea[63:5]) begin
|
if (resv_address==pea[63:5]) begin
|
|
if (!m1UnmappedDataArea & !q[4])
|
|
ITLBD[q] <= 1'b1;
|
wrhit <= dhit;
|
wrhit <= dhit;
|
wr_en <= 1'b1;
|
m2Addr <= {pea[63:3],3'b00};
|
wr_data <= m1b[31:0];
|
cyc_o <= 1'b1;
|
wr_mask <= 4'h0;
|
stb_o <= 1'b1;
|
wr_addr <= {pea[63:3],3'b000};
|
we_o <= 1'b1;
|
m2Addr <= {pea[63:3],3'b000};
|
sel_o <= 8'hFF;
|
|
adr_o <= {pea[63:3],3'b000};
|
|
dat_o <= m1b;
|
resv_address <= 59'd0;
|
resv_address <= 59'd0;
|
rsf <= 1'b1;
|
rsf <= 1'b1;
|
end
|
end
|
else
|
else
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
Line 2062... |
Line 2169... |
end
|
end
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// EXECUTE:
|
// EXECUTE:
|
// - perform datapath operation
|
// - perform datapath operation
|
// - Stores always initiate a bus cycle
|
// - perform virtual to physical address translation.
|
// - Loads initiate a bus cycle only from non-cacheable
|
|
// addresses
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceX) begin
|
if (advanceX) begin
|
m1irqf <= xirqf;
|
m1hwxtype <= xhwxtype;
|
m1Fip <= xFip;
|
m1Fip <= xFip;
|
m1extype <= xextype;
|
m1extype <= xextype;
|
m1Opcode <= xOpcode;
|
m1Opcode <= xOpcode;
|
m1Func <= xFunc;
|
m1Func <= xFunc;
|
m1Rt <= xRt;
|
m1Rt <= xRt;
|
Line 2097... |
Line 2202... |
// xpc <= 64'd0;
|
// xpc <= 64'd0;
|
case(xOpcode)
|
case(xOpcode)
|
`MISC:
|
`MISC:
|
case(xFunc)
|
case(xFunc)
|
`WAIT: m1clkoff <= 1'b1;
|
`WAIT: m1clkoff <= 1'b1;
|
|
`TLBP: ea <= TLBVirtPage;
|
`TLBR,`TLBWI:
|
`TLBR,`TLBWI:
|
begin
|
begin
|
i <= Index;
|
i <= Index;
|
end
|
end
|
`TLBWR:
|
`TLBWR:
|
Line 2115... |
Line 2221... |
case(xIR[12:7])
|
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];
|
`TLBPhysPage0: TLBPhysPage0 <= xData[63:13];
|
|
`TLBPhysPage1: TLBPhysPage1 <= xData[63:13];
|
`TLBPageMask: TLBPageMask <= xData[24:13];
|
`TLBPageMask: TLBPageMask <= xData[24:13];
|
`TLBASID: TLBASID <= xData[7:0];
|
`TLBASID: begin
|
|
TLBValid <= xData[0];
|
|
TLBD <= xData[1];
|
|
TLBG <= xData[2];
|
|
TLBASID <= xData[15:8];
|
|
end
|
`PageTableAddr: PageTableAddr <= xData[63:13];
|
`PageTableAddr: PageTableAddr <= xData[63:13];
|
`BadVAddr: BadVAddr <= xData[63:13];
|
`BadVAddr: BadVAddr <= xData[63:13];
|
`EPC: EPC <= xData;
|
`EPC: EPC <= xData;
|
`TBA: TBA <= xData;
|
`TBA: TBA <= xData;
|
|
`AXC: AXC <= xData[3:0];
|
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;
|
`OMG: mutex_gate[a[5:0]] <= 1'b1;
|
`CMG: mutex_gate[a[5:0]] <= 1'b0;
|
`CMG: mutex_gate[a[5:0]] <= 1'b0;
|
Line 2136... |
Line 2249... |
`CALL: m1Data <= fnIncPC(xpc);
|
`CALL: m1Data <= fnIncPC(xpc);
|
`INW:
|
`INW:
|
begin
|
begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'hF;
|
sel_o <= 8'hFF;
|
adr_o <= {xData[63:3],3'b000};
|
adr_o <= {xData[63:3],3'b000};
|
end
|
end
|
`INH:
|
`INH,`INHU:
|
begin
|
begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= xData[2] ? 8'b11110000 : 8'b00001111;
|
adr_o <= {xData[63:2],2'b00};
|
adr_o <= {xData[63:2],2'b00};
|
end
|
end
|
`INCH:
|
`INCH,`INCU:
|
begin
|
begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
case(xData[1])
|
case(xData[2:1])
|
1'b0: sel_o <= 4'b0011;
|
2'b00: sel_o <= 8'b00000011;
|
1'b1: sel_o <= 4'b1100;
|
2'b01: sel_o <= 8'b00001100;
|
|
2'b10: sel_o <= 8'b00110000;
|
|
2'b11: sel_o <= 8'b11000000;
|
endcase
|
endcase
|
adr_o <= {xData[63:1],1'b0};
|
adr_o <= {xData[63:1],1'b0};
|
end
|
end
|
`INB:
|
`INB,`INBU:
|
begin
|
begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
case(xData[1:0])
|
case(xData[2:0])
|
2'b00: sel_o <= 8'b0001;
|
3'b000: sel_o <= 8'b00000001;
|
2'b01: sel_o <= 8'b0010;
|
3'b001: sel_o <= 8'b00000010;
|
2'b10: sel_o <= 8'b0100;
|
3'b010: sel_o <= 8'b00000100;
|
2'b11: sel_o <= 8'b1000;
|
3'b011: sel_o <= 8'b00001000;
|
|
3'b100: sel_o <= 8'b00010000;
|
|
3'b101: sel_o <= 8'b00100000;
|
|
3'b110: sel_o <= 8'b01000000;
|
|
3'b111: sel_o <= 8'b10000000;
|
endcase
|
endcase
|
adr_o <= xData;
|
adr_o <= xData;
|
end
|
end
|
`OUTW:
|
`OUTW:
|
begin
|
begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
sel_o <= 4'hF;
|
sel_o <= 8'hFF;
|
adr_o <= {xData[63:3],3'b000};
|
adr_o <= {xData[63:3],3'b000};
|
dat_o <= b[31:0];
|
dat_o <= b;
|
end
|
end
|
`OUTH:
|
`OUTH:
|
begin
|
begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
sel_o <= 4'b1111;
|
sel_o <= xData[2] ? 8'b11110000 : 8'b00001111;
|
adr_o <= {xData[63:2],2'b00};
|
adr_o <= {xData[63:2],2'b00};
|
dat_o <= b[31:0];
|
dat_o <= {2{b[31:0]}};
|
end
|
end
|
`OUTC:
|
`OUTC:
|
begin
|
begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
case(xData[1])
|
case(xData[2:1])
|
1'b0: sel_o <= 4'b0011;
|
2'b00: sel_o <= 8'b00000011;
|
1'b1: sel_o <= 4'b1100;
|
2'b01: sel_o <= 8'b00001100;
|
|
2'b10: sel_o <= 8'b00110000;
|
|
2'b11: sel_o <= 8'b11000000;
|
endcase
|
endcase
|
adr_o <= {xData[63:1],1'b0};
|
adr_o <= {xData[63:1],1'b0};
|
dat_o <= {2{b[15:0]}};
|
dat_o <= {4{b[15:0]}};
|
end
|
end
|
`OUTB:
|
`OUTB:
|
begin
|
begin
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
we_o <= 1'b1;
|
we_o <= 1'b1;
|
case(xData[1:0])
|
case(xData[2:0])
|
2'b00: sel_o <= 4'b0001;
|
3'b000: sel_o <= 8'b00000001;
|
2'b01: sel_o <= 4'b0010;
|
3'b001: sel_o <= 8'b00000010;
|
2'b10: sel_o <= 4'b0100;
|
3'b010: sel_o <= 8'b00000100;
|
2'b11: sel_o <= 4'b1000;
|
3'b011: sel_o <= 8'b00001000;
|
|
3'b100: sel_o <= 8'b00010000;
|
|
3'b101: sel_o <= 8'b00100000;
|
|
3'b110: sel_o <= 8'b01000000;
|
|
3'b111: sel_o <= 8'b10000000;
|
endcase
|
endcase
|
adr_o <= xData;
|
adr_o <= xData;
|
dat_o <= {4{b[7:0]}};
|
dat_o <= {8{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
|
begin
|
m1b <= b;
|
m1b <= b;
|
ea <= xData;
|
ea <= xData;
|
Line 2241... |
Line 2366... |
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// RFETCH:
|
// RFETCH:
|
// Register fetch stage
|
// Register fetch stage
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceR) begin
|
if (advanceR) begin
|
xirqf <= dirqf;
|
xAXC <= dAXC;
|
|
xhwxtype <= dhwxtype;
|
xFip <= dFip;
|
xFip <= dFip;
|
xextype <= dextype;
|
xextype <= dextype;
|
xIR <= dIR;
|
xIR <= dIR;
|
xpc <= dpc;
|
xpc <= dpc;
|
xbranch_taken <= dbranch_taken;
|
xbranch_taken <= dbranch_taken;
|
Line 2260... |
Line 2386... |
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;
|
m3Rt: a <= m3Data;
|
|
m4Rt: a <= m4Data;
|
|
wRt: a <= wData;
|
wRt: a <= wData;
|
tRt: a <= tData;
|
tRt: a <= tData;
|
default: a <= rfoa;
|
default: a <= rfoa;
|
endcase
|
endcase
|
casex(dRb)
|
casex(dRb)
|
9'bxxxx00000: b <= 64'd0;
|
9'bxxxx00000: b <= 64'd0;
|
xRt: b <= disRightShift ? -xData[5:0] : xData;
|
xRt: b <= disRightShift ? -xData[5:0] : xData;
|
m1Rt: b <= disRightShift ? -m1Data[5:0] : m1Data;
|
m1Rt: b <= disRightShift ? -m1Data[5:0] : m1Data;
|
m2Rt: b <= disRightShift ? -m2Data[5:0] : m2Data;
|
m2Rt: b <= disRightShift ? -m2Data[5:0] : m2Data;
|
m3Rt: b <= disRightShift ? -m3Data[5:0] : m3Data;
|
|
m4Rt: b <= disRightShift ? -m4Data[5:0] : m4Data;
|
|
wRt: b <= disRightShift ? -wData[5:0] : wData;
|
wRt: b <= disRightShift ? -wData[5:0] : wData;
|
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)
|
Line 2287... |
Line 2409... |
casex(dRc)
|
casex(dRc)
|
9'bxxxx00000: c <= 64'd0;
|
9'bxxxx00000: c <= 64'd0;
|
xRt: c <= xData;
|
xRt: c <= xData;
|
m1Rt: c <= m1Data;
|
m1Rt: c <= m1Data;
|
m2Rt: c <= m2Data;
|
m2Rt: c <= m2Data;
|
m3Rt: c <= m3Data;
|
|
m4Rt: c <= m4Data;
|
|
wRt: c <= wData;
|
wRt: c <= wData;
|
tRt: c <= tData;
|
tRt: c <= tData;
|
default: c <= rfoc;
|
default: c <= rfoc;
|
endcase
|
endcase
|
|
|
// Set the target register
|
// Set the target register
|
case(dOpcode)
|
casex(dOpcode)
|
`RR: xRt <= {regset,dIR[24:20]};
|
`SETLO: xRt <= {dAXC,dIR[36:32]};
|
|
`SETHI: xRt <= {dAXC,dIR[36:32]};
|
|
`RR: xRt <= {dAXC,dIR[24:20]};
|
`BTRI: xRt <= 9'd0;
|
`BTRI: xRt <= 9'd0;
|
`BTRR: xRt <= 9'd0;
|
`BTRR: xRt <= 9'd0;
|
`TRAPcc: xRt <= 9'd0;
|
`TRAPcc: xRt <= 9'd0;
|
`TRAPcci: xRt <= 9'd0;
|
`TRAPcci: xRt <= 9'd0;
|
`JMP: xRt <= 9'd00;
|
`JMP: xRt <= 9'd00;
|
`CALL: xRt <= {regset,5'd31};
|
`CALL: xRt <= {dAXC,5'd31};
|
`RET: xRt <= {regset,dIR[24:20]};
|
`RET: xRt <= {dAXC,dIR[24:20]};
|
`MEMNDX:
|
`MEMNDX:
|
case(dFunc)
|
case(dFunc)
|
`SW,`SH,`SC,`SB,`OUTW,`OUTH,`OUTC,`OUTB:
|
`SW,`SH,`SC,`SB,`OUTW,`OUTH,`OUTC,`OUTB:
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
default: xRt <= {regset,dIR[24:20]};
|
default: xRt <= {dAXC,dIR[24:20]};
|
endcase
|
endcase
|
`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 <= {regset,dIR[29:25]};
|
default: xRt <= {dAXC,dIR[29:25]};
|
endcase
|
endcase
|
if (dOpcode[6:4]==`IMM)
|
if (dOpcode[6:4]==`IMM)
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
|
|
// Set immediate value
|
// Set immediate value
|
Line 2355... |
Line 2477... |
// - 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
|
|
dAXC <= AXC;
|
dextype <= `EX_NON;
|
dextype <= `EX_NON;
|
if (nmi_edge) begin
|
if (nmi_edge & !StatusHWI) begin
|
|
$display("*****************");
|
|
$display("NMI edge detected");
|
|
$display("*****************");
|
|
StatusHWI <= 1'b1;
|
nmi_edge <= 1'b0;
|
nmi_edge <= 1'b0;
|
dirqf <= 1'b1;
|
dhwxtype <= 2'b01;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
dextype <= `EX_NMI;
|
dextype <= `EX_NMI;
|
|
IPC <= pc;
|
end
|
end
|
else if (irq_i & !im) begin
|
else if (irq_i & !im & !StatusHWI) begin
|
dirqf <= 1'b1;
|
StatusHWI <= 1'b1;
|
|
dhwxtype <= 2'b10;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
dextype <= `EX_IRQ;
|
dextype <= `EX_IRQ;
|
|
IPC <= pc;
|
end
|
end
|
// Are we filling the pipeline with NOP's as a result of a previous
|
// Are we filling the pipeline with NOP's as a result of a previous
|
// hardware interrupt ?
|
// hardware interrupt ?
|
else if (dirqf|dFip) begin
|
else if (|dhwxtype|dFip) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
|
else if (ITLBMiss)
|
|
dIR <= `NOP_INSN;
|
else begin
|
else begin
|
dIR <= insn;
|
dIR <= insn;
|
//`include "insn_dump.v"
|
`include "insn_dumpsc.v"
|
end
|
end
|
nopI <= 1'b0;
|
nopI <= 1'b0;
|
if (dOpcode[6:4]!=`IMM) begin
|
if (dOpcode[6:4]!=`IMM) begin
|
dpc <= pc;
|
dpc <= pc;
|
end
|
end
|
dRa <= {regset,insn[34:30]};
|
casex(iOpcode)
|
dRb <= {regset,insn[29:25]};
|
`SETLO: dRa <= {AXC,insn[36:32]};
|
dRc <= {regset,insn[24:20]};
|
`SETHI: dRa <= {AXC,insn[36:32]};
|
|
default: dRa <= {AXC,insn[34:30]};
|
|
endcase
|
|
dRb <= {AXC,insn[29:25]};
|
|
dRc <= {AXC,insn[24:20]};
|
if (ITLBMiss) begin
|
if (ITLBMiss) begin
|
|
$display("TLB miss on instruction fetch.");
|
CauseCode <= `EX_TLBI;
|
CauseCode <= `EX_TLBI;
|
StatusEXL <= 1'b1;
|
StatusEXL <= 1'b1;
|
BadVAddr <= pc[63:13];
|
BadVAddr <= pc[63:13];
|
pc <= `ITLB_MissHandler;
|
pc <= `ITLB_MissHandler;
|
EPC <= pc;
|
EPC <= pc;
|
Line 2440... |
Line 2577... |
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceX) begin
|
if (advanceX) begin
|
case(xOpcode)
|
case(xOpcode)
|
`MISC:
|
`MISC:
|
case(xFunc)
|
case(xFunc)
|
`ERET: begin
|
`IRET:
|
|
if (StatusHWI) begin
|
|
StatusHWI <= 1'b0;
|
|
pc <= IPC;
|
|
dpc <= IPC;
|
|
dIR <= `NOP_INSN;
|
|
xpc <= IPC;
|
|
xIR <= `NOP_INSN;
|
|
xRt <= 9'd0;
|
|
end
|
|
`ERET:
|
if (StatusEXL) begin
|
if (StatusEXL) begin
|
|
StatusEXL <= 1'b0;
|
pc <= EPC;
|
pc <= EPC;
|
dpc <= EPC;
|
dpc <= EPC;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xpc <= EPC;
|
xpc <= EPC;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
StatusEXL <= 1'b0;
|
|
end
|
|
default: ;
|
default: ;
|
endcase
|
endcase
|
`BTRR:
|
`BTRR:
|
case(xIR[4:0])
|
case(xIR[4:0])
|
// BEQ r1,r2,label
|
// BEQ r1,r2,label
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR:
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR:
|
if (takb & !xbranch_taken) begin
|
if (!takb & xbranch_taken) begin
|
$display("Taking branch %h",xpc[63:4] + {{42{xIR[24]}},xIR[24:7]});
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
|
pc <= fnIncPC(xpc);
|
|
dpc <= fnIncPC(xpc);
|
|
xpc <= fnIncPC(xpc);
|
|
dIR <= `NOP_INSN;
|
|
xIR <= `NOP_INSN;
|
|
xRt <= 9'd0;
|
|
end
|
|
else if (takb & !xbranch_taken) begin
|
|
$display("Taking branch %h.%h",{xpc[63:4] + {{42{xIR[24]}},xIR[24:7]},4'b0000},xIR[6:5]);
|
pc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
|
pc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
|
pc[3:2] <= xIR[6:5];
|
pc[3:2] <= xIR[6:5];
|
dpc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
|
dpc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]};
|
dpc[3:2] <= xIR[6:5];
|
dpc[3:2] <= xIR[6:5];
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
Line 2488... |
Line 2643... |
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: ;
|
`JAL: begin
|
`JAL:
|
|
begin
|
pc[63:2] <= a[63:2] + imm[63:2];
|
pc[63:2] <= a[63:2] + imm[63:2];
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
dpc[63:2] <= a[63:2] + imm[63:2];
|
dpc[63:2] <= a[63:2] + imm[63:2];
|
xpc[63:2] <= a[63:2] + imm[63:2];
|
xpc[63:2] <= a[63:2] + imm[63:2];
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
`RET: begin
|
`RET:
|
pc[63:2] <= b[63:2];
|
begin
|
$display("returning to: %h", {b,2'b00});
|
$display("returning to: %h", {b,2'b00});
|
|
pc[63:2] <= b[63:2];
|
dpc[63:2] <= b[63:2];
|
dpc[63:2] <= b[63:2];
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xpc[63:2] <= b[63:2];
|
xpc[63:2] <= b[63:2];
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2533... |
Line 2690... |
xpc[3:2] <= xIR[19:18];
|
xpc[3:2] <= xIR[19:18];
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
`TRAPcc:
|
else begin
|
|
if (xbranch_taken) begin
|
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
|
pc <= fnIncPC(xpc);
|
|
dpc <= fnIncPC(xpc);
|
|
xpc <= fnIncPC(xpc);
|
|
dIR <= `NOP_INSN;
|
|
xIR <= `NOP_INSN;
|
|
xRt <= 9'd0;
|
|
end
|
|
end
|
|
`TRAPcc,`TRAPcci:
|
if (takb) begin
|
if (takb) begin
|
StatusEXL <= 1'b1;
|
StatusEXL <= 1'b1;
|
CauseCode <= `EX_TRAP;
|
CauseCode <= `EX_TRAP;
|
EPC <= xpc;
|
EPC <= xpc;
|
if (!xbranch_taken) begin
|
if (!xbranch_taken) begin
|
Line 2547... |
Line 2715... |
xpc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
xpc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
`TRAPcci:
|
else begin
|
if (takb) begin
|
if (xbranch_taken) begin
|
CauseCode <= `EX_TRAP;
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
StatusEXL <= 1'b1;
|
pc <= fnIncPC(xpc);
|
EPC <= xpc;
|
dpc <= fnIncPC(xpc);
|
if (!xbranch_taken) begin
|
xpc <= fnIncPC(xpc);
|
pc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
|
dpc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xpc <= {TBA[63:13],`GEN_TRAP_OFFSET};
|
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
default: ;
|
default: ;
|
endcase
|
endcase
|
|
|
if (dbz_error) begin
|
if (dbz_error) begin
|
$display("Divide by zero error");
|
$display("Divide by zero error");
|
CauseCode <= `EX_DBZ;
|
CauseCode <= `EX_DBZ;
|
StatusEXL <= 1'b1;
|
StatusEXL <= 1'b1;
|
EPC <= xpc;
|
EPC <= xpc;
|
Line 2575... |
Line 2741... |
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xpc <= {TBA[63:13],`DBZ_TRAP_OFFSET};
|
xpc <= {TBA[63:13],`DBZ_TRAP_OFFSET};
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
if (ovr_error) begin
|
else if (ovr_error) begin
|
$display("Overflow error");
|
$display("Overflow error");
|
CauseCode <= `EX_OFL;
|
CauseCode <= `EX_OFL;
|
StatusEXL <= 1'b1;
|
StatusEXL <= 1'b1;
|
EPC <= xpc;
|
EPC <= xpc;
|
pc <= {TBA[63:13],`OFL_TRAP_OFFSET};
|
pc <= {TBA[63:13],`OFL_TRAP_OFFSET};
|
Line 2587... |
Line 2753... |
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xpc <= {TBA[63:13],`OFL_TRAP_OFFSET};
|
xpc <= {TBA[63:13],`OFL_TRAP_OFFSET};
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
|
else if (priv_violation) begin
|
|
$display("Priviledge violation");
|
|
CauseCode <= `EX_PRIV;
|
|
StatusEXL <= 1'b1;
|
|
EPC <= xpc;
|
|
pc <= {TBA[63:13],`PRIV_OFFSET};
|
|
dpc <= {TBA[63:13],`PRIV_OFFSET};
|
|
dIR <= `NOP_INSN;
|
|
xpc <= {TBA[63:13],`PRIV_OFFSET};
|
|
xIR <= `NOP_INSN;
|
|
xRt <= 9'd0;
|
|
end
|
end
|
end
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY1 (M1') - part two:
|
// MEMORY1 (M1') - part two:
|
// Check for a TLB miss.
|
// Check for a TLB miss.
|
Line 2622... |
Line 2800... |
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceM2) begin
|
if (advanceM2) begin
|
end
|
end
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY4 (M3')
|
|
//---------------------------------------------------------
|
|
if (advanceM3) begin
|
|
end
|
|
|
|
//---------------------------------------------------------
|
|
// MEMORY4 (M4')
|
|
// - no exceptions
|
|
//---------------------------------------------------------
|
|
if (advanceM4) begin
|
|
end
|
|
|
|
//((xOpcode==`TRAPcci) && takb)
|
|
//
|
|
//if (xOpcode==`TRAPcci || xOpcode==`TRAPcc)
|
|
// pc_src <= `TRAP_VECTOR;
|
|
//else if (branchI) begin
|
|
// pc_src[63:4] <= xpc[63:4] + {{50{xIR[24]}},xIR[29:20]};
|
|
// pc_src[3:2] <= xIR[19:18];
|
|
// pc_src[1:0] <= 2'b00;
|
|
//end
|
|
//else if (branch) begin
|
|
// pc_src[63:4] <= xpc[63:4] + imm[63:4];
|
|
// pc_src[3:2] <= imm[3:2];
|
|
// pc_src[1:0] <= 2'b00;
|
|
//end
|
|
//else if (branchToReg)
|
|
// pc_src <= b;
|
|
|
|
//---------------------------------------------------------
|
|
// WRITEBACK (WB') - 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
|
// In the case of a hardware interrupt (NMI/IRQ) we know
|
// the pipeline following the interrupt is filled with
|
// the pipeline following the interrupt is filled with
|
// NOP instructions. This means there is no need to
|
// NOP instructions. This means there is no need to
|
// invalidate the pipeline.
|
// invalidate the pipeline.
|
|
// Also, we have to wait until the WB stage before
|
|
// vectoring so that the pc setting doesn't get trashed
|
|
// by a branch or other exception.
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceW) begin
|
if (advanceW) begin
|
if (wextype!=`EX_NON) begin
|
|
case(wextype)
|
case(wextype)
|
`EX_RST:
|
`EX_RST: pc <= `RESET_VECTOR;
|
begin
|
`EX_NMI: pc <= `NMI_VECTOR;
|
StatusEXL <= 1'b1;
|
`EX_IRQ: pc <= `IRQ_VECTOR;
|
EPC <= pc;
|
default: ;
|
pc <= `RESET_VECTOR;
|
|
end
|
|
`EX_NMI:
|
|
begin
|
|
StatusEXL <= 1'b1;
|
|
EPC <= pc;
|
|
pc <= `NMI_VECTOR;
|
|
end
|
|
`EX_IRQ:
|
|
begin
|
|
StatusEXL <= 1'b1;
|
|
EPC <= pc;
|
|
pc <= `IRQ_VECTOR;
|
|
end
|
|
default: ;//pc[63:2] <= exception_address[63:2];
|
|
endcase
|
endcase
|
end
|
end
|
end
|
|
|
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Trailer (TR')
|
// Trailer (TR')
|
// - no exceptions
|
// - no exceptions
|
Line 2699... |
Line 2833... |
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Cache loader
|
// Cache loader
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (rst_i) begin
|
if (rst_i) begin
|
cstate <= IDLE;
|
cstate <= IDLE;
|
// wr_icache <= 1'b0;
|
|
wr_dcache <= 1'b0;
|
|
end
|
end
|
else begin
|
else begin
|
//wr_icache <= 1'b0;
|
|
wr_dcache <= 1'b0;
|
|
case(cstate)
|
case(cstate)
|
IDLE:
|
IDLE:
|
// we can't do anything until the command buffer is available
|
|
// in theory the command fifo should always be available
|
|
if (!cmd_full) begin
|
|
if (triggerDCacheLoad) begin
|
if (triggerDCacheLoad) begin
|
dcaccess <= 1'b1;
|
dcaccess <= 1'b1;
|
cmd_en <= 1'b1;
|
bte_o <= 2'b00; // linear burst
|
cmd_instr <= 3'b001; // READ
|
cti_o <= 3'b010; // burst access
|
cmd_byte_addr <= {pea[29:5],5'b00000};
|
bl_o <= 5'd8;
|
dadr_o <= {pea[63:5],5'b00000};
|
cyc_o <= 1'b1;
|
cmd_bl <= 6'd8; // Eight words per cache line
|
stb_o <= 1'b1;
|
|
adr_o <= {pea[63:6],6'h00};
|
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_instr <= 3'b001; // READ
|
|
cmd_byte_addr <= {ppc[29:6],6'h00};
|
|
iadr_o <= {ppc[63:6],6'h00};
|
|
cmd_bl <= 6'd16; // Sixteen words per cache line
|
|
cstate <= ICACT;
|
|
end
|
|
else begin
|
|
iciaccess <= 1'b1;
|
|
bte_o <= 2'b00; // linear burst
|
bte_o <= 2'b00; // linear burst
|
cti_o <= 3'b010; // burst access
|
cti_o <= 3'b010; // burst access
|
|
bl_o <= 5'd8;
|
cyc_o <= 1'b1;
|
cyc_o <= 1'b1;
|
stb_o <= 1'b1;
|
stb_o <= 1'b1;
|
adr_o <= {ppc[63:6],6'h00};
|
adr_o <= {ppc[63:6],6'h00};
|
iadr_o <= {ppc[63:6],6'h00};
|
|
cstate <= ICACT1;
|
cstate <= ICACT1;
|
end
|
end
|
end
|
|
end
|
|
// Sometime after the read command is issued, the read fifo will begin to fill
|
|
ICACT:
|
|
begin
|
|
rd_en <= 1'b1;
|
|
cstate <= ICACT0;
|
|
end
|
|
//ICACT0: // Read word 0
|
|
// At this point it should not be necessary to check rd_empty
|
|
// if (!rd_empty) begin
|
|
// wr_icache <= 1'b1;
|
|
// idat <= rd_data;
|
|
// cstate <= ICACT1;
|
|
// end
|
|
|
|
ICACT0: // Read word 1-15
|
|
// Might have to wait for subsequent data to be available
|
|
if (!rd_empty) begin
|
|
// wr_icache <= 1'b1;
|
|
// idat <= rd_data;
|
|
iadr_o[5:2] <= iadr_o[5:2] + 4'h1;
|
|
if (iadr_o[5:2]==4'hF) begin
|
|
rd_en <= 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;
|
|
cstate <= ICDLY;
|
|
end
|
|
end
|
|
ICDLY:
|
|
// The fifo should have emptied out, if not we force it to empty
|
|
if (!rd_empty) begin
|
|
rd_en <= 1'b1;
|
|
end
|
|
else begin
|
|
icaccess <= 1'b0;
|
|
rd_en <= 1'b0;
|
|
cstate <= IDLE;
|
|
end
|
|
|
|
// WISHBONE burst accesses
|
// WISHBONE burst accesses
|
//
|
//
|
ICACT1:
|
ICACT1:
|
if (ack_i) begin
|
if (ack_i) begin
|
adr_o[5:2] <= adr_o[5:2] + 4'd1;
|
adr_o[5:3] <= adr_o[5:3] + 3'd1;
|
iadr_o[5:2] <= iadr_o[5:2] + 4'd1;
|
if (adr_o[5:3]==3'h6)
|
if (adr_o[5:2]==4'hE)
|
|
cti_o <= 3'b111; // Last cycle ahead
|
cti_o <= 3'b111; // Last cycle ahead
|
if (adr_o[5:2]==4'hF) begin
|
if (adr_o[5:3]==3'h7) begin
|
cti_o <= 3'b000; // back to non-burst mode
|
cti_o <= 3'b000; // back to non-burst mode
|
cyc_o <= 1'b0;
|
cyc_o <= 1'b0;
|
stb_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
|
tmem[adr_o[12:6]] <= {1'b1,adr_o[63:13]}; // This will cause ihit to go high
|
tvalid[iadr_o[12:6]] <= 1'b1;
|
tvalid[adr_o[12:6]] <= 1'b1;
|
iciaccess <= 1'b0;
|
icaccess <= 1'b0;
|
cstate <= IDLE;
|
cstate <= IDLE;
|
end
|
end
|
end
|
end
|
|
|
DCACT:
|
DCACT:
|
begin
|
if (ack_i) begin
|
rd_en <= 1'b1; // Data should be available on the next clock cycle
|
adr_o[5:3] <= adr_o[5:3] + 3'd1;
|
cstate <= DCACT0;
|
if (adr_o[5:3]==3'h6)
|
end
|
cti_o <= 3'b111; // Last cycle ahead
|
DCACT0: // Read word 0
|
if (adr_o[5:3]==3'h7) begin
|
// At this point it should not be necessary to check rd_empty
|
cti_o <= 3'b000; // back to non-burst mode
|
if (!rd_empty) begin
|
cyc_o <= 1'b0;
|
wr_dcache <= 1'b1;
|
stb_o <= 1'b0;
|
ddat <= rd_data;
|
|
dadr_o[4:2] <= 3'b000;
|
|
cstate <= DCACT1;
|
|
end
|
|
DCACT1: // Read word 1
|
|
// Might have to wait for subsequent data to be available
|
|
if (!rd_empty) begin
|
|
wr_dcache <= 1'b1;
|
|
ddat <= rd_data;
|
|
dadr_o[4:2] <= dadr_o[4:2]+3'd1;
|
|
if (dadr_o[4:2]==3'b111) begin
|
|
rd_en <= 1'b0;
|
|
cstate <= DCDLY;
|
|
end
|
|
end
|
|
DCDLY:
|
|
// The fifo should have emptied out, if not, empty it out.
|
|
if (!rd_empty) begin
|
|
rd_en <= 1'b1;
|
|
end
|
|
else begin
|
|
dcaccess <= 1'b0;
|
dcaccess <= 1'b0;
|
rd_en <= 1'b0;
|
|
cstate <= IDLE;
|
cstate <= IDLE;
|
end
|
end
|
|
end
|
|
|
endcase
|
endcase
|
end
|
end
|
|
|
end
|
end
|
|
|