URL
https://opencores.org/ocsvn/raptor64/raptor64/trunk
Subversion Repositories raptor64
Compare Revisions
- This comparison shows the changes necessary to convert path
/raptor64/trunk/rtl/verilog
- from Rev 9 to Rev 11
- ↔ Reverse comparison
Rev 9 → Rev 11
/Raptor64.v
28,14 → 28,21
|
`define TLBMissPage 52'hFFFF_FFFF_FFFF_F |
`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_RST 8'd1 |
`define EX_NMI 8'd2 |
`define EX_IRQ 8'd3 |
`define EX_TRAP 8'd4 |
`define EX_OFL 8'd16 // overflow |
`define EX_DBZ 8'd17 // divide by zero |
`define EX_TLBI 8'd19 // TLB exception - ifetch |
`define EX_TLBD 8'd20 // TLB exception - data |
|
`define EXCEPT_Int 5'd00 |
`define EXCEPT_Mod 5'd01 // TLB modification |
60,7 → 67,9
`define MISC 7'd0 |
`define BRK 7'd0 |
`define IRQ 7'd1 |
`define FIP 7'd20 |
`define IRET 7'd32 |
`define ERET 7'd33 |
`define WAIT 7'd40 |
`define TLBR 7'd50 |
`define TLBWI 7'd51 |
84,30 → 93,36
`define REDAND 7'd31 |
`define MFSPR 7'd40 |
`define MTSPR 7'd41 |
`define TLBIndex 5'd01 |
`define TLBRandom 5'd02 |
`define PageTableAddr 5'd04 |
`define BadVAddr 5'd08 |
`define TLBPhysPage 5'd10 |
`define TLBVirtPage 5'd11 |
`define TLBPageMask 5'd12 |
`define TLBASID 5'd13 |
`define ASID 5'd14 |
`define Wired 5'd15 |
`define EP0 5'd16 |
`define EP1 5'd17 |
`define EP2 5'd18 |
`define EP3 5'd19 |
`define AXC 5'd20 |
`define MFTICK 7'd56 |
`define MFEPC 7'd57 |
`define TLBIndex 6'd01 |
`define TLBRandom 6'd02 |
`define PageTableAddr 6'd04 |
`define BadVAddr 6'd08 |
`define TLBPhysPage 6'd10 |
`define TLBVirtPage 6'd11 |
`define TLBPageMask 6'd12 |
`define TLBASID 6'd13 |
`define ASID 6'd14 |
`define Wired 6'd15 |
`define EP0 6'd16 |
`define EP1 6'd17 |
`define EP2 6'd18 |
`define EP3 6'd19 |
`define AXC 6'd20 |
`define Tick 6'd21 |
`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 MTTBA 7'd59 |
`define MTREGSET 7'd60 |
`define MFREGSET 7'd61 |
`define RR 7'd2 |
`define ADD 7'd4 |
`define SUB 7'd5 |
`define ADD 7'd2 |
`define ADDU 7'd3 |
`define SUB 7'd4 |
`define SUBU 7'd5 |
`define CMP 7'd6 |
`define CMPU 7'd7 |
`define AND 7'd8 |
128,30 → 143,15
`define MOVZ 7'd30 |
`define MOVNZ 7'd31 |
|
`define ASL 7'd40 |
`define LSR 7'd41 |
`define SHL 7'd40 |
`define SHRU 7'd41 |
`define ROL 7'd42 |
`define ROR 7'd43 |
`define ASR 7'd44 |
`define SHR 7'd44 |
`define ROLAM 7'd45 |
|
`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 SLE 7'd97 |
`define SGT 7'd98 |
167,10 → 167,10
`define BCD_SUB 7'd111 |
|
`define SHFTI 7'd3 |
`define ASLI 7'd0 |
`define LSRI 7'd1 |
`define SHLI 7'd0 |
`define SHRUI 7'd1 |
`define ROLI 7'd2 |
`define ASRI 7'd3 |
`define SHRI 7'd3 |
`define RORI 7'd4 |
`define ROLAMI 7'd5 |
`define BFINS 7'd8 |
179,12 → 179,13
`define BFCHG 7'd11 |
|
`define ADDI 7'd4 |
`define SUBI 7'd5 |
`define CMPI 7'd6 |
`define CMPUI 7'd7 |
`define ANDI 7'd8 |
`define ORI 7'd9 |
`define XORI 7'd10 |
`define ADDUI 7'd5 |
`define SUBI 7'd6 |
`define CMPI 7'd7 |
`define CMPUI 7'd8 |
`define ANDI 7'd9 |
`define ORI 7'd10 |
`define XORI 7'd11 |
|
`define MULUI 7'd12 |
`define MULSI 7'd13 |
191,34 → 192,6
`define DIVUI 7'd14 |
`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 TEQ 7'd0 |
`define TNE 7'd1 |
272,6 → 245,7
`define SH 7'd50 |
`define SW 7'd51 |
`define SP 7'd52 |
`define MEMNDX 7'd53 |
`define SSH 7'd56 |
`define SSW 7'd57 |
`define SF 7'd58 |
289,20 → 263,64
`define OUTH 7'd74 |
`define OUTW 7'd75 |
|
`define BEQI 7'd80 |
`define BNEI 7'd81 |
`define BLTI 7'd82 |
`define BLEI 7'd83 |
`define BGTI 7'd84 |
`define BGEI 7'd85 |
`define BLTUI 7'd86 |
`define BLEUI 7'd87 |
`define BGTUI 7'd88 |
`define BGEUI 7'd89 |
`define BLTI 7'd80 |
`define BGEI 7'd81 |
`define BLEI 7'd82 |
`define BGTI 7'd83 |
`define BLTUI 7'd84 |
`define BGEUI 7'd85 |
`define BLEUI 7'd86 |
`define BGTUI 7'd87 |
`define BEQI 7'd88 |
`define BNEI 7'd89 |
`define BRAI 7'd90 |
`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 SLEI 7'd97 |
`define SGTI 7'd98 |
319,6 → 337,8
`define NOPI 7'd111 |
|
`define IMM 3'd7 |
`define SETLO 7'b11110xx |
`define SETHI 7'b11111xx |
|
`define NOP_INSN 42'b1101111_000_00000000_00000000_00000000_00000000 |
|
355,6 → 375,7
input clk_i; |
input nmi_i; |
input irq_i; |
|
output [1:0] bte_o; |
reg [1:0] bte_o; |
output [2:0] cti_o; |
366,15 → 387,16
input ack_i; |
output we_o; |
reg we_o; |
output [7:0] sel_o; |
reg [7:0] sel_o; |
output [3:0] sel_o; |
reg [3:0] sel_o; |
output rsv_o; |
reg rsv_o; |
output [63:0] adr_o; |
reg [63:0] adr_o; |
output [31:0] adr_o; |
reg [31:0] adr_o; |
input [31:0] dat_i; |
output [31:0] dat_o; |
reg [31:0] dat_o; |
|
input sys_adv; |
input [63:5] sys_adr; |
|
406,14 → 428,15
reg [41:0] dIR; |
reg [41:0] xIR; |
reg [4:0] epcnt; |
reg [3:0] dAXC,AXC,xAXC; |
reg [3:0] dAXC,AXC,xAXC,m1AXC; |
reg [31:0] EP [3:0]; |
reg [63:0] pc [15:0]; |
reg [63:0] ErrorEPC,EPC[15:0]; |
wire [63:0] pc_axc = pc[AXC]; |
reg [63:0] dpc,m1pc,m2pc,m3pc,m4pc,wpc; |
reg [63:0] xpc; |
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] xRt; |
reg [63:0] dImm; |
422,6 → 445,9
reg [31:0] idat; |
reg [4:0] cstate; |
reg dbranch_taken,xbranch_taken; |
reg [63:0] mutex_gate; |
reg [63:0] TBA; |
|
//reg wr_icache; |
reg dccyc; |
wire [63:0] cdat; |
431,21 → 457,35
wire [63:0] rfoa,rfob; |
reg clk_en; |
reg cpu_clk_en; |
reg StatusEXL; // 1= in exception processing |
reg StatusTLB; // 1= in TLB miss handling |
reg [15:0] StatusERL; // 1= in error processing |
reg [15:0] StatusEXL; // 1= in exception processing |
reg [7:0] CauseCode[15:0]; |
reg [7:0] ASID; // address space identifier (process ID) |
integer n; |
reg [63:13] BadVAddr; |
reg [63:13] BadVAddr [15:0]; |
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; |
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 |
//----------------------------------------------------------------------------- |
458,6 → 498,17
reg [15:0] ITLBG; |
reg [7:0] ITLBASID [15:0]; |
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 @* |
for (n = 0; n < 16; n = n + 1) |
IMatch[n] = ((pc_axc[63:13]|ITLBPageMask[n])==(ITLBVirtPage[n]|ITLBPageMask[n])) && |
500,6 → 551,17
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) |
for (n = 0; n < 16; n = n + 1) |
DMatch[n] = ((ea[63:13]|DTLBPageMask[n])==(DTLBVirtPage[n]|DTLBPageMask[n])) && |
555,8 → 617,8
// 8kB |
// |
//----------------------------------------------------------------------------- |
reg icaccess; |
wire wr_icache = !rd_empty & icaccess; |
reg icaccess, iciaccess; |
wire wr_icache = (!rd_empty & icaccess) | (iciaccess & ack_i); |
|
Raptor64_icache_ram_x32 u1 |
( |
563,7 → 625,7
.clk(clk), |
.wr(wr_icache), |
.adr_i(iadr_o[12:0]), |
.dat_i(rd_data), |
.dat_i(icaccess ?rd_data : dat_i), |
.pc(pc_axc), |
.insn(insn) |
); |
637,8 → 699,10
reg m1IsCacheElement; |
|
reg nopI; |
wire [6:0] iFunc = insn[6:0]; |
wire [6:0] dFunc = dIR[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] dOpcode = dIR[41:35]; |
reg [6:0] m1Opcode,m2Opcode,m3Opcode,m4Opcode; |
648,7 → 712,7
reg [63:0] tick; |
reg [63:0] tba; |
reg [63:0] exception_address,ipc; |
reg [63:0] a,b,imm; |
reg [63:0] a,b,c,imm,m1b; |
reg prev_ihit; |
reg rsf; |
reg [63:5] resv_address; |
691,11 → 755,11
wire isDiv = xOpcode==`DIVSI || xOpcode==`DIVUI || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU)); |
|
wire disRRShift = dOpcode==`RR && ( |
dFunc==`ASL || dFunc==`ROL || dFunc==`ASR || |
dFunc==`LSR || dFunc==`ROR || dFunc==`ROLAM |
dFunc==`SHL || dFunc==`ROL || dFunc==`SHR || |
dFunc==`SHRU || dFunc==`ROR || dFunc==`ROLAM |
); |
wire disRightShift = dOpcode==`RR && ( |
dFunc==`ASR || dFunc==`LSR || dFunc==`ROR |
dFunc==`SHR || dFunc==`SHRU || dFunc==`ROR |
); |
|
Raptor64Mult u18 |
826,10 → 890,11
|
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. |
// 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 [1:0] branch_history_table [255:0]; |
wire [7:0] bht_wa = {xpc[5:0],gbl_branch_hist[2:1]}; // write address |
839,16 → 904,11
wire [1:0] bht_ibits = branch_history_table[bht_ra2]; |
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 || |
xOpcode==`BLTI || xOpcode==`BLEI || xOpcode==`BGTI || xOpcode==`BGEI || |
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; |
|
866,9 → 926,16
xbits_new <= bht_xbits; |
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. |
//--------------------------------------------------------- |
//----------------------------------------------------------------------------- |
wire signed [63:0] as = a; |
wire signed [63:0] bs = b; |
wire signed [63:0] imms = imm; |
884,7 → 951,7
|
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) |
`RR: |
`BTRR: |
case(xFunc) |
`BRA: takb = 1'b1; |
`BRN: takb = 1'b0; |
900,6 → 967,17
`BGEU: takb = !ltu; |
`BOR: 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; |
endcase |
`BRAI: takb = 1'b1; |
914,6 → 992,22
`BLEUI: takb = ltui|eqi; |
`BGTUI: takb = !(ltui|eqi); |
`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: |
case(xFunc) |
`TEQ: takb = eq; |
942,45 → 1036,14
`THSI: takb = !ltui; |
default: takb = 1'b0; |
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: |
takb = 1'b0; |
endcase |
|
|
//--------------------------------------------------------- |
//----------------------------------------------------------------------------- |
// Datapath (ALU) operations. |
//--------------------------------------------------------- |
//----------------------------------------------------------------------------- |
wire [6:0] cntlzo,cntloo; |
cntlz64 u12 ( .i(a), .o(cntlzo) ); |
cntlo64 u13 ( .i(a), .o(cntloo) ); |
988,13 → 1051,13
reg [1:0] shftop; |
wire [63:0] shfto; |
always @(xFunc) |
if (xFunc==`ASL) |
if (xFunc==`SHL) |
shftop = 2'b00; |
else if (xFunc==`ROL || xFunc==`ROR) |
shftop = 2'b01; |
else if (xFunc==`LSR) |
else if (xFunc==`SHRU) |
shftop = 2'b10; |
else if (xFunc==`ASR) |
else if (xFunc==`SHR) |
shftop = 2'b11; |
else |
shftop = 2'b01; |
1012,18 → 1075,6
.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 |
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 |
1033,7 → 1084,9
) |
case(xOpcode) |
`R: |
case(xFunc) |
casex(xFunc) |
`SETLO: xData = imm; |
`SETHI: xData = {imm[63:32],a[31:0]}; |
`COM: xData = ~a; |
`NOT: xData = ~|a; |
`NEG: xData = -a; |
1063,7 → 1116,7
`SEXT32: xData = {{32{a[31]}},a[31:0]}; |
|
`MFSPR: |
case(xIR[34:30]) |
case(xIR[12:7]) |
`Wired: xData = Wired; |
`TLBIndex: xData = Index; |
`TLBRandom: xData = Random; |
1072,7 → 1125,7
`TLBPageMask: xData = {TLBPageMask,13'd0}; |
`TLBASID: xData = TLBASID; |
`PageTableAddr: xData = {PageTableAddr,13'd0}; |
`BadVAddr: xData = {BadVAddr,13'd0}; |
`BadVAddr: xData = {BadVAddr[xAXC],13'd0}; |
`ASID: xData = ASID; |
`EP0: xData = EP[0]; |
`EP1: xData = EP[1]; |
1079,20 → 1132,24
`EP2: xData = EP[2]; |
`EP3: xData = EP[3]; |
`AXC: xData = xAXC; |
`Tick: xData = tick; |
`EPC: xData = EPC[xAXC]; |
`CauseCode: xData = CauseCode[xAXC]; |
`TBA: xData = TBA; |
default: xData = 65'd0; |
endcase |
`MFTICK: xData = tick; |
`MFEPC: xData = ipc; |
`MFTBA: xData = tba; |
`MTTBA: xData = a; |
`MTREGSET: xData = a; |
`MFREGSET: xData = regset; |
`OMG: xData = mutex_gate[a[5:0]]; |
`CMG: xData = mutex_gate[a[5:0]]; |
`OMGI: xData = mutex_gate[xIR[12:7]]; |
`CMGI: xData = mutex_gate[xIR[12:7]]; |
default: xData = 65'd0; |
endcase |
`RR: |
case(xFunc) |
`ADD: xData = a + b; |
`ADDU: xData = a + b; |
`SUB: xData = a - b; |
`SUBU: xData = a - b; |
`CMP: xData = lt ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1; |
`CMPU: xData = ltu ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1; |
`SEQ: xData = eq; |
1123,11 → 1180,11
`DIVU: xData = div_q; |
`MOD: xData = div_r; |
|
`ASL: xData = shfto; |
`LSR: xData = shfto; |
`SHL: xData = shfto; |
`SHRU: xData = shfto; |
`ROL: xData = shfto; |
`ROR: xData = {a[0],a[63:1]}; |
`ASR: xData = shfto; |
`SHR: xData = shfto; |
`ROLAM: xData = shfto & masko; |
|
`BCD_ADD: xData = bcdaddo; |
1137,19 → 1194,20
endcase |
`SHFTI: |
case(xFunc) |
`ASLI: xData = shfto; |
`LSRI: xData = shfto; |
`SHLI: xData = shfto; |
`SHRUI: xData = shfto; |
`ROLI: xData = shfto; |
`RORI: xData = {a[0],a[63:1]}; |
`ASRI: xData = shfto; |
`SHRI: xData = shfto; |
`ROLAMI: xData = shfto & masko; |
`BFINS: for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? shfto[n] : b[n]; |
`BFSET: for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b1 : b[n]; |
`BFCLR: for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? 1'b0 : b[n]; |
`BFCHG: for (n = 0; n < 64; n = n + 1) xData[n] = masko[n] ? ~b[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: 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 |
`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; |
endcase |
`ADDI: xData = a + imm; |
`ADDUI: xData = a + imm; |
`SUBI: xData = a - imm; |
`CMPI: xData = lti ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1; |
`CMPUI: xData = ltui ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1; |
1178,6 → 1236,8
xData = a + imm; |
`SW,`SH,`SC,`SB,`SWC: |
xData = a + imm; |
`MEMNDX: |
xData = a + b + imm; |
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BOR,`BAND: |
xData = 64'd0; |
`TRAPcc: xData = fnIncPC(xpc); |
1190,6 → 1250,9
default: xData = 65'd0; |
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 xIsMult = (xOpcode==`RR && (xFunc==`MULU || xFunc==`MULS)) || |
xOpcode==`MULSI || xOpcode==`MULUI; |
1304,13 → 1367,21
wire advanceI = advanceR & ihit; |
|
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 |
m3Opcode==`NOPI && |
m4Opcode==`NOPI && |
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 stallCacheLoad = xWillLoadStore; |
1322,7 → 1393,7
// Register file. |
//--------------------------------------------------------- |
|
syncRam512x64_1rw2r u5 |
syncRam512x64_1rw3r u5 |
( |
.wrst(1'b0), |
.wclk(clk), |
1337,16 → 1408,23
.rcea(advanceR), |
.radra(dRa), |
.roa(rfoa), |
|
|
.rrstb(1'b0), |
.rclkb(~clk), |
.rceb(advanceR), |
.radrb(dRb), |
.rob(rfob) |
.rob(rfob), |
|
.rrstc(1'b0), |
.rclkc(~clk), |
.rcec(advanceR), |
.radrc(dRc), |
.roc(rfoc) |
); |
|
|
reg m1clkoff,m2clkoff,m3clkoff,m4clkoff,wclkoff; |
reg dFip,xFip,m1Fip,m2Fip,m3Fip,m4Fip,wFip; |
|
always @(posedge clk) |
if (rst_i) begin |
1396,6 → 1474,13
m2irqf <= 1'b0; |
m3irqf <= 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; |
tick <= 32'd0; |
cstate <= IDLE; |
1412,20 → 1497,32
clk_en <= 1'b1; |
Random <= 4'hF; |
Wired <= 4'd0; |
StatusTLB <= 1'b0; |
StatusEXL <= 1'b0; |
StatusEXL <= 16'b0; |
epcnt <= 5'd0; |
EP[0] <= 32'd0; |
EP[1] <= 32'd0; |
EP[2] <= 32'd0; |
EP[3] <= 32'd0; |
EP[0] <= 32'h00000000; |
EP[1] <= 32'h00000000; |
EP[2] <= 32'h00000000; |
EP[3] <= 32'h00000000; |
AXC <= 4'd0; |
dAXC <= 4'd0; |
xAXC <= 4'd0; |
resetA <= 1'b1; |
gbl_branch_hist <= 3'b000; |
end |
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) |
Random <= 4'hF; |
else |
1462,6 → 1559,7
//--------------------------------------------------------- |
if (advanceW) begin |
textype <= wextype; |
wextype <= `EX_NON; |
tRt <= wRt; |
tData <= wData; |
// regfile[wRt] <= wData; <- regfile.v |
1476,7 → 1574,6
m4irqf <= 1'b0; |
xirqf <= 1'b0; |
dirqf <= 1'b0; |
ipc <= wpc; |
exception_type <= wextype; |
end |
clk_en <= 1'b1; |
1487,6 → 1584,15
m2clkoff <= 1'b0; |
m3clkoff <= 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 |
|
//--------------------------------------------------------- |
1495,23 → 1601,28
//--------------------------------------------------------- |
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; |
case(m4Opcode) |
`LW,`LWR: begin |
wData <= {rd_data,m4Data[31:0]}; |
rd_en <= 1'b0; // only if LW/LWR |
end |
default: wData <= m4Data; |
endcase |
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 |
|
|
1522,10 → 1633,12
m4Opcode <= m3Opcode; |
m4Func <= m3Func; |
m4irqf <= m3irqf; |
m4Fip <= m3Fip; |
m4extype <= m3extype; |
m4Rt <= m3Rt; |
m4pc <= m3pc; |
m4clkoff <= m3clkoff; |
|
m3Rt <= 9'd0; |
m3Opcode <= `NOPI; |
m3Func <= 7'd0; |
1534,81 → 1647,84
m4Data <= m3Data; |
m3Addr <= 64'd0; |
m3Data <= 64'd0; |
case(m3Opcode) |
`INW: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
m4Data <= {dat_i,m3Data[31:0]}; |
end |
`OUTW: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
end |
`LW,`LWR: |
begin |
rd_en <= 1'b1; |
m4Data <= {32'd0,rd_data}; |
end |
`LH: |
begin |
rd_en <= 1'b0; |
m4Data <= {{32{rd_data[31]}},rd_data}; |
end |
`LHU: |
begin |
rd_en <= 1'b0; |
m4Data <= rd_data; |
end |
`LC: |
begin |
rd_en <= 1'b0; |
case(m3Addr[1]) |
1'b0: m4Data <= {{48{rd_data[15]}},rd_data[15:0]}; |
1'b1: m4Data <= {{48{rd_data[31]}},rd_data[31:16]}; |
m3extype <= `EX_NON; |
if (m3extype==`EX_NON) begin |
case(m3Opcode) |
`INW: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'h0; |
m4Data <= {dat_i,m3Data[31:0]}; |
end |
`OUTW: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'h0; |
end |
`LW,`LWR: |
begin |
rd_en <= 1'b1; |
m4Data <= {32'd0,rd_data}; |
end |
`LH: |
begin |
rd_en <= 1'b0; |
m4Data <= {{32{rd_data[31]}},rd_data}; |
end |
`LHU: |
begin |
rd_en <= 1'b0; |
m4Data <= rd_data; |
end |
`LC: |
begin |
rd_en <= 1'b0; |
case(m3Addr[1]) |
1'b0: m4Data <= {{48{rd_data[15]}},rd_data[15:0]}; |
1'b1: m4Data <= {{48{rd_data[31]}},rd_data[31:16]}; |
endcase |
end |
`LCU: |
begin |
rd_en <= 1'b0; |
case(m3Addr[1]) |
1'b0: m4Data <= {48'd0,rd_data[15:0]}; |
1'b1: m4Data <= {48'd0,rd_data[31:16]}; |
endcase |
end |
`LB: |
begin |
rd_en <= 1'b0; |
case(m3Addr[1:0]) |
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]}; |
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]}; |
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]}; |
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]}; |
endcase |
end |
`LBU: |
begin |
case(m3Addr[1:0]) |
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]}; |
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]}; |
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]}; |
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]}; |
endcase |
rd_en <= 1'b0; |
end |
`SW,`SWC: |
begin |
cmd_en <= 1'b1; |
cmd_instr <= 3'b000; // WRITE |
cmd_bl <= 6'd2; // 2-words |
cmd_byte_addr <= {m3Addr[29:3],3'b000}; |
end |
default: ; |
endcase |
end |
`LCU: |
begin |
rd_en <= 1'b0; |
case(m3Addr[1]) |
1'b0: m4Data <= {48'd0,rd_data[15:0]}; |
1'b1: m4Data <= {48'd0,rd_data[31:16]}; |
endcase |
end |
`LB: |
begin |
rd_en <= 1'b0; |
case(m3Addr[1:0]) |
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]}; |
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]}; |
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]}; |
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]}; |
endcase |
end |
`LBU: |
begin |
case(m3Addr[1:0]) |
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]}; |
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]}; |
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]}; |
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]}; |
endcase |
rd_en <= 1'b0; |
end |
`SW,`SWC: |
begin |
cmd_en <= 1'b1; |
cmd_instr <= 3'b000; // WRITE |
cmd_bl <= 6'd2; // 2-words |
cmd_byte_addr <= {m3Addr[29:3],3'b000}; |
end |
default: ; |
endcase |
end |
end |
|
//--------------------------------------------------------- |
1624,6 → 1740,8
m3Rt <= m2Rt; |
m3pc <= m2pc; |
m3clkoff <= m2clkoff; |
m3Fip <= m2Fip; |
|
m2Rt <= 9'd0; |
m2Opcode <= `NOPI; |
m2Func <= 7'd0; |
1631,43 → 1749,46
m2Data <= 64'd0; |
m2clkoff <= 1'b0; |
m2pc <= 64'd0; |
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 |
default: ; |
endcase |
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 |
default: ; |
endcase |
end |
end |
|
wrhit <= 1'b0; |
1688,6 → 1809,8
m2Rt <= m1Rt; |
m2pc <= m1pc; |
m2clkoff <= m1clkoff; |
m2Fip <= m1Fip; |
|
m1Rt <= 9'd0; |
m1Opcode <= `NOPI; |
m1Func <= 7'd0; |
1695,258 → 1818,266
m1clkoff <= 1'b0; |
m1pc <= 64'd0; |
m1IsCacheElement <= 1'b0; |
case(m1Opcode) |
`MISC: |
case(m1Func) |
`TLBR: |
m1extype <= `EX_NON; |
|
if (m1extype == `EX_NON) begin |
case(m1Opcode) |
`MISC: |
case(m1Func) |
`TLBR: |
begin |
TLBPageMask <= ITLBPageMask[i]; |
TLBVirtPage <= ITLBVirtPage[i]; |
TLBPhysPage <= ITLBPhysPage[i]; |
TLBASID <= ITLBASID[i]; |
TLBG <= ITLBG[i]; |
end |
`TLBWI,`TLBWR: |
begin |
ITLBValid[i] <= 1'b1; |
ITLBVirtPage[i] <= TLBVirtPage; |
ITLBPhysPage[i] <= TLBPhysPage; |
ITLBPageMask[i] <= TLBPageMask; |
ITLBASID[i] <= TLBASID; |
DTLBValid[i] <= 1'b1; |
DTLBVirtPage[i] <= TLBVirtPage; |
DTLBPhysPage[i] <= TLBPhysPage; |
DTLBPageMask[i] <= TLBPageMask; |
DTLBASID[i] <= TLBASID; |
end |
endcase |
`INW: |
begin |
TLBVirtPage <= ITLBVirtPage[i]; |
TLBPhysPage <= ITLBPhysPage[i]; |
stb_o <= 1'b0; |
m2Data <= {32'd0,dat_i}; |
end |
`TLBWI,`TLBWR: |
`INH: |
begin |
ITLBValid[i] <= 1'b1; |
ITLBVirtPage[i] <= TLBVirtPage; |
ITLBPhysPage[i] <= TLBPhysPage; |
ITLBPageMask[i] <= TLBPageMask; |
ITLBASID[i] <= TLBASID; |
DTLBValid[i] <= 1'b1; |
DTLBVirtPage[i] <= TLBVirtPage; |
DTLBPhysPage[i] <= TLBPhysPage; |
DTLBPageMask[i] <= TLBPageMask; |
DTLBASID[i] <= TLBASID; |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'd0; |
m2Data <= {{32{dat_i[31]}},dat_i[31: 0]}; |
end |
endcase |
`INW: |
begin |
stb_o <= 1'b0; |
m2Data <= {32'd0,dat_i}; |
end |
`INH: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'd0; |
m2Data <= {{32{dat_i[31]}},dat_i[31: 0]}; |
end |
`INCH: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'd0; |
case(sel_o) |
4'b0011: m2Data <= {{48{dat_i[15]}},dat_i[15: 0]}; |
4'b1100: m2Data <= {{48{dat_i[31]}},dat_i[31:16]}; |
default: m2Data <= 64'hDEADDEADDEADDEAD; |
endcase |
end |
`INB: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'd0; |
case(sel_o) |
4'b0001: m2Data <= {{56{dat_i[ 7]}},dat_i[ 7: 0]}; |
4'b0010: m2Data <= {{56{dat_i[15]}},dat_i[15: 8]}; |
4'b0100: m2Data <= {{56{dat_i[23]}},dat_i[23:16]}; |
4'b1000: m2Data <= {{56{dat_i[31]}},dat_i[31:24]}; |
default: m2Data <= 64'hDEADDEADDEADDEAD; |
endcase |
end |
`OUTW: |
begin |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'd0; |
end |
`OUTH,`OUTC,`OUTB: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'd0; |
end |
`LW: |
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}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
m2Data <= cdat; |
end |
`LWR: |
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; |
resv_address <= pea[63:5]; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
m2Data <= cdat; |
rsv_o <= 1'b1; |
resv_address <= pea[63:5]; |
end |
`LH: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
if (pea[1]) |
m2Data <= {{32{cdat[31]}},cdat[31:0]}; |
else |
m2Data <= {{32{cdat[63]}},cdat[63:32]}; |
end |
`LHU: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
if (pea[1]) |
m2Data <= {32'd0,cdat}; |
else |
m2Data <= {32'd0,cdat[63:32]}; |
end |
`LC: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
case(pea[2:1]) |
2'd0: m2Data <= {{48{cdat[15]}},cdat[15:0]}; |
2'd1: m2Data <= {{48{cdat[31]}},cdat[31:16]}; |
2'd2: m2Data <= {{48{cdat[47]}},cdat[47:32]}; |
2'd3: m2Data <= {{48{cdat[63]}},cdat[63:48]}; |
endcase |
end |
`LCU: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
case(pea[2:1]) |
2'd0: m2Data <= {48'd0,cdat[15: 0]}; |
2'd1: m2Data <= {48'd0,cdat[31:16]}; |
2'd2: m2Data <= {48'd0,cdat[47:32]}; |
2'd3: m2Data <= {48'd0,cdat[63:48]}; |
endcase |
end |
`LB: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
case(pea[2:0]) |
3'b000: m2Data <= {{56{cdat[ 7]}},cdat[ 7: 0]}; |
3'b001: m2Data <= {{56{cdat[15]}},cdat[15: 8]}; |
3'b010: m2Data <= {{56{cdat[23]}},cdat[23:16]}; |
3'b011: m2Data <= {{56{cdat[31]}},cdat[31:24]}; |
3'b100: m2Data <= {{56{cdat[39]}},cdat[39:32]}; |
3'b101: m2Data <= {{56{cdat[47]}},cdat[47:40]}; |
3'b110: m2Data <= {{56{cdat[55]}},cdat[55:48]}; |
3'b111: m2Data <= {{56{cdat[63]}},cdat[63:56]}; |
endcase |
end |
`LBU: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
case(pea[2:0]) |
3'b000: m2Data <= {56'd0,cdat[ 7: 0]}; |
3'b001: m2Data <= {56'd0,cdat[15: 8]}; |
3'b010: m2Data <= {56'd0,cdat[23:16]}; |
3'b011: m2Data <= {56'd0,cdat[31:23]}; |
3'b100: m2Data <= {56'd0,cdat[39:32]}; |
3'b101: m2Data <= {56'd0,cdat[47:40]}; |
3'b110: m2Data <= {56'd0,cdat[55:48]}; |
3'b111: m2Data <= {56'd0,cdat[63:56]}; |
endcase |
end |
`SW,`SH: |
begin |
wrhit <= dhit; |
wr_en <= 1'b1; |
wr_data <= b[31:0]; |
wr_mask <= 4'h0; |
wr_addr <= {pea[63:3],3'b000}; |
m2Addr <= {pea[63:3],3'b000}; |
if (resv_address==pea[63:5]) |
resv_address <= 59'd0; |
end |
`SC: |
begin |
wrhit <= dhit; |
wr_en <= 1'b1; |
wr_data <= {2{b[15:0]}}; |
wr_mask <= pea[1] ? 4'b0011 : 4'b1100; |
wr_addr <= {pea[63:2],2'b00}; |
m2Addr <= {pea[63:2],2'b00}; |
if (resv_address==pea[63:5]) |
resv_address <= 59'd0; |
end |
`SB: |
begin |
wrhit <= dhit; |
wr_en <= 1'b1; |
wr_data <= {4{b[7:0]}}; |
wr_addr <= {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]) |
resv_address <= 59'd0; |
end |
`SWC: |
begin |
rsf <= 1'b0; |
if (resv_address==pea[63:5]) begin |
`INCH: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'd0; |
case(sel_o) |
4'b0011: m2Data <= {{48{dat_i[15]}},dat_i[15: 0]}; |
4'b1100: m2Data <= {{48{dat_i[31]}},dat_i[31:16]}; |
default: m2Data <= 64'hDEADDEADDEADDEAD; |
endcase |
end |
`INB: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
sel_o <= 4'd0; |
case(sel_o) |
4'b0001: m2Data <= {{56{dat_i[ 7]}},dat_i[ 7: 0]}; |
4'b0010: m2Data <= {{56{dat_i[15]}},dat_i[15: 8]}; |
4'b0100: m2Data <= {{56{dat_i[23]}},dat_i[23:16]}; |
4'b1000: m2Data <= {{56{dat_i[31]}},dat_i[31:24]}; |
default: m2Data <= 64'hDEADDEADDEADDEAD; |
endcase |
end |
`OUTW: |
begin |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'd0; |
end |
`OUTH,`OUTC,`OUTB: |
begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
we_o <= 1'b0; |
sel_o <= 4'd0; |
end |
`LW: |
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}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
m2Data <= cdat; |
end |
`LWR: |
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; |
resv_address <= pea[63:5]; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
m2Data <= cdat; |
rsv_o <= 1'b1; |
resv_address <= pea[63:5]; |
end |
`LH: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
if (pea[1]) |
m2Data <= {{32{cdat[31]}},cdat[31:0]}; |
else |
m2Data <= {{32{cdat[63]}},cdat[63:32]}; |
end |
`LHU: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
if (pea[1]) |
m2Data <= {32'd0,cdat}; |
else |
m2Data <= {32'd0,cdat[63:32]}; |
end |
`LC: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
case(pea[2:1]) |
2'd0: m2Data <= {{48{cdat[15]}},cdat[15:0]}; |
2'd1: m2Data <= {{48{cdat[31]}},cdat[31:16]}; |
2'd2: m2Data <= {{48{cdat[47]}},cdat[47:32]}; |
2'd3: m2Data <= {{48{cdat[63]}},cdat[63:48]}; |
endcase |
end |
`LCU: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
case(pea[2:1]) |
2'd0: m2Data <= {48'd0,cdat[15: 0]}; |
2'd1: m2Data <= {48'd0,cdat[31:16]}; |
2'd2: m2Data <= {48'd0,cdat[47:32]}; |
2'd3: m2Data <= {48'd0,cdat[63:48]}; |
endcase |
end |
`LB: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
case(pea[2:0]) |
3'b000: m2Data <= {{56{cdat[ 7]}},cdat[ 7: 0]}; |
3'b001: m2Data <= {{56{cdat[15]}},cdat[15: 8]}; |
3'b010: m2Data <= {{56{cdat[23]}},cdat[23:16]}; |
3'b011: m2Data <= {{56{cdat[31]}},cdat[31:24]}; |
3'b100: m2Data <= {{56{cdat[39]}},cdat[39:32]}; |
3'b101: m2Data <= {{56{cdat[47]}},cdat[47:40]}; |
3'b110: m2Data <= {{56{cdat[55]}},cdat[55:48]}; |
3'b111: m2Data <= {{56{cdat[63]}},cdat[63:56]}; |
endcase |
end |
`LBU: |
if (!m1IsCacheElement) begin |
cmd_en <= 1'b1; |
cmd_bl <= 6'd1; // 1-words (from 32-bit interface) |
cmd_instr <= 3'b001; // READ |
cmd_byte_addr <= {pea[63:2],2'b00}; |
end |
else if (dhit) begin |
m2Opcode <= `LDONE; |
case(pea[2:0]) |
3'b000: m2Data <= {56'd0,cdat[ 7: 0]}; |
3'b001: m2Data <= {56'd0,cdat[15: 8]}; |
3'b010: m2Data <= {56'd0,cdat[23:16]}; |
3'b011: m2Data <= {56'd0,cdat[31:23]}; |
3'b100: m2Data <= {56'd0,cdat[39:32]}; |
3'b101: m2Data <= {56'd0,cdat[47:40]}; |
3'b110: m2Data <= {56'd0,cdat[55:48]}; |
3'b111: m2Data <= {56'd0,cdat[63:56]}; |
endcase |
end |
`SW,`SH: |
begin |
wrhit <= dhit; |
wr_en <= 1'b1; |
wr_data <= b[31:0]; |
wr_data <= m1b[31:0]; |
wr_mask <= 4'h0; |
wr_addr <= {pea[63:3],3'b000}; |
m2Addr <= {pea[63:3],3'b000}; |
resv_address <= 59'd0; |
rsf <= 1'b1; |
if (resv_address==pea[63:5]) |
resv_address <= 59'd0; |
end |
else |
m2Opcode <= `NOPI; |
end |
endcase |
`SC: |
begin |
$display("Storing char to %h, ea=%h",pea,ea); |
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}; |
if (resv_address==pea[63:5]) |
resv_address <= 59'd0; |
end |
`SB: |
begin |
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}; |
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]) |
resv_address <= 59'd0; |
end |
`SWC: |
begin |
rsf <= 1'b0; |
if (resv_address==pea[63:5]) 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}; |
resv_address <= 59'd0; |
rsf <= 1'b1; |
end |
else |
m2Opcode <= `NOPI; |
end |
endcase |
end |
end |
|
//--------------------------------------------------------- |
1958,6 → 2089,7
//--------------------------------------------------------- |
if (advanceX) begin |
m1irqf <= xirqf; |
m1Fip <= xFip; |
m1extype <= xextype; |
m1Opcode <= xOpcode; |
m1Func <= xFunc; |
1964,6 → 2096,7
m1Rt <= xRt; |
m1Data <= xData; |
m1IsCacheElement <= xisCacheElement; |
m1AXC <= xAXC; |
if (xOpcode==`MOVZ && !aeqz) begin |
m1Rt <= 9'd0; |
m1Data <= 64'd0; |
1977,6 → 2110,7
a <= 64'd0; |
b <= 64'd0; |
imm <= 64'd0; |
xextype <= `EX_NON; |
if (xOpcode[6:4]!=`IMM) begin |
xIR <= `NOP_INSN; |
end |
1998,7 → 2132,7
`R: |
case(xFunc) |
`MTSPR: |
case(xIR[29:25]) |
case(xIR[12:7]) |
`Wired: Wired <= xData[3:0]; |
`ASID: ASID <= xData[7:0]; |
`TLBIndex: Index <= xData[3:0]; |
2007,14 → 2141,20
`TLBPageMask: TLBPageMask <= xData[24:13]; |
`TLBASID: TLBASID <= xData[7:0]; |
`PageTableAddr: PageTableAddr <= xData[63:13]; |
`BadVAddr: BadVAddr <= xData[63:13]; |
`EP0: EP[0] <= xData[31:0]; |
`BadVAddr: BadVAddr[xAXC] <= xData[63:13]; |
`EP0: EP[0] <= {xData[31:4],4'd0}; |
`EP1: EP[1] <= xData[31:0]; |
`EP2: EP[2] <= xData[31:0]; |
`EP3: EP[3] <= xData[31:0]; |
`EPC: EPC[xAXC] <= xData; |
`TBA: TBA <= xData; |
default: ; |
endcase |
`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: ; |
endcase |
`CALL: m1Data <= fnIncPC(xpc); |
2099,11 → 2239,19
dat_o <= {4{b[7:0]}}; |
end |
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWR,`SW,`SH,`SC,`SB,`SWC: |
begin |
m1b <= b; |
ea <= xData; |
end |
`MEMNDX: |
begin |
m1Opcode <= xFunc; |
m1b <= c; |
ea <= xData; |
end |
`DIVSI,`DIVUI: |
if (b==64'd0) begin |
if (xextype == 8'h00) |
xextype <= `EX_DBZ; |
xextype <= `EX_DBZ; |
end |
default: ; |
endcase |
2120,6 → 2268,7
//--------------------------------------------------------- |
if (advanceR) begin |
xirqf <= dirqf; |
xFip <= dFip; |
xextype <= dextype; |
xAXC <= dAXC; |
xIR <= dIR; |
2126,10 → 2275,13
xpc <= dpc; |
xbranch_taken <= dbranch_taken; |
dbranch_taken <= 1'b0; |
dextype <= `EX_NON; |
if (dOpcode[6:4]!=`IMM) // IMM is "sticky" |
dIR <= `NOP_INSN; |
dRa <= 9'd0; |
dRb <= 9'd0; |
|
// Result forward muxes |
casex(dRa) |
9'bxxxx00000: a <= 64'd0; |
xRt: a <= xData; |
2154,22 → 2306,37
endcase |
if (dOpcode==`SHFTI) |
case(dFunc) |
`ROLI,`ASLI,`ROLAMI: b <= {58'd0,dIR[24:19]}; |
`RORI,`ASRI,`LSRI: b <= {58'd0,~dIR[24:19]+6'd1}; |
`RORI: 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 |
|
// Set the target register |
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) |
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BRA,`BRN,`BAND,`BOR: |
xRt <= 9'd0; |
`SW,`SH,`SC,`SB,`OUTW,`OUTH,`OUTC,`OUTB: |
xRt <= 9'd0; |
default: xRt <= {dAXC,dIR[24:20]}; |
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: |
xRt <= 9'd0; |
`NOPI: xRt <= 9'd0; |
2177,30 → 2344,27
xRt <= 9'd0; |
default: xRt <= {dAXC,dIR[29:25]}; |
endcase |
if (dOpcode[6:4]==`IMM) |
xRt <= 9'd0; |
|
// Set immediate value |
if (xOpcode[6:4]==`IMM) begin |
imm <= {xIR[38:0],dIR[24:0]}; |
end |
else |
case(dOpcode) |
`BTRI: imm <= {{44{dIR[19]}},dIR[19:0]}; |
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI: |
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]}; |
`ORI: 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]}; |
`MEMNDX: imm <= {{51{dIR[19]}},dIR[19:7]}; |
default: imm <= {{39{dIR[24]}},dIR[24:0]}; |
endcase |
if (dOpcode[6:4]==`IMM) |
xRt <= 9'd0; |
case(dOpcode) |
|
`MISC: |
case(dFunc) |
`SEI: im <= 1'b1; |
2218,7 → 2382,8
// - set special register defaults for some instructions |
//--------------------------------------------------------- |
if (advanceI) begin |
if (dOpcode[6:4]!=`IMM) begin |
dextype <= `EX_NON; |
if (iOpcode[6:4]!=`IMM) begin |
epcnt <= epcnt + 5'd1; |
case(epcnt) |
5'd0: AXC <= EP[0][ 3: 0]; |
2267,7 → 2432,10
dIR <= `NOP_INSN; |
dextype <= `EX_IRQ; |
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; |
end |
else begin |
2281,30 → 2449,37
dAXC <= AXC; |
dRa <= {AXC,insn[34:30]}; |
dRb <= {AXC,insn[29:25]}; |
dRc <= {AXC,insn[24:20]}; |
if (ITLBMiss) begin |
dextype <= `EX_TLBI; |
StatusTLB <= 1'b1; |
StatusEXL <= 1'b1; |
BadVAddr <= pc_axc[63:13]; |
CauseCode[AXC] <= `EX_TLBI; |
StatusEXL[AXC] <= 1'b1; |
BadVAddr[AXC] <= pc_axc[63:13]; |
pc[AXC] <= `ITLB_MissHandler; |
tlbra <= pc_axc; |
EPC[AXC] <= pc_axc; |
end |
else begin |
dbranch_taken <= 1'b0; |
pc[AXC] <= fnIncPC(pc_axc); |
case(insn[41:35]) |
case(iOpcode) |
`MISC: |
case(iFunc) |
`FIP: dFip <= 1'b1; |
default: ; |
endcase |
`JMP,`CALL: |
begin |
dbranch_taken <= 1'b1; |
pc[AXC] <= jmp_tgt; |
end |
`RR: |
case(insn[6:0]) |
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU: |
`BTRR: |
case(insn[4:0]) |
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR: |
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; |
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 |
default: ; |
endcase |
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI: |
begin |
2313,23 → 2488,13
pc[AXC] <= {pc_axc[63:4] + {{50{insn[29]}},insn[29:20]},insn[19:18],2'b00}; |
end |
end |
`TRAPcc: if (predict_taken) begin pc[AXC] <= `TRAP_VECTOR; dbranch_taken <= 1'b1; end |
`TRAPcci: 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] <= {TBA[63:13],`GEN_TRAP_OFFSET}; dbranch_taken <= 1'b1; end |
default: ; |
endcase |
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" |
//--------------------------------------------------------- |
// EXECUTE - part two: |
2342,47 → 2507,61
case(xOpcode) |
`MISC: |
case(xFunc) |
`IRET: begin |
if (StatusTLB) begin |
pc[xAXC] <= tlbra; |
if (xAXC==AXC) |
dpc[63:2] <= tlbra[63:2]; |
if (xAXC==dAXC) |
xpc[63:2] <= tlbra[63:2]; |
StatusTLB <= 1'b0; |
`ERET: begin |
if (StatusEXL[xAXC]) begin |
pc[xAXC] <= EPC[xAXC]; |
if (xAXC==AXC) begin |
dpc <= EPC[xAXC]; |
dIR <= `NOP_INSN; |
end |
if (xAXC==dAXC) begin |
xpc <= EPC[xAXC]; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
end |
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 |
StatusEXL <= 1'b0; |
xIR <= `NOP_INSN; |
dIR <= `NOP_INSN; |
xRt <= 9'd0; |
StatusEXL[xAXC] <= 1'b0; |
end |
default: ; |
endcase |
`RR: |
case(xFunc) |
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR: |
`BTRR: |
case(xIR[4:0]) |
// BEQ r1,r2,label |
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR: |
if (takb & !xbranch_taken) begin |
pc[xAXC][63:4] <= xpc[63:4] + {{44{xIR[24]}},xIR[24:9]}; |
pc[xAXC][3:2] <= xIR[8:7]; |
$display("Taking branch %h",xpc[63:4] + {{42{xIR[24]}},xIR[24: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 |
dpc[63:4] <= xpc[63:4] + {{44{xIR[24]}},xIR[24:9]}; |
dpc[3:2] <= xIR[8:7]; |
dpc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24:7]}; |
dpc[3:2] <= xIR[6:5]; |
dIR <= `NOP_INSN; |
end |
if (xAXC==dAXC) begin |
xpc[63:4] <= xpc[63:4] + {{44{xIR[24]}},xIR[24:9]}; |
xpc[3:2] <= xIR[8:7]; |
xpc[63:4] <= xpc[63:4] + {{42{xIR[24]}},xIR[24: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; |
xRt <= 9'd0; |
end |
end |
default: ; |
endcase |
// 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. |
2413,6 → 2592,24
xRt <= 9'd0; |
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: |
if (takb) begin |
if (!xbranch_taken) begin |
2431,82 → 2628,19
end |
end |
end |
`BRr: |
case(xIR[29:25]) |
`BRAZ: |
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 |
if (dAXC==xAXC) begin |
xpc[63:4] <= xpc[63:4] + imm[63:4]; |
xpc[3:2] <= imm[3:2]; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
end |
end |
`BEQZ,`BNEZ,`BLTZ,`BLEZ,`BGTZ,`BGEZ,`BNR: |
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 |
if (dAXC==xAXC) begin |
xpc[63:4] <= xpc[63:4] + imm[63:4]; |
xpc[3:2] <= imm[3:2]; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
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 |
`BEQZR,`BNEZR,`BLTZR,`BLEZR,`BGTZR,`BGEZR: |
if (takb) begin |
pc[xAXC][63:2] <= b[63:2]; |
if (xAXC==AXC) begin |
dpc[63:2] <= b[63:2]; |
dIR <= `NOP_INSN; |
end |
if (dAXC==xAXC) begin |
xpc[63:2] <= b[63:2]; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
end |
end |
`BEQZRD,`BNEZRD,`BLTZRD,`BLEZRD,`BGTZRD,`BGEZRD: |
if (takb) begin |
pc[xAXC][63:2] <= b[63:2]; |
if (xAXC==AXC) begin |
dpc[63:2] <= b[63:2]; |
dIR <= `NOP_INSN; |
end |
end |
endcase |
`TRAPcc: |
if (takb) begin |
StatusEXL[xAXC] <= 1'b1; |
CauseCode[xAXC] <= `EX_TRAP; |
EPC[xAXC] <= xpc; |
if (!xbranch_taken) begin |
pc[xAXC] <= `TRAP_VECTOR; |
pc[xAXC] <= {TBA[63:13],`GEN_TRAP_OFFSET}; |
if (xAXC==AXC) begin |
dpc <= `TRAP_VECTOR; |
dpc <= {TBA[63:13],`GEN_TRAP_OFFSET}; |
dIR <= `NOP_INSN; |
end |
if (xAXC==dAXC) begin |
xpc <= `TRAP_VECTOR; |
xpc <= {TBA[63:13],`GEN_TRAP_OFFSET}; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
end |
2514,14 → 2648,17
end |
`TRAPcci: |
if (takb) begin |
CauseCode[xAXC] <= `EX_TRAP; |
StatusEXL[xAXC] <= 1'b1; |
EPC[xAXC] <= xpc; |
if (!xbranch_taken) begin |
pc[xAXC] <= `TRAP_VECTOR; |
pc[xAXC] <= {TBA[63:13],`GEN_TRAP_OFFSET}; |
if (xAXC==AXC) begin |
dpc <= `TRAP_VECTOR; |
dpc <= {TBA[63:13],`GEN_TRAP_OFFSET}; |
dIR <= `NOP_INSN; |
end |
if (xAXC==dAXC) begin |
xpc <= `TRAP_VECTOR; |
xpc <= {TBA[63:13],`GEN_TRAP_OFFSET}; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
end |
2529,9 → 2666,91
end |
default: ; |
endcase |
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 |
dpc <= {TBA[63:13],`DBZ_TRAP_OFFSET}; |
dIR <= `NOP_INSN; |
end |
if (xAXC==dAXC) begin |
xpc <= {TBA[63:13],`DBZ_TRAP_OFFSET}; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
end |
end |
if (ovr_error) begin |
$display("Overflow error"); |
CauseCode[xAXC] <= `EX_OFL; |
StatusEXL[xAXC] <= 1'b1; |
EPC[xAXC] <= xpc; |
pc[xAXC] <= {TBA[63:13],`OFL_TRAP_OFFSET}; |
if (xAXC==AXC) begin |
dpc <= {TBA[63:13],`OFL_TRAP_OFFSET}; |
dIR <= `NOP_INSN; |
end |
if (xAXC==dAXC) begin |
xpc <= {TBA[63:13],`OFL_TRAP_OFFSET}; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
end |
end |
end |
|
//--------------------------------------------------------- |
// MEMORY1 (M1') - part two: |
// Check for a TLB miss. |
//--------------------------------------------------------- |
if (advanceM1) begin |
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 |
if (m1AXC==dAXC) begin |
xpc <= `DTLB_MissHandler; |
xIR <= `NOP_INSN; |
xRt <= 9'd0; |
end |
if (m1AXC==AXC) begin |
dpc <= `DTLB_MissHandler; |
dIR <= `NOP_INSN; |
end |
end |
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) |
// |
//if (xOpcode==`TRAPcci || xOpcode==`TRAPcc) |
2550,22 → 2769,52
// pc_src <= b; |
|
//--------------------------------------------------------- |
// WRITEBACK - part two: |
// WRITEBACK (WB') - part two: |
// - 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 (wirqf) begin |
if (wextype!=`EX_NON) begin |
case(wextype) |
`EX_NON: ; // Dont' vector without an exception! |
`EX_RST: pc[AXC] <= `RESET_VECTOR; |
`EX_NMI: pc[AXC] <= `NMI_VECTOR; |
`EX_IRQ: pc[AXC] <= `IRQ_VECTOR; |
`EX_RST: |
begin |
StatusEXL[0] <= 1'b1; |
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]; |
endcase |
end |
end |
|
|
//--------------------------------------------------------- |
// Trailer (TR') |
// - no exceptions |
//--------------------------------------------------------- |
if (advanceT) begin |
end |
|
|
//--------------------------------------------------------- |
// Cache loader |
//--------------------------------------------------------- |
if (rst_i) begin |
2574,7 → 2823,6
wr_dcache <= 1'b0; |
end |
else begin |
cmd_en <= 1'b0; // allow this signal only to pulse for a single clock cycle |
//wr_icache <= 1'b0; |
wr_dcache <= 1'b0; |
case(cstate) |
2592,13 → 2840,25
cstate <= DCACT; |
end |
else if (triggerICacheLoad) begin |
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; |
if (!ppc[63]) begin |
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 |
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 |
// Sometime after the read command is issued, the read fifo will begin to fill |
2638,7 → 2898,26
rd_en <= 1'b0; |
cstate <= IDLE; |
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: |
begin |
rd_en <= 1'b1; // Data should be available on the next clock cycle |