Line 197... |
Line 197... |
//reg [15:0] pf_v;
|
//reg [15:0] pf_v;
|
reg im,imb;
|
reg im,imb;
|
reg fxe;
|
reg fxe;
|
reg nmi1,nmi_edge;
|
reg nmi1,nmi_edge;
|
reg StatusHWI;
|
reg StatusHWI;
|
|
reg StatusDBG;
|
reg [7:0] StatusEXL;
|
reg [7:0] StatusEXL;
|
assign km = StatusHWI | |StatusEXL;
|
assign km = StatusHWI | |StatusEXL;
|
reg [7:0] GM; // register group mask
|
reg [7:0] GM; // register group mask
|
reg [7:0] GMB;
|
reg [7:0] GMB;
|
wire [63:0] sr = {32'd0,imb,7'b0,GMB,im,1'b0,km,fxe,4'b0,GM};
|
wire [63:0] sr = {32'd0,imb,7'b0,GMB,im,1'b0,km,fxe,4'b0,GM};
|
wire int_commit;
|
wire int_commit;
|
wire int_pending;
|
wire int_pending;
|
wire sys_commit;
|
wire sys_commit;
|
|
wire dbg_commit;
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
wire [DBW-1:0] spc = (pc[ABW+3:ABW]==4'hF) ? pc[ABW-1:0] :
|
wire [DBW-1:0] spc = (pc[ABW+3:ABW]==4'hF) ? pc[ABW-1:0] :
|
(pc[ABW-1:ABW-4]==4'hF) ? pc[ABW-1:0] : {sregs[7],12'h000} + pc[ABW-1:0];
|
(pc[ABW-1:ABW-4]==4'hF) ? pc[ABW-1:0] : {sregs[7],12'h000} + pc[ABW-1:0];
|
`else
|
`else
|
wire [DBW-1:0] spc = pc;
|
wire [DBW-1:0] spc = pc;
|
Line 234... |
Line 236... |
reg iqentry_done [0:7]; // instruction result valid
|
reg iqentry_done [0:7]; // instruction result valid
|
reg [7:0] iqentry_cmt; // commit result to machine state
|
reg [7:0] iqentry_cmt; // commit result to machine state
|
reg iqentry_bt [0:7]; // branch-taken (used only for branches)
|
reg iqentry_bt [0:7]; // branch-taken (used only for branches)
|
reg iqentry_agen [0:7]; // memory address is generated
|
reg iqentry_agen [0:7]; // memory address is generated
|
reg iqentry_mem [0:7]; // touches memory: 1 if LW/SW
|
reg iqentry_mem [0:7]; // touches memory: 1 if LW/SW
|
|
reg iqentry_ndx [0:7]; // TRUE if indexed memory op
|
|
reg iqentry_cas [0:7];
|
|
reg iqentry_pushpop [0:7];
|
|
reg iqentry_pea [0:7];
|
|
reg iqentry_cmpmv [0:7];
|
|
reg iqentry_tlb [0:7];
|
reg iqentry_jmp [0:7]; // changes control flow: 1 if BEQ/JALR
|
reg iqentry_jmp [0:7]; // changes control flow: 1 if BEQ/JALR
|
|
reg iqentry_jmpi [0:7];
|
reg iqentry_fp [0:7]; // is an floating point operation
|
reg iqentry_fp [0:7]; // is an floating point operation
|
reg iqentry_rfw [0:7]; // writes to register file
|
reg iqentry_rfw [0:7]; // writes to register file
|
reg [DBW-1:0] iqentry_res [0:7]; // instruction result
|
reg [DBW-1:0] iqentry_res [0:7]; // instruction result
|
reg [3:0] iqentry_insnsz [0:7]; // the size of the instruction
|
reg [3:0] iqentry_insnsz [0:7]; // the size of the instruction
|
reg [3:0] iqentry_cond [0:7]; // predicating condition
|
reg [3:0] iqentry_cond [0:7]; // predicating condition
|
Line 250... |
Line 259... |
reg [5:0] iqentry_fn [0:7]; // instruction function
|
reg [5:0] iqentry_fn [0:7]; // instruction function
|
reg [2:0] iqentry_renmapno [0:7]; // register rename map number
|
reg [2:0] iqentry_renmapno [0:7]; // register rename map number
|
reg [6:0] iqentry_tgt [0:7]; // Rt field or ZERO -- this is the instruction's target (if any)
|
reg [6:0] iqentry_tgt [0:7]; // Rt field or ZERO -- this is the instruction's target (if any)
|
reg [DBW-1:0] iqentry_a0 [0:7]; // argument 0 (immediate)
|
reg [DBW-1:0] iqentry_a0 [0:7]; // argument 0 (immediate)
|
reg [DBW-1:0] iqentry_a1 [0:7]; // argument 1
|
reg [DBW-1:0] iqentry_a1 [0:7]; // argument 1
|
|
reg [6:0] iqentry_r1 [0:7];
|
reg iqentry_a1_v [0:7]; // arg1 valid
|
reg iqentry_a1_v [0:7]; // arg1 valid
|
reg [3:0] iqentry_a1_s [0:7]; // arg1 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [3:0] iqentry_a1_s [0:7]; // arg1 source (iq entry # with top bit representing ALU/DRAM bus)
|
|
reg [6:0] iqentry_r2 [0:7];
|
reg [DBW-1:0] iqentry_a2 [0:7]; // argument 2
|
reg [DBW-1:0] iqentry_a2 [0:7]; // argument 2
|
reg iqentry_a2_v [0:7]; // arg2 valid
|
reg iqentry_a2_v [0:7]; // arg2 valid
|
reg [3:0] iqentry_a2_s [0:7]; // arg2 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [3:0] iqentry_a2_s [0:7]; // arg2 source (iq entry # with top bit representing ALU/DRAM bus)
|
|
reg [6:0] iqentry_r3 [0:7];
|
reg [DBW-1:0] iqentry_a3 [0:7]; // argument 3
|
reg [DBW-1:0] iqentry_a3 [0:7]; // argument 3
|
reg iqentry_a3_v [0:7]; // arg3 valid
|
reg iqentry_a3_v [0:7]; // arg3 valid
|
reg [3:0] iqentry_a3_s [0:7]; // arg3 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [3:0] iqentry_a3_s [0:7]; // arg3 source (iq entry # with top bit representing ALU/DRAM bus)
|
|
reg [6:0] iqentry_rt [0:7];
|
reg [DBW-1:0] iqentry_T [0:7];
|
reg [DBW-1:0] iqentry_T [0:7];
|
reg iqentry_T_v [0:7];
|
reg iqentry_T_v [0:7];
|
reg [3:0] iqentry_T_s [0:7];
|
reg [3:0] iqentry_T_s [0:7];
|
reg [DBW-1:0] iqentry_pc [0:7]; // program counter for this instruction
|
reg [DBW-1:0] iqentry_pc [0:7]; // program counter for this instruction
|
|
|
Line 432... |
Line 445... |
wire [3:0] alu1_exc;
|
wire [3:0] alu1_exc;
|
reg alu1_v;
|
reg alu1_v;
|
wire alu1_branchmiss;
|
wire alu1_branchmiss;
|
reg [ABW+3:0] alu1_misspc;
|
reg [ABW+3:0] alu1_misspc;
|
|
|
|
wire jmpi_miss;
|
|
reg [ABW-1:0] jmpi_misspc;
|
wire mem_stringmissx;
|
wire mem_stringmissx;
|
reg mem_stringmiss;
|
reg mem_stringmiss;
|
wire branchmiss;
|
wire branchmiss;
|
wire [ABW+3:0] misspc;
|
wire [ABW+3:0] misspc;
|
|
|
Line 944... |
Line 959... |
`RTE: fnRa = 7'h5D;
|
`RTE: fnRa = 7'h5D;
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2:
|
fnRa = {3'h5,isn[23:20]};
|
fnRa = {3'h5,isn[23:20]};
|
`TLB: fnRa = {1'b0,isn[29:24]};
|
`TLB: fnRa = {1'b0,isn[29:24]};
|
`P: fnRa = 7'h70;
|
`P: fnRa = 7'h70;
|
`LOOP: fnRa = 7'h5F;
|
`LOOP: fnRa = 7'h73;
|
|
`PUSH: fnRa = km ? 7'd31 : 7'd27;
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
`PUSH,`PEA,`POP,`LINK: fnRa = 7'd27;
|
`PEA,`POP,`LINK: fnRa = km ? 7'd31 : 7'd27;
|
`endif
|
`endif
|
|
`MFSPR,`MOVS: fnRa = {1'b1,isn[`INSTRUCTION_RA]};
|
default: fnRa = {1'b0,isn[`INSTRUCTION_RA]};
|
default: fnRa = {1'b0,isn[`INSTRUCTION_RA]};
|
endcase
|
endcase
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
Line 959... |
Line 976... |
input [63:0] isn;
|
input [63:0] isn;
|
if (isn[7:0]==8'h11) // RTS short form
|
if (isn[7:0]==8'h11) // RTS short form
|
fnRb = 7'h51;
|
fnRb = 7'h51;
|
else
|
else
|
case(isn[15:8])
|
case(isn[15:8])
|
`RTI: fnRb = 7'h5E;
|
`RTS2: fnRb = km ? 7'd31 : 7'd27;
|
`RTD: fnRb = 7'h5B;
|
// `LOOP: fnRb = 7'h73;
|
`RTE: fnRb = 7'h5D;
|
// `RTS,`STP,`TLB,`POP: fnRb = 7'd0;
|
`RTS2: fnRb = 7'd27;
|
|
`LOOP: fnRb = 7'h73;
|
|
`RTS,`STP,`TLB,`POP: fnRb = 7'd0;
|
|
`JSR,`JSRS,`JSRZ,`SYS,`INT:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT:
|
fnRb = {3'h5,isn[23:20]};
|
fnRb = {3'h5,isn[23:20]};
|
`SWS: fnRb = {1'b1,isn[27:22]};
|
`SWS: fnRb = {1'b1,isn[27:22]};
|
`ifdef STACKOPS
|
|
`PUSH: fnRb = isn[22:16];
|
`PUSH: fnRb = isn[22:16];
|
|
`ifdef STACKOPS
|
`LINK: fnRb = {1'b0,isn[27:22]};
|
`LINK: fnRb = {1'b0,isn[27:22]};
|
`PEA: fnRb = {1'b0,isn[21:16]};
|
`PEA: fnRb = {1'b0,isn[21:16]};
|
`endif
|
`endif
|
default: fnRb = {1'b0,isn[`INSTRUCTION_RB]};
|
default: fnRb = {1'b0,isn[`INSTRUCTION_RB]};
|
endcase
|
endcase
|
Line 1004... |
Line 1018... |
if (isn[7:0]==8'h11) // RTS short form
|
if (isn[7:0]==8'h11) // RTS short form
|
fnFunc = 6'h00; // func is used as a small immediate
|
fnFunc = 6'h00; // func is used as a small immediate
|
else
|
else
|
case(isn[15:8])
|
case(isn[15:8])
|
`BITFIELD: fnFunc = isn[43:40];
|
`BITFIELD: fnFunc = isn[43:40];
|
|
`R: fnFunc = isn[31:28];
|
|
`R2: fnFunc = isn[31:28];
|
|
`DOUBLE_R: fnFunc = isn[31:28];
|
|
`SINGLE_R: fnFunc = isn[31:28];
|
8'h10: fnFunc = isn[31:28];
|
8'h10: fnFunc = isn[31:28];
|
8'h11: fnFunc = isn[31:28];
|
8'h11: fnFunc = isn[31:28];
|
8'h12: fnFunc = isn[31:28];
|
8'h12: fnFunc = isn[31:28];
|
8'h13: fnFunc = isn[31:28];
|
8'h13: fnFunc = isn[31:28];
|
8'h14: fnFunc = isn[31:28];
|
8'h14: fnFunc = isn[31:28];
|
Line 1037... |
Line 1055... |
8'h0C: fnFunc = isn[23:22];
|
8'h0C: fnFunc = isn[23:22];
|
8'h0D: fnFunc = isn[23:22];
|
8'h0D: fnFunc = isn[23:22];
|
8'h0E: fnFunc = isn[23:22];
|
8'h0E: fnFunc = isn[23:22];
|
8'h0F: fnFunc = isn[23:22];
|
8'h0F: fnFunc = isn[23:22];
|
`INC: fnFunc = isn[24:22];
|
`INC: fnFunc = isn[24:22];
|
|
`TLB: fnFunc = isn[19:16];
|
`RTS,`RTS2: fnFunc = isn[19:16]; // used to pass a small immediate
|
`RTS,`RTS2: fnFunc = isn[19:16]; // used to pass a small immediate
|
`CACHE: fnFunc = isn[31:26];
|
`CACHE: fnFunc = isn[31:26];
|
|
`PUSH,`PEA: fnFunc = km ? 6'b0 : 6'b110000; // select segment register #6
|
|
`JMPI: fnFunc = {isn[39:37],1'b0,isn[27:26]};
|
|
`JMPIX: fnFunc = {isn[39:37],1'b0,isn[33:32]};
|
default:
|
default:
|
fnFunc = isn[39:34];
|
fnFunc = isn[39:34];
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
Line 1141... |
Line 1163... |
case(opcode)
|
case(opcode)
|
`R,`P: fnSource2_v = 1'b1;
|
`R,`P: fnSource2_v = 1'b1;
|
`LDI,`LDIS,`IMM,`NOP,`STP: fnSource2_v = 1'b1;
|
`LDI,`LDIS,`IMM,`NOP,`STP: fnSource2_v = 1'b1;
|
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC:
|
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC:
|
fnSource2_v = 1'b1;
|
fnSource2_v = 1'b1;
|
`RTI,`RTD,`RTE: fnSource2_v = 1'b1;
|
`RTI,`RTD,`RTE,`JMPI: fnSource2_v = 1'b1;
|
// TST
|
// TST
|
8'h00: fnSource2_v = 1'b1;
|
8'h00: fnSource2_v = 1'b1;
|
8'h01: fnSource2_v = 1'b1;
|
8'h01: fnSource2_v = 1'b1;
|
8'h02: fnSource2_v = 1'b1;
|
8'h02: fnSource2_v = 1'b1;
|
8'h03: fnSource2_v = 1'b1;
|
8'h03: fnSource2_v = 1'b1;
|
Line 1210... |
Line 1232... |
fnSource2_v = `TRUE;
|
fnSource2_v = `TRUE;
|
else
|
else
|
fnSource2_v = `FALSE;
|
fnSource2_v = `FALSE;
|
`CACHE,`LCL,`TLB,
|
`CACHE,`LCL,`TLB,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`LEA,`STI,`INC:
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`STI,`INC:
|
fnSource2_v = 1'b1;
|
fnSource2_v = 1'b1;
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS:
|
fnSource2_v = 1'b1;
|
fnSource2_v = 1'b1;
|
`MTSPR,`MFSPR,`POP,`UNLINK:
|
`MTSPR,`MFSPR,`POP,`UNLINK:
|
fnSource2_v = 1'b1;
|
fnSource2_v = 1'b1;
|
`BITFIELD:
|
`BITFIELD:
|
if (func==`BFINS)
|
if (func==`BFINS)
|
fnSource2_v = 1'b0;
|
fnSource2_v = 1'b0;
|
else
|
else
|
fnSource2_v = 1'b1;
|
fnSource2_v = 1'b1;
|
`LOOP: fnSource2_v = 1'b0;
|
`LOOP: fnSource2_v = 1'b1;
|
default: fnSource2_v = 1'b0;
|
default: fnSource2_v = 1'b0;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
|
|
Line 1265... |
Line 1287... |
input [63:0] ins;
|
input [63:0] ins;
|
case(fnOpcode(ins))
|
case(fnOpcode(ins))
|
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`MOVS,`STP:
|
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`MOVS,`STP:
|
fnNumReadPorts = 3'd0;
|
fnNumReadPorts = 3'd0;
|
`LDI,`LDIS,`IMM: fnNumReadPorts = 3'd0;
|
`LDI,`LDIS,`IMM: fnNumReadPorts = 3'd0;
|
`R,`P,`STI: fnNumReadPorts = 3'd1;
|
`R,`P,`STI,`LOOP,`JMPI: fnNumReadPorts = 3'd1;
|
`RTI,`RTD,`RTE: fnNumReadPorts = 3'd1;
|
`RTI,`RTD,`RTE: fnNumReadPorts = 3'd1;
|
`ADDI,`ADDUI,`ADDUIS:
|
`ADDI,`ADDUI,`ADDUIS:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI:
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
Line 1282... |
Line 1304... |
if (ins[39:38]==2'h1) // shift immediate
|
if (ins[39:38]==2'h1) // shift immediate
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
else
|
else
|
fnNumReadPorts = 3'd2;
|
fnNumReadPorts = 3'd2;
|
`RTS2,`CACHE,`LCL,`TLB,
|
`RTS2,`CACHE,`LCL,`TLB,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,`LWS,`LEA,`INC:
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,`LWS,`INC:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`BR:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`BR:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
`SBX,`SCX,`SHX,`SWX,
|
`SBX,`SCX,`SHX,`SWX,
|
`MUX,`CAS,`STMV,`STCMP:
|
`MUX,`CAS,`STMV,`STCMP:
|
Line 1511... |
Line 1533... |
// 50-5F = code address register
|
// 50-5F = code address register
|
// 60-67 = segment base register
|
// 60-67 = segment base register
|
// 68-6F = segment limit register
|
// 68-6F = segment limit register
|
// 70 = predicate register horizontal
|
// 70 = predicate register horizontal
|
// 73 = loop counter
|
// 73 = loop counter
|
|
// 7C = breakout index register
|
|
// 7D = broken out register
|
|
// 7F = power shift register
|
function [6:0] fnTargetReg;
|
function [6:0] fnTargetReg;
|
input [63:0] ir;
|
input [63:0] ir;
|
begin
|
begin
|
if (ir[3:0]==4'h0) // Process special predicates
|
// Process special predicates (NOP, IMM)
|
|
// Note that BRK (00) is already translated to a SYS instruction
|
|
if (ir[3:0]==4'h0)
|
fnTargetReg = 7'h000;
|
fnTargetReg = 7'h000;
|
else
|
else
|
case(fnOpcode(ir))
|
case(fnOpcode(ir))
|
`POP: fnTargetReg = ir[22:16];
|
`POP: fnTargetReg = ir[22:16];
|
`LDI,`ADDUIS,`STS,`LINK,`UNLINK:
|
`LDI,`ADDUIS,`STS,`LINK,`UNLINK:
|
Line 1531... |
Line 1558... |
`LOGIC,`FLOAT,
|
`LOGIC,`FLOAT,
|
`LWX,`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`STMV,`STCMP,`STFND:
|
`LWX,`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`STMV,`STCMP,`STFND:
|
fnTargetReg = {1'b0,ir[33:28]};
|
fnTargetReg = {1'b0,ir[33:28]};
|
`SHIFT:
|
`SHIFT:
|
fnTargetReg = {1'b0,ir[33:28]};
|
fnTargetReg = {1'b0,ir[33:28]};
|
`R,`DOUBLE_R,`SINGLE_R,
|
`R,`R2,`DOUBLE_R,`SINGLE_R,
|
`ADDI,`ADDUI,`SUBI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,
|
`ADDI,`ADDUI,`SUBI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`ANDI,`ORI,`EORI,
|
`ANDI,`ORI,`EORI,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LEA,`LINK:
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LINK:
|
fnTargetReg = {1'b0,ir[27:22]};
|
fnTargetReg = {1'b0,ir[27:22]};
|
`CAS:
|
`CAS:
|
fnTargetReg = {1'b0,ir[39:34]};
|
fnTargetReg = {1'b0,ir[39:34]};
|
`BITFIELD:
|
`BITFIELD:
|
fnTargetReg = {1'b0,ir[27:22]};
|
fnTargetReg = {1'b0,ir[27:22]};
|
Line 1552... |
Line 1579... |
`MFSPR:
|
`MFSPR:
|
fnTargetReg = {1'b0,ir[27:22]};
|
fnTargetReg = {1'b0,ir[27:22]};
|
`BITI:
|
`BITI:
|
fnTargetReg = {3'h4,ir[25:22]};
|
fnTargetReg = {3'h4,ir[25:22]};
|
// TST
|
// TST
|
8'h00,
|
8'h00,8'h01,8'h02,8'h03,
|
8'h01,
|
8'h04,8'h05,8'h06,8'h07,
|
8'h02,
|
8'h08,8'h09,8'h0A,8'h0B,
|
8'h03,
|
8'h0C,8'h0D,8'h0E,8'h0F,
|
8'h04,
|
|
8'h05,
|
|
8'h06,
|
|
8'h07,
|
|
8'h08,
|
|
8'h09,
|
|
8'h0A,
|
|
8'h0B,
|
|
8'h0C,
|
|
8'h0D,
|
|
8'h0E,
|
|
8'h0F,
|
|
// CMP
|
// CMP
|
8'h10,
|
8'h10,8'h11,8'h12,8'h13,
|
8'h11,
|
8'h14,8'h15,8'h16,8'h17,
|
8'h12,
|
8'h18,8'h19,8'h1A,8'h1B,
|
8'h13,
|
8'h1C,8'h1D,8'h1E,8'h1F,
|
8'h14,
|
|
8'h15,
|
|
8'h16,
|
|
8'h17,
|
|
8'h18,
|
|
8'h19,
|
|
8'h1A,
|
|
8'h1B,
|
|
8'h1C,
|
|
8'h1D,
|
|
8'h1E,
|
|
8'h1F,
|
|
// CMPI
|
// CMPI
|
8'h20,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h21,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h22,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h23,
|
8'h2C,8'h2D,8'h2E,8'h2F:
|
8'h24,
|
|
8'h25,
|
|
8'h26,
|
|
8'h27,
|
|
8'h28,
|
|
8'h29,
|
|
8'h2A,
|
|
8'h2B,
|
|
8'h2C,
|
|
8'h2D,
|
|
8'h2E,
|
|
8'h2F:
|
|
begin
|
begin
|
fnTargetReg = {3'h4,ir[11:8]};
|
fnTargetReg = {3'h4,ir[11:8]};
|
end
|
end
|
`SWCR: fnTargetReg = {3'h4,4'h0};
|
`SWCR: fnTargetReg = {3'h4,4'h0};
|
`JSR,`JSRZ,`JSRS,`SYS,`INT:
|
`JSR,`JSRZ,`JSRS,`SYS,`INT:
|
fnTargetReg = {3'h5,ir[19:16]};
|
fnTargetReg = {3'h5,ir[19:16]};
|
|
`JMPI:
|
|
fnTargetReg = {3'h5,ir[25:22]};
|
|
`JMPIX:
|
|
fnTargetReg = {3'h5,ir[31:28]};
|
`MTSPR,`MOVS,`LWS:
|
`MTSPR,`MOVS,`LWS:
|
fnTargetReg = {1'b1,ir[27:22]};
|
fnTargetReg = {1'b1,ir[27:22]};
|
/*
|
/*
|
if (ir[27:26]==2'h1) // Move to code address register
|
if (ir[27:26]==2'h1) // Move to code address register
|
fnTargetReg = {3'h5,ir[25:22]};
|
fnTargetReg = {3'h5,ir[25:22]};
|
Line 1620... |
Line 1615... |
else if (ir[27:22]==6'h04)
|
else if (ir[27:22]==6'h04)
|
fnTargetReg = 7'h70;
|
fnTargetReg = 7'h70;
|
else
|
else
|
fnTargetReg = 7'h00;
|
fnTargetReg = 7'h00;
|
*/
|
*/
|
`RTS2: fnTargetReg = 7'd27;
|
`RTS2,`PUSH: fnTargetReg = km ? 7'd31 : 7'd27;
|
`LOOP: fnTargetReg = 7'h73;
|
`LOOP: fnTargetReg = 7'h73;
|
`STP: fnTargetReg = 7'h7F;
|
`STP: fnTargetReg = 7'h7F;
|
`P: fnTargetReg = 7'h70;
|
`P: fnTargetReg = 7'h70;
|
default: fnTargetReg = 7'h00;
|
default: fnTargetReg = 7'h00;
|
endcase
|
endcase
|
Line 1643... |
Line 1638... |
fnTargetsCa = `FALSE;
|
fnTargetsCa = `FALSE;
|
else begin
|
else begin
|
case(fnOpcode(ir))
|
case(fnOpcode(ir))
|
`JSR,`JSRZ,`JSRS,`SYS,`INT:
|
`JSR,`JSRZ,`JSRS,`SYS,`INT:
|
fnTargetsCa = `TRUE;
|
fnTargetsCa = `TRUE;
|
|
`JMPI,`JMPIX:
|
|
fnTargetsCa = `TRUE;
|
`LWS:
|
`LWS:
|
if (ir[27:26]==2'h1)
|
if (ir[27:26]==2'h1)
|
fnTargetsCa = `TRUE;
|
fnTargetsCa = `TRUE;
|
else
|
else
|
fnTargetsCa = `FALSE;
|
fnTargetsCa = `FALSE;
|
Line 1699... |
Line 1696... |
`BFCLR,`BFSET,`BFCHG,`BFEXT,`BFEXTU,`BFINS,
|
`BFCLR,`BFSET,`BFCHG,`BFEXT,`BFEXTU,`BFINS,
|
`LDI,`LDIS,`ADDUIS,
|
`LDI,`LDIS,`ADDUIS,
|
`ADDI,`SUBI,`ADDUI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,
|
`ADDI,`SUBI,`ADDUI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
// CMPI
|
// CMPI
|
8'h20,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h21,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h22,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h23,
|
8'h2C,8'h2D,8'h2E,8'h2F,
|
8'h24,
|
|
8'h25,
|
|
8'h26,
|
|
8'h27,
|
|
8'h28,
|
|
8'h29,
|
|
8'h2A,
|
|
8'h2B,
|
|
8'h2C,
|
|
8'h2D,
|
|
8'h2E,
|
|
8'h2F,
|
|
// BR
|
// BR
|
8'h30,
|
8'h30,8'h31,8'h32,8'h33,
|
8'h31,
|
8'h34,8'h35,8'h36,8'h37,
|
8'h32,
|
8'h38,8'h39,8'h3A,8'h3B,
|
8'h33,
|
8'h3C,8'h3D,8'h3E,8'h3F,
|
8'h34,
|
|
8'h35,
|
|
8'h36,
|
|
8'h37,
|
|
8'h38,
|
|
8'h39,
|
|
8'h3A,
|
|
8'h3B,
|
|
8'h3C,
|
|
8'h3D,
|
|
8'h3E,
|
|
8'h3F,
|
|
`ANDI,`ORI,`EORI,`BITI,
|
`ANDI,`ORI,`EORI,`BITI,
|
// `SHLI,`SHLUI,`SHRI,`SHRUI,`ROLI,`RORI,
|
// `SHLI,`SHLUI,`SHRI,`SHRUI,`ROLI,`RORI,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`LEA,`INC,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`INC,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,`STI,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,`STI,`JMPI,
|
`SB,`SC,`SH,`SW,`SWCR,`CAS,`SWS,
|
`SB,`SC,`SH,`SW,`SWCR,`CAS,`SWS,
|
|
`RTI,`RTD,`RTE,
|
`JSR,`JSRS,`SYS,`INT,`RTS2,`LOOP,`PEA,`LINK,`UNLINK:
|
`JSR,`JSRS,`SYS,`INT,`RTS2,`LOOP,`PEA,`LINK,`UNLINK:
|
fnHasConst = 1'b1;
|
fnHasConst = 1'b1;
|
default:
|
default:
|
fnHasConst = 1'b0;
|
fnHasConst = 1'b0;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
|
// Used by memory issue logic.
|
function fnIsFlowCtrl;
|
function fnIsFlowCtrl;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
begin
|
begin
|
case(opcode)
|
case(opcode)
|
|
`JMPI,`JMPIX,
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`LOOP,`RTS,`RTS2,`RTI,`RTD,`RTE:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`LOOP,`RTS,`RTS2,`RTI,`RTD,`RTE:
|
fnIsFlowCtrl = 1'b1;
|
fnIsFlowCtrl = 1'b1;
|
default:
|
default:
|
if (opcode[7:4]==`BR)
|
if (opcode[7:4]==`BR)
|
fnIsFlowCtrl = 1'b1;
|
fnIsFlowCtrl = 1'b1;
|
Line 1760... |
Line 1736... |
endcase
|
endcase
|
end
|
end
|
endfunction
|
endfunction
|
|
|
// fnCanException
|
// fnCanException
|
// Used by issue logic.
|
// Used by memory issue logic.
|
// Returns TRUE if the instruction can cause an exception
|
// Returns TRUE if the instruction can cause an exception
|
//
|
//
|
function fnCanException;
|
function fnCanException;
|
input [7:0] op;
|
input [7:0] op;
|
input [5:0] func;
|
input [5:0] func;
|
Line 1907... |
Line 1883... |
opcode==`STS || opcode==`LCL ||
|
opcode==`STS || opcode==`LCL ||
|
opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
|
opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
|
opcode==`TLB || opcode==`CAS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
|
opcode==`TLB || opcode==`CAS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
|
opcode==`LWS || opcode==`SWS || opcode==`STI ||
|
opcode==`LWS || opcode==`SWS || opcode==`STI ||
|
opcode==`INC ||
|
opcode==`INC ||
|
|
opcode==`JMPI || opcode==`JMPIX ||
|
opcode==`PUSH || opcode==`POP || opcode==`PEA || opcode==`LINK || opcode==`UNLINK
|
opcode==`PUSH || opcode==`POP || opcode==`PEA || opcode==`LINK || opcode==`UNLINK
|
;
|
;
|
endfunction
|
endfunction
|
|
|
function fnIsNdxd;
|
function fnIsNdxd;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsNdxd = opcode==`LBX || opcode==`LWX || opcode==`LBUX || opcode==`LHX || opcode==`LHUX || opcode==`LCX || opcode==`LCUX ||
|
fnIsNdxd = opcode==`LBX || opcode==`LWX || opcode==`LBUX || opcode==`LHX || opcode==`LHUX || opcode==`LCX || opcode==`LCUX ||
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX ||
|
|
opcode==`JMPIX
|
;
|
;
|
endfunction
|
endfunction
|
|
|
// Determines which instruction write to the register file
|
// Determines which instruction write to the register file
|
function fnIsRFW;
|
function fnIsRFW;
|
Line 1929... |
Line 1907... |
opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
|
opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
|
opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
opcode==`LVB || opcode==`LVH || opcode==`LVC || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
|
opcode==`LVB || opcode==`LVH || opcode==`LVC || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
|
opcode==`RTS2 || opcode==`STP ||
|
opcode==`RTS2 || opcode==`STP ||
|
opcode==`CAS || opcode==`LWS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
|
opcode==`CAS || opcode==`LWS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
|
opcode==`STS || opcode==`POP || opcode==`LINK || opcode==`UNLINK ||
|
opcode==`STS || opcode==`PUSH || opcode==`POP || opcode==`LINK || opcode==`UNLINK ||
|
|
opcode==`JMPI || opcode==`JMPIX ||
|
opcode==`ADDI || opcode==`SUBI || opcode==`ADDUI || opcode==`SUBUI || opcode==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI ||
|
opcode==`ADDI || opcode==`SUBI || opcode==`ADDUI || opcode==`SUBUI || opcode==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI ||
|
|
opcode==`_2ADDUI || opcode==`_4ADDUI || opcode==`_8ADDUI || opcode==`_16ADDUI ||
|
opcode==`ANDI || opcode==`ORI || opcode==`EORI ||
|
opcode==`ANDI || opcode==`ORI || opcode==`EORI ||
|
opcode==`ADD || opcode==`SUB || opcode==`ADDU || opcode==`SUBU || opcode==`MUL || opcode==`MULU || opcode==`DIV || opcode==`DIVU ||
|
opcode==`ADD || opcode==`SUB || opcode==`ADDU || opcode==`SUBU || opcode==`MUL || opcode==`MULU || opcode==`DIV || opcode==`DIVU ||
|
opcode==`AND || opcode==`OR || opcode==`EOR || opcode==`NAND || opcode==`NOR || opcode==`ENOR || opcode==`ANDC || opcode==`ORC ||
|
opcode==`AND || opcode==`OR || opcode==`EOR || opcode==`NAND || opcode==`NOR || opcode==`ENOR || opcode==`ANDC || opcode==`ORC ||
|
opcode==`SHIFT ||
|
opcode==`SHIFT ||
|
opcode==`R || opcode==`RR || opcode==`LEA || opcode==`P || opcode==`LOOP ||
|
opcode==`R || opcode==`RR || opcode==`P || opcode==`LOOP ||
|
opcode==`BITI || opcode==`CMP || opcode==`CMPI || opcode==`TST ||
|
opcode==`BITI || opcode==`CMP || opcode==`CMPI || opcode==`TST ||
|
opcode==`LDI || opcode==`LDIS || opcode==`ADDUIS || opcode==`MFSPR ||
|
opcode==`LDI || opcode==`LDIS || opcode==`ADDUIS || opcode==`MFSPR ||
|
// Branch registers / Segment registers
|
// Branch registers / Segment registers
|
((opcode==`MTSPR || opcode==`MOVS) /*&& (fnTargetsCa(ir) || fnTargetsSegreg(ir))*/) ||
|
((opcode==`MTSPR || opcode==`MOVS) /*&& (fnTargetsCa(ir) || fnTargetsSegreg(ir))*/) ||
|
opcode==`JSR || opcode==`JSRS || opcode==`JSRZ || opcode==`SYS || opcode==`INT ||
|
opcode==`JSR || opcode==`JSRS || opcode==`JSRZ || opcode==`SYS || opcode==`INT ||
|
Line 1963... |
Line 1943... |
function fnIsLoad;
|
function fnIsLoad;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsLoad = opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
|
fnIsLoad = opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
|
opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`LCL ||
|
opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`LCL ||
|
opcode==`LWS || opcode==`UNLINK ||
|
opcode==`LWS || opcode==`UNLINK || opcode==`JMPI || opcode==`JMPIX ||
|
opcode==`POP;
|
opcode==`POP;
|
endfunction
|
endfunction
|
|
|
function fnIsLoadV;
|
function fnIsLoadV;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
Line 1975... |
Line 1955... |
endfunction
|
endfunction
|
|
|
function fnIsIndexed;
|
function fnIsIndexed;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsIndexed = opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
fnIsIndexed = opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX;
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX || opcode==`JMPIX;
|
endfunction
|
endfunction
|
|
|
//
|
//
|
function fnIsPFW;
|
function fnIsPFW;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
Line 2041... |
Line 2021... |
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'h60,8'h61,8'h62,8'h63,8'h64,8'h65,8'h66,8'h67,8'h68,8'h69,8'h6A:
|
8'h60,8'h61,8'h62,8'h63,8'h64,8'h65,8'h66,8'h67,8'h68,8'h69,8'h6A:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'h73,8'h74,8'h75,8'h76,8'h7A,8'h7B,8'h7C,8'h7D,8'h7E,8'h7F:
|
8'h73,8'h74,8'h75,8'h76,8'h7A,8'h7B,8'h7C,8'h7D,8'h7E,8'h7F:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'h87,8'h88,8'h89,8'h8A,8'h8D:
|
8'h87,8'h88,8'h89,8'h8A:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'h94,8'h95,8'h9C:
|
8'h94,8'h95,8'h9C:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'hB7,8'b10111xxx:
|
8'b10111xxx:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'hC4,8'hC5,8'b11001xxx:
|
8'hC4,8'hC5,8'b11001xxx:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'hDx: fnIsIllegal = `TRUE;
|
8'hDx: fnIsIllegal = `TRUE;
|
8'hEx: fnIsIllegal = `TRUE;
|
8'hEx: fnIsIllegal = `TRUE;
|
Line 2081... |
Line 2061... |
endcase
|
endcase
|
3'd2:
|
3'd2:
|
fnSelect = 8'hFF;
|
fnSelect = 8'hFF;
|
default: fnSelect = 8'h00;
|
default: fnSelect = 8'h00;
|
endcase
|
endcase
|
|
`JMPI,`JMPIX:
|
|
case(fn[1:0])
|
|
2'd1:
|
|
case(adr[1])
|
|
1'b0: fnSelect = 8'h33;
|
|
1'b1: fnSelect = 8'hCC;
|
|
endcase
|
|
2'd2: fnSelect = 8'hFF;
|
|
2'd3: fnSelect = 8'hFF;
|
|
default: fnSelect = 8'h00;
|
|
endcase
|
`LB,`LBU,`LBX,`LBUX,`SB,`SBX,`LVB:
|
`LB,`LBU,`LBX,`LBUX,`SB,`SBX,`LVB:
|
case(adr[1:0])
|
case(adr[1:0])
|
3'd0: fnSelect = 8'h11;
|
3'd0: fnSelect = 8'h11;
|
3'd1: fnSelect = 8'h22;
|
3'd1: fnSelect = 8'h22;
|
3'd2: fnSelect = 8'h44;
|
3'd2: fnSelect = 8'h44;
|
Line 2131... |
Line 2122... |
endcase
|
endcase
|
3'd3:
|
3'd3:
|
fnSelect = 8'hFF;
|
fnSelect = 8'hFF;
|
default: fnSelect = 8'h00;
|
default: fnSelect = 8'h00;
|
endcase
|
endcase
|
|
`JMPI,`JMPIX:
|
|
case(fn[1:0])
|
|
2'd1:
|
|
case(adr[2:1])
|
|
2'd0: fnSelect = 8'h03;
|
|
2'd1: fnSelect = 8'h0C;
|
|
2'd2: fnSelect = 8'h30;
|
|
2'd3: fnSelect = 8'hC0;
|
|
endcase
|
|
2'd2:
|
|
case(adr[2])
|
|
1'b0: fnSelect = 8'h0F;
|
|
1'b1: fnSelect = 8'hF0;
|
|
endcase
|
|
2'd3: fnSelect = 8'hFF;
|
|
default: fnSelect = 8'h00;
|
|
endcase
|
`LB,`LBU,`LBX,`SB,`LVB,`LBUX,`SBX:
|
`LB,`LBU,`LBX,`SB,`LVB,`LBUX,`SBX:
|
case(adr[2:0])
|
case(adr[2:0])
|
3'd0: fnSelect = 8'h01;
|
3'd0: fnSelect = 8'h01;
|
3'd1: fnSelect = 8'h02;
|
3'd1: fnSelect = 8'h02;
|
3'd2: fnSelect = 8'h04;
|
3'd2: fnSelect = 8'h04;
|
Line 2189... |
Line 2197... |
default: fnDatai = {DBW{1'b1}};
|
default: fnDatai = {DBW{1'b1}};
|
endcase
|
endcase
|
default:
|
default:
|
fnDatai = dat[31:0];
|
fnDatai = dat[31:0];
|
endcase
|
endcase
|
|
`JMPI,`JMPIX:
|
|
case(func[1:0])
|
|
2'd1:
|
|
case(sel[3:0])
|
|
4'h3: fnDatai = dat[15:0];
|
|
4'hC: fnDatai = dat[31:16];
|
|
default: fnDatai = {DBW{1'b1}};
|
|
endcase
|
|
2'd2: fnDatai = dat[31:0];
|
|
default: fnDatai = dat[31:0];
|
|
endcase
|
`LB,`LBX,`LVB:
|
`LB,`LBX,`LVB:
|
case(sel[3:0])
|
case(sel[3:0])
|
8'h1: fnDatai = {{24{dat[7]}},dat[7:0]};
|
8'h1: fnDatai = {{24{dat[7]}},dat[7:0]};
|
8'h2: fnDatai = {{24{dat[15]}},dat[15:8]};
|
8'h2: fnDatai = {{24{dat[15]}},dat[15:8]};
|
8'h4: fnDatai = {{24{dat[23]}},dat[23:16]};
|
8'h4: fnDatai = {{24{dat[23]}},dat[23:16]};
|
Line 2253... |
Line 2272... |
8'hF0: fnDatai = dat[DBW-1:DBW/2];
|
8'hF0: fnDatai = dat[DBW-1:DBW/2];
|
default: fnDatai = {DBW{1'b1}};
|
default: fnDatai = {DBW{1'b1}};
|
endcase
|
endcase
|
3'd3,3'd7: fnDatai = dat;
|
3'd3,3'd7: fnDatai = dat;
|
endcase
|
endcase
|
|
`JMPI,`JMPIX:
|
|
case(func[1:0])
|
|
2'd1:
|
|
case(sel[7:0])
|
|
8'h03: fnDatai = dat[15:0];
|
|
8'h0C: fnDatai = dat[31:16];
|
|
8'h30: fnDatai = dat[47:32];
|
|
8'hC0: fnDatai = dat[63:48];
|
|
default: fnDatai = dat[15:0];
|
|
endcase
|
|
2'd2:
|
|
case(sel[7:0])
|
|
8'h0F: fnDatai = dat[31:0];
|
|
8'hF0: fnDatai = dat[63:32];
|
|
default: fnDatai = dat[31:0];
|
|
endcase
|
|
2'd3: fnDatai = dat;
|
|
default: fnDatai = dat;
|
|
endcase
|
`LB,`LBX,`LVB:
|
`LB,`LBX,`LVB:
|
case(sel)
|
case(sel)
|
8'h01: fnDatai = {{DBW*7/8{dat[DBW*1/8-1]}},dat[DBW*1/8-1:0]};
|
8'h01: fnDatai = {{DBW*7/8{dat[DBW*1/8-1]}},dat[DBW*1/8-1:0]};
|
8'h02: fnDatai = {{DBW*7/8{dat[DBW*2/8-1]}},dat[DBW*2/8-1:DBW*1/8]};
|
8'h02: fnDatai = {{DBW*7/8{dat[DBW*2/8-1]}},dat[DBW*2/8-1:DBW*1/8]};
|
8'h04: fnDatai = {{DBW*7/8{dat[DBW*3/8-1]}},dat[DBW*3/8-1:DBW*2/8]};
|
8'h04: fnDatai = {{DBW*7/8{dat[DBW*3/8-1]}},dat[DBW*3/8-1:DBW*2/8]};
|
Line 2383... |
Line 2421... |
// ({fetchbuf0_v, fnIsBranch(opcode0), predict_taken0} == {`VAL, `TRUE, `TRUE}) ? (ihit ?
|
// ({fetchbuf0_v, fnIsBranch(opcode0), predict_taken0} == {`VAL, `TRUE, `TRUE}) ? (ihit ?
|
// fetchbuf0_pc + {{DBW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} + 64'd3 : fetchbuf0_pc):
|
// fetchbuf0_pc + {{DBW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} + 64'd3 : fetchbuf0_pc):
|
// (ihit ? fetchbuf1_pc + {{DBW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} + 64'd3 : fetchbuf1_pc);
|
// (ihit ? fetchbuf1_pc + {{DBW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} + 64'd3 : fetchbuf1_pc);
|
always @*
|
always @*
|
if (fnIsBranch(opcode0) && fetchbuf0_v && predict_taken0) begin
|
if (fnIsBranch(opcode0) && fetchbuf0_v && predict_taken0) begin
|
if (ihit)
|
|
branch_pc <= fetchbuf0_pc + {{ABW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} + 64'd3;
|
branch_pc <= fetchbuf0_pc + {{ABW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} + 64'd3;
|
else
|
|
branch_pc <= fetchbuf0_pc;
|
|
end
|
end
|
else if (opcode0==`LOOP && fetchbuf0_v) begin
|
else if (opcode0==`LOOP && fetchbuf0_v) begin
|
if (ihit)
|
|
branch_pc <= fetchbuf0_pc + {{ABW-8{fetchbuf0_instr[23]}},fetchbuf0_instr[23:16]} + 64'd3;
|
branch_pc <= fetchbuf0_pc + {{ABW-8{fetchbuf0_instr[23]}},fetchbuf0_instr[23:16]} + 64'd3;
|
else
|
|
branch_pc <= fetchbuf0_pc;
|
|
end
|
end
|
else if (fnIsBranch(opcode1) && fetchbuf1_v && predict_taken1) begin
|
else if (fnIsBranch(opcode1) && fetchbuf1_v && predict_taken1) begin
|
if (ihit)
|
|
branch_pc <= fetchbuf1_pc + {{ABW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} + 64'd3;
|
branch_pc <= fetchbuf1_pc + {{ABW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} + 64'd3;
|
else
|
|
branch_pc <= fetchbuf1_pc;
|
|
end
|
end
|
else if (opcode1==`LOOP && fetchbuf1_v) begin
|
else if (opcode1==`LOOP && fetchbuf1_v) begin
|
if (ihit)
|
|
branch_pc <= fetchbuf1_pc + {{ABW-8{fetchbuf1_instr[23]}},fetchbuf1_instr[23:16]} + 64'd3;
|
branch_pc <= fetchbuf1_pc + {{ABW-8{fetchbuf1_instr[23]}},fetchbuf1_instr[23:16]} + 64'd3;
|
else
|
|
branch_pc <= fetchbuf1_pc;
|
|
end
|
end
|
else begin
|
else begin
|
branch_pc <= {{ABW-8{1'b1}},8'h80}; // set to something to prevent a latch
|
branch_pc <= RSTADDR; // set to something to prevent a latch
|
end
|
end
|
|
|
assign int_pending = (nmi_edge & ~StatusHWI & ~int_commit) || (irq_i & ~im & ~StatusHWI & ~int_commit);
|
assign int_pending = (nmi_edge & ~StatusHWI & ~int_commit) || (irq_i & ~im & ~StatusHWI & ~int_commit);
|
|
|
assign mem_stringmissx = ((dram0_op==`STS || dram0_op==`STFND) && int_pending && lc != 0) ||
|
assign mem_stringmissx = ((dram0_op==`STS || dram0_op==`STFND) && int_pending && lc != 0) ||
|
((dram0_op==`STMV || dram0_op==`STCMP) && int_pending && lc != 0 && stmv_flag);
|
((dram0_op==`STMV || dram0_op==`STCMP) && int_pending && lc != 0 && stmv_flag);
|
|
|
|
assign jmpi_miss = dram_v && (dram0_op==`JMPI || dram0_op==`JMPIX);
|
|
|
// "Stream" interrupt instructions into the instruction stream until an INT
|
// "Stream" interrupt instructions into the instruction stream until an INT
|
// instruction commits. This avoids the problem of an INT instruction being
|
// instruction commits. This avoids the problem of an INT instruction being
|
// stomped on by a previous branch instruction.
|
// stomped on by a previous branch instruction.
|
// Populate the instruction buffers with INT instructions for a hardware interrupt
|
// Populate the instruction buffers with INT instructions for a hardware interrupt
|
// Also populate the instruction buffers with a call to the instruction error vector
|
// Also populate the instruction buffers with a call to the instruction error vector
|
Line 2509... |
Line 2537... |
`JSRS: fnImm = {{48{insn[39]}},insn[39:24]};
|
`JSRS: fnImm = {{48{insn[39]}},insn[39:24]};
|
`BITFIELD: fnImm = insn[47:32];
|
`BITFIELD: fnImm = insn[47:32];
|
`SYS,`INT: fnImm = insn[31:24];
|
`SYS,`INT: fnImm = insn[31:24];
|
`RTS2: fnImm = {insn[31:27],3'b000};
|
`RTS2: fnImm = {insn[31:27],3'b000};
|
//`CMPI,
|
//`CMPI,
|
8'h20,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h21,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h22,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h23,
|
8'h2C,8'h2D,8'h2E,8'h2F,
|
8'h24,
|
|
8'h25,
|
|
8'h26,
|
|
8'h27,
|
|
8'h28,
|
|
8'h29,
|
|
8'h2A,
|
|
8'h2B,
|
|
8'h2C,
|
|
8'h2D,
|
|
8'h2E,
|
|
8'h2F,
|
|
`LDI,`LDIS,`ADDUIS:
|
`LDI,`LDIS,`ADDUIS:
|
fnImm = {{54{insn[31]}},insn[31:22]};
|
fnImm = {{54{insn[31]}},insn[31:22]};
|
`RTS: fnImm = insn[19:16];
|
`RTS: fnImm = insn[19:16];
|
`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm = 8'h00;
|
`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm = 64'h0;
|
`STI: fnImm = {{58{insn[33]}},insn[33:28]};
|
`STI: fnImm = {{58{insn[33]}},insn[33:28]};
|
|
`PUSH: fnImm = 64'hFFFFFFFFFFFFFFF8; //-8
|
//`LINK: fnImm = {insn[39:28],3'b000};
|
//`LINK: fnImm = {insn[39:28],3'b000};
|
|
`JMPI,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
|
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
|
fnImm = {{55{insn[36]}},insn[36:28]};
|
fnImm = {{55{insn[36]}},insn[36:28]};
|
default:
|
default:
|
fnImm = {{52{insn[39]}},insn[39:28]};
|
fnImm = {{52{insn[39]}},insn[39:28]};
|
Line 2556... |
Line 2574... |
`STP: fnImm8 = insn[23:16];
|
`STP: fnImm8 = insn[23:16];
|
`JSR,`JSRS,`RTS2: fnImm8 = insn[31:24];
|
`JSR,`JSRS,`RTS2: fnImm8 = insn[31:24];
|
`BITFIELD: fnImm8 = insn[39:32];
|
`BITFIELD: fnImm8 = insn[39:32];
|
`SYS,`INT: fnImm8 = insn[31:24];
|
`SYS,`INT: fnImm8 = insn[31:24];
|
//`CMPI,
|
//`CMPI,
|
8'h20,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h21,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h22,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h23,
|
8'h2C,8'h2D,8'h2E,8'h2F,
|
8'h24,
|
|
8'h25,
|
|
8'h26,
|
|
8'h27,
|
|
8'h28,
|
|
8'h29,
|
|
8'h2A,
|
|
8'h2B,
|
|
8'h2C,
|
|
8'h2D,
|
|
8'h2E,
|
|
8'h2F,
|
|
`LDI,`LDIS,`ADDUIS: fnImm8 = insn[29:22];
|
`LDI,`LDIS,`ADDUIS: fnImm8 = insn[29:22];
|
`RTS: fnImm8 = insn[19:16];
|
`RTS: fnImm8 = insn[19:16];
|
`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm8 = 8'h00;
|
`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm8 = 8'h00;
|
`STI: fnImm8 = insn[35:28];
|
`STI: fnImm8 = insn[35:28];
|
|
`PUSH: fnImm8 = 8'hF8;
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
`LINK: fnImm8 = {insn[32:28],3'b000};
|
`LINK: fnImm8 = {insn[32:28],3'b000};
|
`endif
|
`endif
|
|
`JMPI,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
|
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
|
fnImm8 = insn[35:28];
|
fnImm8 = insn[35:28];
|
default: fnImm8 = insn[35:28];
|
default: fnImm8 = insn[35:28];
|
endcase
|
endcase
|
Line 2603... |
Line 2611... |
`JSR:
|
`JSR:
|
fnImmMSB = insn[47];
|
fnImmMSB = insn[47];
|
`JSRS:
|
`JSRS:
|
fnImmMSB = insn[39];
|
fnImmMSB = insn[39];
|
//`CMPI,
|
//`CMPI,
|
8'h20,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h21,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h22,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h23,
|
8'h2C,8'h2D,8'h2E,8'h2F,
|
8'h24,
|
|
8'h25,
|
|
8'h26,
|
|
8'h27,
|
|
8'h28,
|
|
8'h29,
|
|
8'h2A,
|
|
8'h2B,
|
|
8'h2C,
|
|
8'h2D,
|
|
8'h2E,
|
|
8'h2F,
|
|
`LDI,`LDIS,`ADDUIS:
|
`LDI,`LDIS,`ADDUIS:
|
fnImmMSB = insn[31];
|
fnImmMSB = insn[31];
|
`SYS,`INT,`CACHE,`LINK:
|
`SYS,`INT,`CACHE,`LINK:
|
fnImmMSB = 1'b0; // SYS,INT are unsigned
|
fnImmMSB = 1'b0; // SYS,INT are unsigned
|
`RTS,`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`RTS2,`STS:
|
`RTS,`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`RTS2,`STS:
|
fnImmMSB = 1'b0; // RTS is unsigned
|
fnImmMSB = 1'b0; // RTS is unsigned
|
|
`PUSH: fnImmMSB = 1'b1;
|
`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`LWX,
|
`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`LWX,
|
`SBX,`SCX,`SHX,`SWX:
|
`SBX,`SCX,`SHX,`SWX:
|
fnImmMSB = insn[47];
|
fnImmMSB = insn[47];
|
|
`JMPI,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,
|
`SB,`SC,`SH,`SW,`SWCR,`STI,`LWS,`SWS,`INC,`LCL,`PEA:
|
`SB,`SC,`SH,`SW,`SWCR,`STI,`LWS,`SWS,`INC,`LCL,`PEA:
|
fnImmMSB = insn[36];
|
fnImmMSB = insn[36];
|
default:
|
default:
|
fnImmMSB = insn[39];
|
fnImmMSB = insn[39];
|
Line 2653... |
Line 2651... |
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
|
|
// Used during enque
|
// Used during enque
|
|
// Operand A is a little more work than B or C as it may read from special
|
|
// purpose registers.
|
function [63:0] fnOpa;
|
function [63:0] fnOpa;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
|
input [6:0] Ra;
|
input [63:0] ins;
|
input [63:0] ins;
|
input [63:0] rfo;
|
input [63:0] rfo;
|
input [63:0] epc;
|
input [63:0] epc;
|
begin
|
begin
|
`ifdef BITFIELDOPS
|
`ifdef BITFIELDOPS
|
if (opcode==`BITFIELD && ins[43:40]==`BFINSI)
|
if (opcode==`BITFIELD && ins[43:40]==`BFINSI)
|
fnOpa = ins[21:16];
|
fnOpa = ins[21:16];
|
else
|
else
|
`endif
|
`endif
|
if (opcode==`RTS) begin
|
if (Ra[6])
|
fnOpa = (commit1_v && commit1_tgt[6:0]==7'h51) ? commit1_bus :
|
fnOpa = fnSpr(Ra[5:0],epc);
|
(commit0_v && commit0_tgt[6:0]==7'h51) ? commit0_bus :
|
|
cregs[3'd1];
|
|
end
|
|
else if (opcode==`LOOP)
|
|
fnOpa = epc;
|
|
else if (fnIsFlowCtrl(opcode))
|
|
fnOpa = fnCar(ins)==4'd0 ? 64'd0 : fnCar(ins)==4'd15 ? epc :
|
|
(commit1_v && commit1_tgt[6:4]==3'h5 && commit1_tgt[3:0]==fnCar(ins)) ? commit1_bus :
|
|
(commit0_v && commit0_tgt[6:4]==3'h5 && commit0_tgt[3:0]==fnCar(ins)) ? commit0_bus :
|
|
cregs[fnCar(ins)];
|
|
else if (opcode==`P)
|
|
fnOpa = fnSpr(6'h30,epc);
|
|
else if (opcode==`MFSPR || opcode==`MOVS)
|
|
fnOpa = fnSpr(ins[`INSTRUCTION_RA],epc);
|
|
else
|
else
|
fnOpa = rfo;
|
fnOpa = rfo;
|
end
|
end
|
endfunction
|
endfunction
|
|
|
|
function [DBW-1:0] fnOpb;
|
|
input [7:0] opcode;
|
|
input [6:0] Rb;
|
|
input [63:0] ins;
|
|
input [63:0] rfo;
|
|
input [63:0] epc;
|
|
begin
|
|
fnOpb = fnIsShiftiop(ins) ? {{DBW-6{1'b0}},ins[`INSTRUCTION_RB]} :
|
|
fnIsFPCtrl(ins) ? {{DBW-6{1'b0}},ins[`INSTRUCTION_RB]} :
|
|
opcode==`INC ? {{56{ins[47]}},ins[47:40]} :
|
|
opcode==`STI ? ins[27:22] :
|
|
Rb[6] ? fnSpr(Rb[5:0],epc) :
|
|
rfo;
|
|
end
|
|
endfunction
|
|
|
|
// Used during enque
|
|
function [63:0] fnOpt;
|
|
input [6:0] tgt;
|
|
input [63:0] rfo;
|
|
input [63:0] epc;
|
|
begin
|
|
if (tgt[6])
|
|
fnOpt = fnSpr(tgt[5:0],epc);
|
|
else
|
|
fnOpt = rfo;
|
|
end
|
|
endfunction
|
|
|
// Returns TRUE if instruction is only allowed in kernel mode.
|
// Returns TRUE if instruction is only allowed in kernel mode.
|
function fnIsKMOnly;
|
function fnIsKMOnly;
|
input [7:0] op;
|
input [7:0] op;
|
fnIsKMOnly = op==`RTI || op==`RTE || op==`RTD || op==`TLB || op==`CLI || op==`SEI ||
|
fnIsKMOnly = op==`RTI || op==`RTE || op==`RTD || op==`TLB || op==`CLI || op==`SEI ||
|
Line 2697... |
Line 2712... |
endfunction
|
endfunction
|
|
|
function fnIsKMOnlyReg;
|
function fnIsKMOnlyReg;
|
input [6:0] regx;
|
input [6:0] regx;
|
fnIsKMOnlyReg = regx==7'd28 || regx==7'd29 || regx==7'd30 || regx==7'd31 ||
|
fnIsKMOnlyReg = regx==7'd28 || regx==7'd29 || regx==7'd30 || regx==7'd31 ||
|
regx==7'h5B || regx==7'h5C || regx==7'h5D || regx==7'h5E;
|
regx==7'h5B || regx==7'h5C || regx==7'h5D || regx==7'h5E ||
|
|
regx==7'h60 || regx==7'h68;
|
endfunction
|
endfunction
|
|
|
// Returns TRUE if the register is automatically valid.
|
// Returns TRUE if the register is automatically valid.
|
function fnRegIsAutoValid;
|
function fnRegIsAutoValid;
|
input [6:0] regno; // r0, c0, c15, tick
|
input [6:0] regno; // r0, c0, c15, tick
|
Line 3510... |
Line 3526... |
(commit0_v && iqentry_op[head1]==`INT && commit1_v && iqentry_tgt[head1][3:0]==4'hE);
|
(commit0_v && iqentry_op[head1]==`INT && commit1_v && iqentry_tgt[head1][3:0]==4'hE);
|
assign sys_commit = ((iqentry_op[head0]==`SYS || (iqentry_op[head0]==`INT &&
|
assign sys_commit = ((iqentry_op[head0]==`SYS || (iqentry_op[head0]==`INT &&
|
(iqentry_tgt[head0][3:0]==4'hD || iqentry_tgt[head0][3:0]==4'hB))) && commit0_v) ||
|
(iqentry_tgt[head0][3:0]==4'hD || iqentry_tgt[head0][3:0]==4'hB))) && commit0_v) ||
|
(commit0_v && (iqentry_op[head1]==`SYS || (iqentry_op[head1]==`INT &&
|
(commit0_v && (iqentry_op[head1]==`SYS || (iqentry_op[head1]==`INT &&
|
(iqentry_tgt[head1][3:0]==4'hD || iqentry_tgt[head1][3:0]==4'hB))) && commit1_v);
|
(iqentry_tgt[head1][3:0]==4'hD || iqentry_tgt[head1][3:0]==4'hB))) && commit1_v);
|
|
`ifdef DEBUG_LOGIC
|
|
assign dbg_commit = (((iqentry_op[head0]==`SYS && iqentry_tgt[head0][3:0]==4'hB) ||
|
|
(iqentry_op[head0]==`INT && (iqentry_tgt[head0][3:0]==4'hB))) && commit0_v) ||
|
|
(commit0_v && ((iqentry_op[head1]==`SYS && iqentry_tgt[head1][3:0]==4'hB)||
|
|
(iqentry_op[head1]==`INT && (iqentry_tgt[head1][3:0]==4'hB))) && commit1_v);
|
|
`endif
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst_i)
|
if (rst_i)
|
tick <= 64'd0;
|
tick <= 64'd0;
|
else
|
else
|
Line 3777... |
Line 3799... |
if (|alu0_exc)
|
if (|alu0_exc)
|
set_exception(alu0_id, alu0_exc==`EXC_DBZ ? 8'd241 : 8'h00);
|
set_exception(alu0_id, alu0_exc==`EXC_DBZ ? 8'd241 : 8'h00);
|
else begin
|
else begin
|
if (iqentry_op[alu0_id[2:0]]!=`IMM)
|
if (iqentry_op[alu0_id[2:0]]!=`IMM)
|
iqentry_done[ alu0_id[2:0] ] <= (!iqentry_mem[ alu0_id[2:0] ] || !alu0_cmt);
|
iqentry_done[ alu0_id[2:0] ] <= (!iqentry_mem[ alu0_id[2:0] ] || !alu0_cmt);
|
|
if (iqentry_jmpi[alu0_id[2:0]] && alu0_cmt)
|
|
iqentry_res [alu0_id[2:0]] <= alu0_pc + alu0_insnsz;
|
|
else
|
iqentry_res [ alu0_id[2:0] ] <= alu0_bus;
|
iqentry_res [ alu0_id[2:0] ] <= alu0_bus;
|
iqentry_out [ alu0_id[2:0] ] <= `FALSE;
|
iqentry_out [ alu0_id[2:0] ] <= `FALSE;
|
iqentry_cmt [ alu0_id[2:0] ] <= alu0_cmt;
|
iqentry_cmt [ alu0_id[2:0] ] <= alu0_cmt;
|
iqentry_agen[ alu0_id[2:0] ] <= `TRUE;
|
iqentry_agen[ alu0_id[2:0] ] <= `TRUE;
|
iqentry_out [ alu0_id[2:0] ] <= `FALSE;
|
|
end
|
end
|
end
|
end
|
|
|
|
|
if (((alu1_op==`RR && (alu1_fn==`MUL || alu1_fn==`MULU)) || alu1_op==`MULI || alu1_op==`MULUI) && ALU1BIG) begin
|
if (((alu1_op==`RR && (alu1_fn==`MUL || alu1_fn==`MULU)) || alu1_op==`MULI || alu1_op==`MULUI) && ALU1BIG) begin
|
Line 3805... |
Line 3829... |
if (|alu1_exc)
|
if (|alu1_exc)
|
set_exception(alu1_id, alu1_exc==`EXC_DBZ ? 8'd241 : 8'h00);
|
set_exception(alu1_id, alu1_exc==`EXC_DBZ ? 8'd241 : 8'h00);
|
else begin
|
else begin
|
if (iqentry_op[alu1_id[2:0]]!=`IMM)
|
if (iqentry_op[alu1_id[2:0]]!=`IMM)
|
iqentry_done[ alu1_id[2:0] ] <= (!iqentry_mem[ alu1_id[2:0] ] || !alu1_cmt);
|
iqentry_done[ alu1_id[2:0] ] <= (!iqentry_mem[ alu1_id[2:0] ] || !alu1_cmt);
|
|
if (iqentry_jmpi[alu1_id[2:0]] && alu1_cmt)
|
|
iqentry_res [alu1_id[2:0]] <= alu1_pc + alu1_insnsz;
|
|
else
|
iqentry_res [ alu1_id[2:0] ] <= alu1_bus;
|
iqentry_res [ alu1_id[2:0] ] <= alu1_bus;
|
iqentry_out [ alu1_id[2:0] ] <= `FALSE;
|
iqentry_out [ alu1_id[2:0] ] <= `FALSE;
|
iqentry_cmt [ alu1_id[2:0] ] <= alu1_cmt;
|
iqentry_cmt [ alu1_id[2:0] ] <= alu1_cmt;
|
iqentry_agen[ alu1_id[2:0] ] <= `TRUE;
|
iqentry_agen[ alu1_id[2:0] ] <= `TRUE;
|
iqentry_out [ alu1_id[2:0] ] <= `FALSE;
|
|
end
|
end
|
end
|
end
|
|
|
`ifdef FLOATING_POINT
|
`ifdef FLOATING_POINT
|
if (fp0_v) begin
|
if (fp0_v) begin
|
Line 4153... |
Line 4179... |
// as well as the appropriate iqentry_res slots (and setting valid bits)
|
// as well as the appropriate iqentry_res slots (and setting valid bits)
|
//
|
//
|
//
|
//
|
if (dram_v && iqentry_v[ dram_id[2:0] ] && iqentry_mem[ dram_id[2:0] ] ) begin // if data for stomped instruction, ignore
|
if (dram_v && iqentry_v[ dram_id[2:0] ] && iqentry_mem[ dram_id[2:0] ] ) begin // if data for stomped instruction, ignore
|
$display("dram results to iq[%d]=%h", dram_id[2:0],dram_bus);
|
$display("dram results to iq[%d]=%h", dram_id[2:0],dram_bus);
|
|
if (!iqentry_jmpi[dram_id[2:0]])
|
iqentry_res [ dram_id[2:0] ] <= dram_bus;
|
iqentry_res [ dram_id[2:0] ] <= dram_bus;
|
// If an exception occurred, stuff an interrupt instruction into the queue
|
// If an exception occurred, stuff an interrupt instruction into the queue
|
// slot. The instruction will re-issue as an ALU operation. We can change
|
// slot. The instruction will re-issue as an ALU operation. We can change
|
// the queued instruction because it isn't finished yet.
|
// the queued instruction because it isn't finished yet.
|
if (|dram_exc)
|
if (|dram_exc) begin
|
set_exception(dram_id,
|
set_exception(dram_id,
|
dram_exc==`EXC_DBE ? 8'hFB :
|
dram_exc==`EXC_DBE ? 8'hFB :
|
dram_exc==`EXC_DBG ? 8'd243 :
|
dram_exc==`EXC_DBG ? 8'd243 :
|
dram_exc==`EXC_SEGV ? 8'd244 :
|
dram_exc==`EXC_SEGV ? 8'd244 :
|
8'hF8); // F8 = TLBMiss exception 243 = debug
|
8'hF8); // F8 = TLBMiss exception 243 = debug
|
|
$stop;
|
|
end
|
else begin
|
else begin
|
// Note that the predicate was already evaluated to TRUE before the
|
// Note that the predicate was already evaluated to TRUE before the
|
// dram operation started.
|
// dram operation started.
|
iqentry_cmt[dram_id[2:0]] <= `TRUE;
|
iqentry_cmt[dram_id[2:0]] <= `TRUE;
|
iqentry_done[ dram_id[2:0] ] <= `TRUE;
|
iqentry_done[ dram_id[2:0] ] <= `TRUE;
|
Line 4181... |
Line 4210... |
end
|
end
|
|
|
// What if there's a databus error during the store ?
|
// What if there's a databus error during the store ?
|
// set the IQ entry == DONE as soon as the SW is let loose to the memory system
|
// set the IQ entry == DONE as soon as the SW is let loose to the memory system
|
//
|
//
|
if (dram0 == 2'd2 && fnIsStore(dram0_op) && dram0_op != `STS) begin
|
if (dram0 == 2'd2 && fnIsStore(dram0_op) && dram0_op != `STS && dram0_op != `STMV) begin
|
if ((alu0_v && dram0_id[2:0] == alu0_id[2:0]) || (alu1_v && dram0_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
|
if ((alu0_v && dram0_id[2:0] == alu0_id[2:0]) || (alu1_v && dram0_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
|
iqentry_done[ dram0_id[2:0] ] <= `TRUE;
|
iqentry_done[ dram0_id[2:0] ] <= `TRUE;
|
iqentry_cmt [ dram0_id[2:0]] <= `TRUE;
|
iqentry_cmt [ dram0_id[2:0]] <= `TRUE;
|
iqentry_out[ dram0_id[2:0] ] <= `FALSE;
|
iqentry_out[ dram0_id[2:0] ] <= `FALSE;
|
end
|
end
|
if (dram1 == 2'd2 && fnIsStore(dram1_op) && dram1_op != `STS) begin
|
if (dram1 == 2'd2 && fnIsStore(dram1_op) && dram1_op != `STS && dram1_op != `STMV) begin
|
if ((alu0_v && dram1_id[2:0] == alu0_id[2:0]) || (alu1_v && dram1_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
|
if ((alu0_v && dram1_id[2:0] == alu0_id[2:0]) || (alu1_v && dram1_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
|
iqentry_done[ dram1_id[2:0] ] <= `TRUE;
|
iqentry_done[ dram1_id[2:0] ] <= `TRUE;
|
iqentry_cmt [ dram1_id[2:0]] <= `TRUE;
|
iqentry_cmt [ dram1_id[2:0]] <= `TRUE;
|
iqentry_out[ dram1_id[2:0] ] <= `FALSE;
|
iqentry_out[ dram1_id[2:0] ] <= `FALSE;
|
end
|
end
|
if (dram2 == 2'd2 && fnIsStore(dram2_op) && dram2_op != `STS) begin
|
if (dram2 == 2'd2 && fnIsStore(dram2_op) && dram2_op != `STS && dram2_op != `STMV) begin
|
if ((alu0_v && dram2_id[2:0] == alu0_id[2:0]) || (alu1_v && dram2_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
|
if ((alu0_v && dram2_id[2:0] == alu0_id[2:0]) || (alu1_v && dram2_id[2:0] == alu1_id[2:0])) panic <= `PANIC_MEMORYRACE;
|
iqentry_done[ dram2_id[2:0] ] <= `TRUE;
|
iqentry_done[ dram2_id[2:0] ] <= `TRUE;
|
iqentry_cmt [ dram2_id[2:0]] <= `TRUE;
|
iqentry_cmt [ dram2_id[2:0]] <= `TRUE;
|
iqentry_out[ dram2_id[2:0] ] <= `FALSE;
|
iqentry_out[ dram2_id[2:0] ] <= `FALSE;
|
end
|
end
|
Line 4412... |
Line 4441... |
: (iqentry_a2_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_a2_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_a2_s[n] == alu1_id) ? alu1_bus
|
: (iqentry_a2_s[n] == alu1_id) ? alu1_bus
|
: 64'hDEADDEADDEADDEAD;
|
: 64'hDEADDEADDEADDEAD;
|
alu0_argC <=
|
alu0_argC <=
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
`ifdef STACKOPS
|
(iqentry_mem[n] && !iqentry_cmpmv[n]) ? {sregs[iqentry_fn[n][5:3]],12'h000} :
|
(iqentry_op[n]==`POP || iqentry_op[n]==`PUSH || iqentry_op[n]==`PEA) ? {sregs[3'd6],12'h000} :
|
|
`endif
|
|
(iqentry_mem[n] && iqentry_op[n]!=`STCMP && iqentry_op[n]!=`STMV) ? {sregs[iqentry_fn[n][5:3]],12'h000} :
|
|
`endif
|
`endif
|
iqentry_a3_v[n] ? iqentry_a3[n]
|
iqentry_a3_v[n] ? iqentry_a3[n]
|
: (iqentry_a3_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_a3_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_a3_s[n] == alu1_id) ? alu1_bus
|
: (iqentry_a3_s[n] == alu1_id) ? alu1_bus
|
: 64'hDEADDEADDEADDEAD;
|
: 64'hDEADDEADDEADDEAD;
|
Line 4450... |
Line 4476... |
: (iqentry_a2_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_a2_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_a2_s[n] == alu1_id) ? alu1_bus
|
: (iqentry_a2_s[n] == alu1_id) ? alu1_bus
|
: 64'hDEADDEADDEADDEAD;
|
: 64'hDEADDEADDEADDEAD;
|
alu1_argC <=
|
alu1_argC <=
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
`ifdef STACKOPS
|
(iqentry_mem[n] && !iqentry_cmpmv[n])? {sregs[iqentry_fn[n][5:3]],12'h000} :
|
(iqentry_op[n]==`POP || iqentry_op[n]==`PUSH || iqentry_op[n]==`PEA) ? {sregs[3'd6],12'h000} :
|
|
`endif
|
|
(iqentry_mem[n] && iqentry_op[n]!=`STCMP && iqentry_op[n]!=`STMV)? {sregs[iqentry_fn[n][5:3]],12'h000} :
|
|
`endif
|
`endif
|
iqentry_a3_v[n] ? iqentry_a3[n]
|
iqentry_a3_v[n] ? iqentry_a3[n]
|
: (iqentry_a3_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_a3_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_a3_s[n] == alu1_id) ? alu1_bus
|
: (iqentry_a3_s[n] == alu1_id) ? alu1_bus
|
: 64'hDEADDEADDEADDEAD;
|
: 64'hDEADDEADDEADDEAD;
|
Line 4470... |
Line 4493... |
end
|
end
|
default: panic <= `PANIC_INVALIDISLOT;
|
default: panic <= `PANIC_INVALIDISLOT;
|
endcase
|
endcase
|
iqentry_out[n] <= `TRUE;
|
iqentry_out[n] <= `TRUE;
|
// if it is a memory operation, this is the address-generation step ... collect result into arg1
|
// if it is a memory operation, this is the address-generation step ... collect result into arg1
|
if (iqentry_mem[n] && iqentry_op[n]!=`TLB) begin
|
if (iqentry_mem[n] && !iqentry_tlb[n]) begin
|
iqentry_a1_v[n] <= `INV;
|
iqentry_a1_v[n] <= `INV;
|
iqentry_a1_s[n] <= n[3:0];
|
iqentry_a1_s[n] <= n[3:0];
|
end
|
end
|
end
|
end
|
end
|
end
|
Line 4563... |
Line 4586... |
dram_exc <= `EXC_DBG;
|
dram_exc <= `EXC_DBG;
|
dram_bus <= 64'h0;
|
dram_bus <= 64'h0;
|
dram0 <= 3'd0;
|
dram0 <= 3'd0;
|
end
|
end
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
|
`ifdef SEGLIMITS
|
else if (dram0_addr[ABW-1:12] >= dram0_lmt) begin
|
else if (dram0_addr[ABW-1:12] >= dram0_lmt) begin
|
dram_v <= `TRUE; // we are finished the memory cycle
|
dram_v <= `TRUE; // we are finished the memory cycle
|
dram_id <= dram0_id;
|
dram_id <= dram0_id;
|
dram_tgt <= dram0_tgt;
|
dram_tgt <= dram0_tgt;
|
dram_exc <= `EXC_SEGV; //dram0_exc;
|
dram_exc <= `EXC_SEGV; //dram0_exc;
|
dram_bus <= 64'h0;
|
dram_bus <= 64'h0;
|
dram0 <= 3'd0;
|
dram0 <= 3'd0;
|
end
|
end
|
`endif
|
`endif
|
|
`endif
|
else if (!cyc_o) dram0 <= dram0 + 3'd1;
|
else if (!cyc_o) dram0 <= dram0 + 3'd1;
|
end
|
end
|
|
|
// State 2:
|
// State 2:
|
// Check for a TLB miss on the translated address, and
|
// Check for a TLB miss on the translated address, and
|
Line 4899... |
Line 4924... |
// setup by only the operating system. The system software must ensure the
|
// setup by only the operating system. The system software must ensure the
|
// segment registers are stable before they get used. We don't bother checking
|
// segment registers are stable before they get used. We don't bother checking
|
// for rf_v[].
|
// for rf_v[].
|
//
|
//
|
for (n = 0; n < QENTRIES; n = n + 1)
|
for (n = 0; n < QENTRIES; n = n + 1)
|
if (!iqentry_stomp[n] && iqentry_memissue[n] && iqentry_agen[n] && iqentry_op[n]==`TLB && !iqentry_out[n]) begin
|
if (!iqentry_stomp[n] && iqentry_memissue[n] && iqentry_agen[n] && iqentry_tlb[n] && !iqentry_out[n]) begin
|
$display("TLB issue");
|
$display("TLB issue");
|
if (!iqentry_cmt[n]) begin
|
if (!iqentry_cmt[n]) begin
|
iqentry_done[n] <= `TRUE;
|
iqentry_done[n] <= `TRUE;
|
iqentry_out[n] <= `FALSE;
|
iqentry_out[n] <= `FALSE;
|
iqentry_agen[n] <= `FALSE;
|
iqentry_agen[n] <= `FALSE;
|
Line 4941... |
Line 4966... |
dram0_id <= { 1'b1, n[2:0] };
|
dram0_id <= { 1'b1, n[2:0] };
|
dram0_misspc <= iqentry_pc[n];
|
dram0_misspc <= iqentry_pc[n];
|
dram0_op <= iqentry_op[n];
|
dram0_op <= iqentry_op[n];
|
dram0_fn <= iqentry_fn[n];
|
dram0_fn <= iqentry_fn[n];
|
dram0_tgt <= iqentry_tgt[n];
|
dram0_tgt <= iqentry_tgt[n];
|
dram0_data <= (fnIsIndexed(iqentry_op[n]) || iqentry_op[n]==`CAS) ? iqentry_a3[n] :
|
dram0_data <= (iqentry_ndx[n] || iqentry_cas[n]) ? iqentry_a3[n] :
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
iqentry_op[n]==`PEA ? iqentry_a2[n] + iqentry_a0[n] :
|
iqentry_pea[n] ? iqentry_a2[n] + iqentry_a0[n] :
|
`endif
|
`endif
|
iqentry_a2[n];
|
iqentry_a2[n];
|
dram0_datacmp <= iqentry_a2[n];
|
dram0_datacmp <= iqentry_a2[n];
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
if (iqentry_op[n]==`STCMP || iqentry_op[n]==`STMV)
|
if (iqentry_cmpmv[n])
|
dram0_addr <= iqentry_a1[n] + {sregs[iqentry_fn[n][5:3]],12'h000};
|
dram0_addr <= iqentry_a1[n] + {sregs[iqentry_fn[n][5:3]],12'h000};
|
else
|
else
|
dram0_addr <= iqentry_a1[n];
|
dram0_addr <= iqentry_a1[n];
|
dram0_seg <= {sregs[iqentry_fn[n][5:3]],12'h000};
|
dram0_seg <= {sregs[iqentry_fn[n][5:3]],12'h000};
|
dram0_lmt <= sregs[iqentry_fn[n][5:3]] + sregs_lmt[iqentry_fn[n][5:3]];
|
dram0_lmt <= sregs[iqentry_fn[n][5:3]] + sregs_lmt[iqentry_fn[n][5:3]];
|
Line 4979... |
Line 5004... |
begin
|
begin
|
if (iqentry_op[n]==`IMM && iqentry_v[(n+1)&7] &&
|
if (iqentry_op[n]==`IMM && iqentry_v[(n+1)&7] &&
|
((iqentry_pc[(n+1)&7]==iqentry_pc[n]+iqentry_insnsz[n]) ||
|
((iqentry_pc[(n+1)&7]==iqentry_pc[n]+iqentry_insnsz[n]) ||
|
(iqentry_pc[(n+1)&7]==iqentry_pc[n]))) // address inherited due to interrupt
|
(iqentry_pc[(n+1)&7]==iqentry_pc[n]))) // address inherited due to interrupt
|
iqentry_done[n] <= `TRUE;
|
iqentry_done[n] <= `TRUE;
|
/*
|
|
if (iqentry_v[n] && args_valid[n] && !iqentry_out[n] && !iq_cmt[n] && iqentry_op[n]!=`IMM) begin
|
|
iqentry_done[n] <= `TRUE;
|
|
iqentry_res[n] <= iqentry_T[n];
|
|
end
|
|
*/
|
|
if (!iqentry_v[n])
|
if (!iqentry_v[n])
|
iqentry_done[n] <= `FALSE;
|
iqentry_done[n] <= `FALSE;
|
/*
|
|
if (iqentry_v[n] && !iqentry_done[n]) begin
|
|
if (!iqentry_a1_v[n] && iqentry_v[iqentry_a1_s[n][2:0]] && iqentry_done[iqentry_a1_s[n][2:0]]) begin
|
|
iqentry_a1_v[n] <= `VAL;
|
|
iqentry_a1[n] <= iqentry_res[iqentry_a1_s[n][2:0]];
|
|
end
|
|
if (!iqentry_a2_v[n] && iqentry_v[iqentry_a2_s[n][2:0]] && iqentry_done[iqentry_a2_s[n][2:0]]) begin
|
|
iqentry_a2_v[n] <= `VAL;
|
|
iqentry_a2[n] <= iqentry_res[iqentry_a2_s[n][2:0]];
|
|
end
|
|
if (!iqentry_a3_v[n] && iqentry_v[iqentry_a3_s[n][2:0]] && iqentry_done[iqentry_a3_s[n][2:0]]) begin
|
|
iqentry_a3_v[n] <= `VAL;
|
|
iqentry_a3[n] <= iqentry_res[iqentry_a3_s[n][2:0]];
|
|
end
|
|
end
|
|
*/
|
|
end
|
end
|
|
|
|
|
// $display("TLB: en=%b imatch=%b pgsz=%d pcs=%h phys=%h", utlb1.TLBenabled,utlb1.IMatch,utlb1.PageSize,utlb1.pcs,utlb1.IPFN);
|
// $display("TLB: en=%b imatch=%b pgsz=%d pcs=%h phys=%h", utlb1.TLBenabled,utlb1.IMatch,utlb1.PageSize,utlb1.pcs,utlb1.IPFN);
|
// for (i = 0; i < 64; i = i + 1)
|
// for (i = 0; i < 64; i = i + 1)
|
Line 5040... |
Line 5043... |
begin
|
begin
|
if (StatusEXL!=8'hFF)
|
if (StatusEXL!=8'hFF)
|
StatusEXL <= StatusEXL + 8'd1;
|
StatusEXL <= StatusEXL + 8'd1;
|
end
|
end
|
|
|
|
// On a debug commit set status StatusDBG to prevent further single stepping.
|
|
`ifdef DEBUG_LOGIC
|
|
if (dbg_commit)
|
|
begin
|
|
StatusDBG <= `TRUE;
|
|
end
|
|
`endif
|
|
|
oddball_commit(commit0_v,head0);
|
oddball_commit(commit0_v,head0);
|
oddball_commit(commit1_v,head1);
|
oddball_commit(commit1_v,head1);
|
|
|
//
|
//
|
// COMMIT PHASE (dequeue only ... not register-file update)
|
// COMMIT PHASE (dequeue only ... not register-file update)
|
Line 5458... |
Line 5469... |
6'd1: dbg_adr1 <= commit_bus;
|
6'd1: dbg_adr1 <= commit_bus;
|
6'd2: dbg_adr2 <= commit_bus;
|
6'd2: dbg_adr2 <= commit_bus;
|
6'd3: dbg_adr3 <= commit_bus;
|
6'd3: dbg_adr3 <= commit_bus;
|
6'd4: dbg_ctrl <= commit_bus;
|
6'd4: dbg_ctrl <= commit_bus;
|
6'd5: dbg_stat <= commit_bus;
|
6'd5: dbg_stat <= commit_bus;
|
|
default: ;
|
endcase
|
endcase
|
6'b111111:
|
6'b111111:
|
begin
|
begin
|
ld_clk_throttle <= `TRUE;
|
ld_clk_throttle <= `TRUE;
|
clk_throttle_new <= commit_bus[15:0];
|
clk_throttle_new <= commit_bus[15:0];
|
end
|
end
|
|
default: ;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
Line 5543... |
Line 5556... |
6'd5: fnSpr = dbg_stat;
|
6'd5: fnSpr = dbg_stat;
|
default: fnSpr = 64'd0;
|
default: fnSpr = 64'd0;
|
endcase
|
endcase
|
default: fnSpr = 64'd0;
|
default: fnSpr = 64'd0;
|
endcase
|
endcase
|
|
// Not sure why bother read the commit bus here ? Why not the alu bus as well ?
|
|
// Need bypassing for write-through register file, reg read at same time as write
|
|
// Shaves a clock cycle off register updates. rf_v is being set valid on the
|
|
// clock cycle of the commit.
|
// If an spr is committing...
|
// If an spr is committing...
|
if (commit0_v && commit0_tgt=={1'b1,regno})
|
if (commit0_v && commit0_tgt=={1'b1,regno})
|
fnSpr = commit0_bus;
|
fnSpr = commit0_bus;
|
if (commit1_v && commit1_tgt=={1'b1,regno})
|
if (commit1_v && commit1_tgt=={1'b1,regno})
|
fnSpr = commit1_bus;
|
fnSpr = commit1_bus;
|
Line 5575... |
Line 5591... |
// When the RTI instruction commits clear the hardware interrupt status to enable interrupts.
|
// When the RTI instruction commits clear the hardware interrupt status to enable interrupts.
|
`RTI: begin
|
`RTI: begin
|
StatusHWI <= `FALSE;
|
StatusHWI <= `FALSE;
|
im <= imb;
|
im <= imb;
|
end
|
end
|
`RTE,`RTD:
|
`RTD:
|
|
begin
|
|
StatusDBG <= `FALSE;
|
|
if (StatusEXL!=8'h00)
|
|
StatusEXL <= StatusEXL - 8'd1;
|
|
end
|
|
`RTE:
|
begin
|
begin
|
if (StatusEXL!=8'h00)
|
if (StatusEXL!=8'h00)
|
StatusEXL <= StatusEXL - 8'd1;
|
StatusEXL <= StatusEXL - 8'd1;
|
end
|
end
|
`CACHE:
|
`CACHE:
|
Line 5610... |
Line 5632... |
task enque0a;
|
task enque0a;
|
input [2:0] tail;
|
input [2:0] tail;
|
input [2:0] inc;
|
input [2:0] inc;
|
input unlink;
|
input unlink;
|
begin
|
begin
|
|
if (fetchbuf0_pc==32'h0)
|
|
$stop;
|
|
if (fetchbuf0_pc==32'hF44)
|
|
$stop;
|
|
if (fetchbuf0_pc==32'hFFFFda49)
|
|
$stop;
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
|
`ifdef SEGLIMITS
|
// If segment limit exceeded and not in the non-segmented area.
|
// If segment limit exceeded and not in the non-segmented area.
|
if (fetchbuf0_pc >= {sregs_lmt[7],12'h000} && fetchbuf0_pc[ABW-1:ABW-4]!=4'hF)
|
if (fetchbuf0_pc >= {sregs_lmt[7],12'h000} && fetchbuf0_pc[ABW-1:ABW-4]!=4'hF)
|
set_exception(tail,8'd244);
|
set_exception(tail,8'd244);
|
`endif
|
`endif
|
|
`endif
|
// If targeting a kernel mode register and not in kernel mode.
|
// If targeting a kernel mode register and not in kernel mode.
|
// But okay if it is an SYS or INT instruction.
|
// But okay if it is an SYS or INT instruction.
|
if (fnIsKMOnlyReg(Rt0) && !km && !(opcode0==`SYS || opcode0==`INT))
|
if (fnIsKMOnlyReg(Rt0) && !km && !(opcode0==`SYS || opcode0==`INT))
|
set_exception(tail,8'd245);
|
set_exception(tail,8'd245);
|
// If attempting to use an undefined instruction
|
// If attempting to use an undefined instruction
|
Line 5661... |
Line 5691... |
iqentry_cond [tail] <= cond0;
|
iqentry_cond [tail] <= cond0;
|
iqentry_bt [tail] <= fnIsFlowCtrl(opcode0) && predict_taken0;
|
iqentry_bt [tail] <= fnIsFlowCtrl(opcode0) && predict_taken0;
|
iqentry_agen [tail] <= `INV;
|
iqentry_agen [tail] <= `INV;
|
iqentry_pc [tail] <= (opcode0==`INT && Rt0[3:0]==4'hE) ? interrupt_pc : fetchbuf0_pc;
|
iqentry_pc [tail] <= (opcode0==`INT && Rt0[3:0]==4'hE) ? interrupt_pc : fetchbuf0_pc;
|
iqentry_mem [tail] <= fetchbuf0_mem;
|
iqentry_mem [tail] <= fetchbuf0_mem;
|
|
iqentry_ndx [tail] <= fnIsIndexed(opcode0);
|
|
iqentry_cas [tail] <= opcode0==`CAS;
|
|
iqentry_pushpop[tail] <= opcode0==`PUSH || opcode0==`POP;
|
|
iqentry_pea [tail] <= opcode0==`PEA;
|
|
iqentry_cmpmv[tail] <= opcode0==`STCMP || opcode0==`STMV;
|
|
iqentry_tlb [tail] <= opcode0==`TLB;
|
iqentry_jmp [tail] <= fetchbuf0_jmp;
|
iqentry_jmp [tail] <= fetchbuf0_jmp;
|
|
iqentry_jmpi [tail] <= opcode0==`JMPI || opcode0==`JMPIX;
|
iqentry_fp [tail] <= fetchbuf0_fp;
|
iqentry_fp [tail] <= fetchbuf0_fp;
|
iqentry_rfw [tail] <= fetchbuf0_rfw;
|
iqentry_rfw [tail] <= fetchbuf0_rfw;
|
iqentry_tgt [tail] <= Rt0;
|
iqentry_tgt [tail] <= Rt0;
|
iqentry_preg [tail] <= Pn0;
|
iqentry_preg [tail] <= Pn0;
|
iqentry_pred [tail] <= pregs[Pn0];
|
iqentry_pred [tail] <= pregs[Pn0];
|
Line 5673... |
Line 5710... |
iqentry_a0[tail] <= opcode0==`INT ? fnImm(fetchbuf0_instr) :
|
iqentry_a0[tail] <= opcode0==`INT ? fnImm(fetchbuf0_instr) :
|
fnIsBranch(opcode0) ? {{DBW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} :
|
fnIsBranch(opcode0) ? {{DBW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} :
|
iqentry_op[(tail-3'd1)&7]==`IMM && iqentry_v[tail-3'd1] ? {iqentry_a0[(tail-3'd1)&7][DBW-1:8],fnImm8(fetchbuf0_instr)}:
|
iqentry_op[(tail-3'd1)&7]==`IMM && iqentry_v[tail-3'd1] ? {iqentry_a0[(tail-3'd1)&7][DBW-1:8],fnImm8(fetchbuf0_instr)}:
|
opcode0==`IMM ? fnImmImm(fetchbuf0_instr) :
|
opcode0==`IMM ? fnImmImm(fetchbuf0_instr) :
|
fnImm(fetchbuf0_instr);
|
fnImm(fetchbuf0_instr);
|
iqentry_a1 [tail] <= fnOpa(opcode0,fetchbuf0_instr,rfoa0,fetchbuf0_pc);
|
// These register recordings for simulation debug. They should be stripped
|
iqentry_a2 [tail] <= fnIsShiftiop(fetchbuf0_instr) ? {{DBW-6{1'b0}},fetchbuf0_instr[`INSTRUCTION_RB]} :
|
// out of synthesis because they don't drive any signals.
|
fnIsFPCtrl(fetchbuf0_instr) ? {{DBW-6{1'b0}},fetchbuf0_instr[`INSTRUCTION_RB]} :
|
`ifdef SIMULATION
|
opcode0==`INC ? {{56{fetchbuf0_instr[47]}},fetchbuf0_instr[47:40]} :
|
iqentry_r1 [tail] <= Ra0;
|
opcode0==`STI ? fetchbuf0_instr[27:22] :
|
iqentry_r2 [tail] <= Rb0;
|
Rb0[6] ? fnSpr(Rb0[5:0],fetchbuf0_pc) :
|
iqentry_r3 [tail] <= Rc0;
|
rfob0;
|
iqentry_rt [tail] <= Rt0;
|
|
`endif
|
|
iqentry_a1 [tail] <= fnOpa(opcode0,Ra0,fetchbuf0_instr,rfoa0,fetchbuf0_pc);
|
|
iqentry_a2 [tail] <= fnOpb(opcode0,Rb0,fetchbuf0_instr,rfob0,fetchbuf0_pc);
|
iqentry_a3 [tail] <= rfoc0;
|
iqentry_a3 [tail] <= rfoc0;
|
iqentry_T [tail] <= rfot0;
|
iqentry_T [tail] <= fnOpt(Rt0,rfot0,fetchbuf0_pc);
|
// The source is set even though the arg might be automatically valid (less logic).
|
// The source is set even though the arg might be automatically valid (less logic).
|
// This is harmless to do. Note there is no source for the 'I' argument.
|
// This is harmless to do. Note there is no source for the 'I' argument.
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn0}];
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn0}];
|
iqentry_a1_s [tail] <= //unlink ? {1'b0, (tail-1)&7} :
|
iqentry_a1_s [tail] <= //unlink ? {1'b0, (tail-1)&7} :
|
rf_source[Ra0];
|
rf_source[Ra0];
|
Line 5722... |
Line 5762... |
iqentry_cond [tail] <= which ? cond1 :cond0;
|
iqentry_cond [tail] <= which ? cond1 :cond0;
|
iqentry_bt [tail] <= 1'b0;
|
iqentry_bt [tail] <= 1'b0;
|
iqentry_agen [tail] <= `INV;
|
iqentry_agen [tail] <= `INV;
|
iqentry_pc [tail] <= which ? fetchbuf1_pc : fetchbuf0_pc;
|
iqentry_pc [tail] <= which ? fetchbuf1_pc : fetchbuf0_pc;
|
iqentry_mem [tail] <= 1'b0;
|
iqentry_mem [tail] <= 1'b0;
|
|
iqentry_ndx [tail] <= 1'b0;
|
|
iqentry_cas [tail] <= 1'b0;
|
|
iqentry_pushpop[tail] <= 1'b0;
|
|
iqentry_pea [tail] <= 1'b0;
|
|
iqentry_cmpmv[tail] <= 1'b0;
|
|
iqentry_tlb [tail] <= 1'b0;
|
iqentry_jmp [tail] <= 1'b0;
|
iqentry_jmp [tail] <= 1'b0;
|
|
iqentry_jmpi [tail] <= 1'b0;
|
iqentry_fp [tail] <= 1'b0;
|
iqentry_fp [tail] <= 1'b0;
|
iqentry_rfw [tail] <= 1'b1;
|
iqentry_rfw [tail] <= 1'b1;
|
iqentry_tgt [tail] <= 7'd27;
|
iqentry_tgt [tail] <= 7'd27;
|
iqentry_pred [tail] <= pregs[which ? Pn1 : Pn0];
|
iqentry_pred [tail] <= pregs[which ? Pn1 : Pn0];
|
// Look at the previous queue slot to see if an immediate prefix is enqueued
|
// Look at the previous queue slot to see if an immediate prefix is enqueued
|
Line 5762... |
Line 5809... |
input [2:0] tail;
|
input [2:0] tail;
|
input [2:0] inc;
|
input [2:0] inc;
|
input test_stomp;
|
input test_stomp;
|
input validate_args;
|
input validate_args;
|
begin
|
begin
|
if (opcode0==`NOP)
|
if (`FALSE)
|
queued1 = `TRUE; // to update fetch buffers
|
;
|
|
// if (opcode0==`NOP)
|
|
// queued1 = `TRUE; // to update fetch buffers
|
|
`ifdef DEBUG_LOGIC
|
|
else
|
|
if (dbg_ctrl[7] && !StatusDBG) begin
|
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
|
enque0a(tail,3'd2,1'b0);
|
|
set_exception((tail+1)&7,8'd243);
|
|
allowq = `FALSE;
|
|
end
|
|
end
|
|
`endif
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
// A pop instruction takes 2 queue entries.
|
// A pop instruction takes 2 queue entries.
|
else if (fnIsPop(fetchbuf0_instr)|fnIsPush(fetchbuf0_instr)|opcode0==`LINK) begin
|
else if (fnIsPop(fetchbuf0_instr)|fnIsPush(fetchbuf0_instr)|opcode0==`LINK) begin
|
$display("0 found push/pop");
|
$display("0 found push/pop");
|
if (iqentry_v[tail]==`INV && iqentry_v[tail+1]==`INV) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
$display("enqueing2");
|
$display("enqueing2");
|
enque0a(tail,3'd2,1'b0);
|
enque0a(tail,3'd2,1'b0);
|
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf0_instr),opcode0==`LINK,0,0);
|
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf0_instr),opcode0==`LINK,0,0);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
|
`ifdef UNLINKOP
|
else if (opcode0==`UNLINK) begin
|
else if (opcode0==`UNLINK) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
enquePushpopAdd(tail,1'b0,1'b0,1'b1,0);
|
enquePushpopAdd(tail,1'b0,1'b0,1'b1,0);
|
enque0a((tail+1)&7,3'd2,1'b1);
|
enque0a((tail+1)&7,3'd2,1'b1);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
|
`endif
|
else if (iqentry_v[tail] == `INV) begin
|
else if (iqentry_v[tail] == `INV) begin
|
if ((({fnIsBranch(opcode0), predict_taken0} == {`TRUE, `TRUE})||(opcode0==`LOOP)) && test_stomp)
|
if ((({fnIsBranch(opcode0), predict_taken0} == {`TRUE, `TRUE})||(opcode0==`LOOP)) && test_stomp)
|
qstomp = `TRUE;
|
qstomp = `TRUE;
|
enque0a(tail,inc,0);
|
enque0a(tail,inc,0);
|
end
|
end
|
Line 5797... |
Line 5858... |
input [2:0] tail;
|
input [2:0] tail;
|
input [2:0] inc;
|
input [2:0] inc;
|
input validate_args;
|
input validate_args;
|
input unlink;
|
input unlink;
|
begin
|
begin
|
|
if (fetchbuf1_pc==32'h0)
|
|
$stop;
|
|
if (fetchbuf1_pc==32'hF44)
|
|
$stop;
|
|
if (fetchbuf1_pc==32'hFFFFDA49)
|
|
$stop;
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
|
`ifdef SEGLIMITS
|
if (fetchbuf1_pc >= {sregs_lmt[7],12'h000} && fetchbuf1_pc[ABW-1:ABW-4]!=4'hF)
|
if (fetchbuf1_pc >= {sregs_lmt[7],12'h000} && fetchbuf1_pc[ABW-1:ABW-4]!=4'hF)
|
set_exception(tail,8'd244);
|
set_exception(tail,8'd244);
|
`endif
|
`endif
|
|
`endif
|
if (fnIsKMOnlyReg(Rt1) && !km && !(opcode1==`SYS || opcode1==`INT))
|
if (fnIsKMOnlyReg(Rt1) && !km && !(opcode1==`SYS || opcode1==`INT))
|
set_exception(tail,8'd245);
|
set_exception(tail,8'd245);
|
`ifdef TRAP_ILLEGALOPS
|
`ifdef TRAP_ILLEGALOPS
|
if (fnIsIllegal(opcode1,opcode1==`MLO ? rfoc1[5:0] : fnFunc(fetchbuf1_instr)))
|
if (fnIsIllegal(opcode1,opcode1==`MLO ? rfoc1[5:0] : fnFunc(fetchbuf1_instr)))
|
set_exception(tail,8'd250);
|
set_exception(tail,8'd250);
|
Line 5849... |
Line 5918... |
// If a string operation was in progress then inherit the address of the string operation so that
|
// If a string operation was in progress then inherit the address of the string operation so that
|
// it can be continued.
|
// it can be continued.
|
|
|
iqentry_pc [tail] <= (opcode1==`INT && Rt1[3:0]==4'hE) ? interrupt_pc : fetchbuf1_pc;
|
iqentry_pc [tail] <= (opcode1==`INT && Rt1[3:0]==4'hE) ? interrupt_pc : fetchbuf1_pc;
|
iqentry_mem [tail] <= fetchbuf1_mem;
|
iqentry_mem [tail] <= fetchbuf1_mem;
|
|
iqentry_ndx [tail] <= fnIsIndexed(opcode1);
|
|
iqentry_cas [tail] <= opcode1==`CAS;
|
|
iqentry_pushpop[tail] <= opcode1==`PUSH || opcode1==`POP;
|
|
iqentry_pea [tail] <= opcode1==`PEA;
|
|
iqentry_cmpmv[tail] <= opcode1==`STCMP || opcode1==`STMV;
|
|
iqentry_tlb [tail] <= opcode1==`TLB;
|
iqentry_jmp [tail] <= fetchbuf1_jmp;
|
iqentry_jmp [tail] <= fetchbuf1_jmp;
|
|
iqentry_jmpi [tail] <= opcode1==`JMPI || opcode1==`JMPIX;
|
iqentry_fp [tail] <= fetchbuf1_fp;
|
iqentry_fp [tail] <= fetchbuf1_fp;
|
iqentry_rfw [tail] <= fetchbuf1_rfw;
|
iqentry_rfw [tail] <= fetchbuf1_rfw;
|
iqentry_tgt [tail] <= Rt1;
|
iqentry_tgt [tail] <= Rt1;
|
iqentry_preg [tail] <= Pn1;
|
iqentry_preg [tail] <= Pn1;
|
iqentry_pred [tail] <= pregs[Pn1];
|
iqentry_pred [tail] <= pregs[Pn1];
|
Line 5863... |
Line 5939... |
fnIsBranch(opcode1) ? {{DBW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} :
|
fnIsBranch(opcode1) ? {{DBW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} :
|
(queued1 && opcode0==`IMM) ? {fnImmImm(fetchbuf0_instr)|fnImm8(fetchbuf1_instr)} :
|
(queued1 && opcode0==`IMM) ? {fnImmImm(fetchbuf0_instr)|fnImm8(fetchbuf1_instr)} :
|
(!queued1 && iqentry_op[(tail-3'd1)&7]==`IMM) && iqentry_v[(tail-3'd1)&7] ? {iqentry_a0[(tail-3'd1)&7][DBW-1:8],fnImm8(fetchbuf1_instr)} :
|
(!queued1 && iqentry_op[(tail-3'd1)&7]==`IMM) && iqentry_v[(tail-3'd1)&7] ? {iqentry_a0[(tail-3'd1)&7][DBW-1:8],fnImm8(fetchbuf1_instr)} :
|
opcode1==`IMM ? fnImmImm(fetchbuf1_instr) :
|
opcode1==`IMM ? fnImmImm(fetchbuf1_instr) :
|
fnImm(fetchbuf1_instr);
|
fnImm(fetchbuf1_instr);
|
iqentry_a1 [tail] <= fnOpa(opcode1,fetchbuf1_instr,rfoa1,fetchbuf1_pc);
|
iqentry_a1 [tail] <= fnOpa(opcode1,Ra1,fetchbuf1_instr,rfoa1,fetchbuf1_pc);
|
iqentry_a2 [tail] <= fnIsShiftiop(fetchbuf1_instr) ? {{DBW-6{1'b0}},fetchbuf1_instr[`INSTRUCTION_RB]} :
|
iqentry_a2 [tail] <= fnOpb(opcode1,Rb1,fetchbuf1_instr,rfob1,fetchbuf1_pc);
|
fnIsFPCtrl(fetchbuf1_instr) ? {{DBW-6{1'b0}},fetchbuf1_instr[`INSTRUCTION_RB]} :
|
|
opcode1==`INC ? {{56{fetchbuf1_instr[47]}},fetchbuf1_instr[47:40]} :
|
|
opcode1==`STI ? fetchbuf1_instr[27:22] :
|
|
Rb1[6] ? fnSpr(Rb1[5:0],fetchbuf1_pc) :
|
|
rfob1;
|
|
iqentry_a3 [tail] <= rfoc1;
|
iqentry_a3 [tail] <= rfoc1;
|
iqentry_T [tail] <= rfot1;
|
iqentry_T [tail] <= fnOpt(Rt1,rfot1,fetchbuf1_pc);
|
|
`ifdef SIMULATION
|
|
iqentry_r1 [tail] <= Ra1;
|
|
iqentry_r2 [tail] <= Rb1;
|
|
iqentry_r3 [tail] <= Rc1;
|
|
iqentry_rt [tail] <= Rt1;
|
|
`endif
|
// The source is set even though the arg might be automatically valid (less logic). If
|
// The source is set even though the arg might be automatically valid (less logic). If
|
// queueing two entries the source settings may be overridden in the argument valudation.
|
// queueing two entries the source settings may be overridden in the argument valudation.
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn1}];
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn1}];
|
iqentry_a1_s [tail] <= //unlink ? {1'b0, (tail-3'd1)&7} :
|
iqentry_a1_s [tail] <= //unlink ? {1'b0, (tail-3'd1)&7} :
|
rf_source[Ra1];
|
rf_source[Ra1];
|
Line 5896... |
Line 5973... |
input [2:0] tail;
|
input [2:0] tail;
|
input [2:0] inc;
|
input [2:0] inc;
|
input test_stomp;
|
input test_stomp;
|
input validate_args;
|
input validate_args;
|
begin
|
begin
|
if (opcode1==`NOP) begin
|
if (`FALSE)
|
if (queued1==`TRUE) queued2 = `TRUE;
|
;
|
queued1 = `TRUE;
|
// if (opcode1==`NOP) begin
|
|
// if (queued1==`TRUE) queued2 = `TRUE;
|
|
// queued1 = `TRUE;
|
|
// end
|
|
`ifdef DEBUG_LOGIC
|
|
else
|
|
if (dbg_ctrl[7] && !StatusDBG) begin
|
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
|
enque1a(tail,3'd2,1,0);
|
|
set_exception((tail+1)&7,8'd243);
|
|
allowq = `FALSE;
|
end
|
end
|
|
end
|
|
`endif
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
else if (fnIsPop(fetchbuf1_instr)|fnIsPush(fetchbuf1_instr)|opcode1==`LINK) begin
|
else if (fnIsPop(fetchbuf1_instr)|fnIsPush(fetchbuf1_instr)|opcode1==`LINK) begin
|
$display("1 found push/pop");
|
$display("1 found push/pop");
|
$display("iqv[%d]:%d", tail,iqentry_v[tail]);
|
$display("iqv[%d]:%d", tail,iqentry_v[tail]);
|
$display("iqv[%d+1]:%d", tail, iqentry_v[tail+1]);
|
$display("iqv[%d+1]:%d", tail, iqentry_v[tail+1]);
|
Line 5914... |
Line 6003... |
enque1a(tail,3'd2,1,0);
|
enque1a(tail,3'd2,1,0);
|
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf1_instr),opcode1==`LINK,0,1);
|
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf1_instr),opcode1==`LINK,0,1);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
|
`ifdef UNLINKOP
|
else if (opcode1==`UNLINK) begin
|
else if (opcode1==`UNLINK) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
enquePushpopAdd(tail,1'b0,1'b0,1'b1,1);
|
enquePushpopAdd(tail,1'b0,1'b0,1'b1,1);
|
enque1a((tail+1)&7,3'd2,1,1);
|
enque1a((tail+1)&7,3'd2,1,1);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
|
`endif
|
else if (iqentry_v[tail] == `INV && !qstomp) begin
|
else if (iqentry_v[tail] == `INV && !qstomp) begin
|
if ((({fnIsBranch(opcode1), predict_taken1} == {`TRUE, `TRUE})||(opcode1==`LOOP)) && test_stomp)
|
if ((({fnIsBranch(opcode1), predict_taken1} == {`TRUE, `TRUE})||(opcode1==`LOOP)) && test_stomp)
|
qstomp = `TRUE;
|
qstomp = `TRUE;
|
enque1a(tail,inc,validate_args,0);
|
enque1a(tail,inc,validate_args,0);
|
if (queued1==`TRUE) queued2 = `TRUE;
|
if (queued1==`TRUE) queued2 = `TRUE;
|