OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /thor
    from Rev 9 to Rev 10
    Reverse comparison

Rev 9 → Rev 10

/trunk/rtl/verilog/Thor.v
199,6 → 199,7
reg fxe;
reg nmi1,nmi_edge;
reg StatusHWI;
reg StatusDBG;
reg [7:0] StatusEXL;
assign km = StatusHWI | |StatusEXL;
reg [7:0] GM; // register group mask
207,6 → 208,7
wire int_commit;
wire int_pending;
wire sys_commit;
wire dbg_commit;
`ifdef SEGMENTATION
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];
236,7 → 238,14
reg iqentry_bt [0:7]; // branch-taken (used only for branches)
reg iqentry_agen [0:7]; // memory address is generated
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_jmpi [0:7];
reg iqentry_fp [0:7]; // is an floating point operation
reg iqentry_rfw [0:7]; // writes to register file
reg [DBW-1:0] iqentry_res [0:7]; // instruction result
252,14 → 261,18
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_a1 [0:7]; // argument 1
reg [6:0] iqentry_r1 [0:7];
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 [6:0] iqentry_r2 [0:7];
reg [DBW-1:0] iqentry_a2 [0:7]; // argument 2
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 [6:0] iqentry_r3 [0:7];
reg [DBW-1:0] iqentry_a3 [0:7]; // argument 3
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 [6:0] iqentry_rt [0:7];
reg [DBW-1:0] iqentry_T [0:7];
reg iqentry_T_v [0:7];
reg [3:0] iqentry_T_s [0:7];
434,6 → 447,8
wire alu1_branchmiss;
reg [ABW+3:0] alu1_misspc;
 
wire jmpi_miss;
reg [ABW-1:0] jmpi_misspc;
wire mem_stringmissx;
reg mem_stringmiss;
wire branchmiss;
946,10 → 961,12
fnRa = {3'h5,isn[23:20]};
`TLB: fnRa = {1'b0,isn[29:24]};
`P: fnRa = 7'h70;
`LOOP: fnRa = 7'h5F;
`LOOP: fnRa = 7'h73;
`PUSH: fnRa = km ? 7'd31 : 7'd27;
`ifdef STACKOPS
`PUSH,`PEA,`POP,`LINK: fnRa = 7'd27;
`PEA,`POP,`LINK: fnRa = km ? 7'd31 : 7'd27;
`endif
`MFSPR,`MOVS: fnRa = {1'b1,isn[`INSTRUCTION_RA]};
default: fnRa = {1'b0,isn[`INSTRUCTION_RA]};
endcase
endcase
961,17 → 978,14
fnRb = 7'h51;
else
case(isn[15:8])
`RTI: fnRb = 7'h5E;
`RTD: fnRb = 7'h5B;
`RTE: fnRb = 7'h5D;
`RTS2: fnRb = 7'd27;
`LOOP: fnRb = 7'h73;
`RTS,`STP,`TLB,`POP: fnRb = 7'd0;
`RTS2: fnRb = km ? 7'd31 : 7'd27;
// `LOOP: fnRb = 7'h73;
// `RTS,`STP,`TLB,`POP: fnRb = 7'd0;
`JSR,`JSRS,`JSRZ,`SYS,`INT:
fnRb = {3'h5,isn[23:20]};
`SWS: fnRb = {1'b1,isn[27:22]};
`PUSH: fnRb = isn[22:16];
`ifdef STACKOPS
`PUSH: fnRb = isn[22:16];
`LINK: fnRb = {1'b0,isn[27:22]};
`PEA: fnRb = {1'b0,isn[21:16]};
`endif
1006,6 → 1020,10
else
case(isn[15:8])
`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'h11: fnFunc = isn[31:28];
8'h12: fnFunc = isn[31:28];
1039,8 → 1057,12
8'h0E: fnFunc = isn[23:22];
8'h0F: fnFunc = isn[23:22];
`INC: fnFunc = isn[24:22];
`TLB: fnFunc = isn[19:16];
`RTS,`RTS2: fnFunc = isn[19:16]; // used to pass a small immediate
`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:
fnFunc = isn[39:34];
endcase
1143,7 → 1165,7
`LDI,`LDIS,`IMM,`NOP,`STP: fnSource2_v = 1'b1;
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC:
fnSource2_v = 1'b1;
`RTI,`RTD,`RTE: fnSource2_v = 1'b1;
`RTI,`RTD,`RTE,`JMPI: fnSource2_v = 1'b1;
// TST
8'h00: fnSource2_v = 1'b1;
8'h01: fnSource2_v = 1'b1;
1212,7 → 1234,7
fnSource2_v = `FALSE;
`CACHE,`LCL,`TLB,
`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;
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS:
fnSource2_v = 1'b1;
1223,7 → 1245,7
fnSource2_v = 1'b0;
else
fnSource2_v = 1'b1;
`LOOP: fnSource2_v = 1'b0;
`LOOP: fnSource2_v = 1'b1;
default: fnSource2_v = 1'b0;
endcase
endfunction
1267,7 → 1289,7
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`MOVS,`STP:
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;
`ADDI,`ADDUI,`ADDUIS:
fnNumReadPorts = 3'd1;
1284,7 → 1306,7
else
fnNumReadPorts = 3'd2;
`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;
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`BR:
fnNumReadPorts = 3'd1;
1513,10 → 1535,15
// 68-6F = segment limit register
// 70 = predicate register horizontal
// 73 = loop counter
// 7C = breakout index register
// 7D = broken out register
// 7F = power shift register
function [6:0] fnTargetReg;
input [63:0] ir;
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;
else
case(fnOpcode(ir))
1533,12 → 1560,12
fnTargetReg = {1'b0,ir[33:28]};
`SHIFT:
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,
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
`ANDI,`ORI,`EORI,
`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]};
`CAS:
fnTargetReg = {1'b0,ir[39:34]};
1554,56 → 1581,20
`BITI:
fnTargetReg = {3'h4,ir[25:22]};
// TST
8'h00,
8'h01,
8'h02,
8'h03,
8'h04,
8'h05,
8'h06,
8'h07,
8'h08,
8'h09,
8'h0A,
8'h0B,
8'h0C,
8'h0D,
8'h0E,
8'h0F,
8'h00,8'h01,8'h02,8'h03,
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
8'h10,
8'h11,
8'h12,
8'h13,
8'h14,
8'h15,
8'h16,
8'h17,
8'h18,
8'h19,
8'h1A,
8'h1B,
8'h1C,
8'h1D,
8'h1E,
8'h1F,
8'h10,8'h11,8'h12,8'h13,
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
8'h20,
8'h21,
8'h22,
8'h23,
8'h24,
8'h25,
8'h26,
8'h27,
8'h28,
8'h29,
8'h2A,
8'h2B,
8'h2C,
8'h2D,
8'h2E,
8'h2F:
8'h20,8'h21,8'h22,8'h23,
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
fnTargetReg = {3'h4,ir[11:8]};
end
1610,6 → 1601,10
`SWCR: fnTargetReg = {3'h4,4'h0};
`JSR,`JSRZ,`JSRS,`SYS,`INT:
fnTargetReg = {3'h5,ir[19:16]};
`JMPI:
fnTargetReg = {3'h5,ir[25:22]};
`JMPIX:
fnTargetReg = {3'h5,ir[31:28]};
`MTSPR,`MOVS,`LWS:
fnTargetReg = {1'b1,ir[27:22]};
/*
1622,7 → 1617,7
else
fnTargetReg = 7'h00;
*/
`RTS2: fnTargetReg = 7'd27;
`RTS2,`PUSH: fnTargetReg = km ? 7'd31 : 7'd27;
`LOOP: fnTargetReg = 7'h73;
`STP: fnTargetReg = 7'h7F;
`P: fnTargetReg = 7'h70;
1645,6 → 1640,8
case(fnOpcode(ir))
`JSR,`JSRZ,`JSRS,`SYS,`INT:
fnTargetsCa = `TRUE;
`JMPI,`JMPIX:
fnTargetsCa = `TRUE;
`LWS:
if (ir[27:26]==2'h1)
fnTargetsCa = `TRUE;
1701,44 → 1698,21
`ADDI,`SUBI,`ADDUI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
// CMPI
8'h20,
8'h21,
8'h22,
8'h23,
8'h24,
8'h25,
8'h26,
8'h27,
8'h28,
8'h29,
8'h2A,
8'h2B,
8'h2C,
8'h2D,
8'h2E,
8'h2F,
8'h20,8'h21,8'h22,8'h23,
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
8'h30,
8'h31,
8'h32,
8'h33,
8'h34,
8'h35,
8'h36,
8'h37,
8'h38,
8'h39,
8'h3A,
8'h3B,
8'h3C,
8'h3D,
8'h3E,
8'h3F,
8'h30,8'h31,8'h32,8'h33,
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,
// `SHLI,`SHLUI,`SHRI,`SHRUI,`ROLI,`RORI,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`LEA,`INC,
`LVB,`LVC,`LVH,`LVW,`LVWAR,`STI,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`INC,
`LVB,`LVC,`LVH,`LVW,`LVWAR,`STI,`JMPI,
`SB,`SC,`SH,`SW,`SWCR,`CAS,`SWS,
`RTI,`RTD,`RTE,
`JSR,`JSRS,`SYS,`INT,`RTS2,`LOOP,`PEA,`LINK,`UNLINK:
fnHasConst = 1'b1;
default:
1746,10 → 1720,12
endcase
endfunction
 
// Used by memory issue logic.
function fnIsFlowCtrl;
input [7:0] opcode;
begin
case(opcode)
`JMPI,`JMPIX,
`JSR,`JSRS,`JSRZ,`SYS,`INT,`LOOP,`RTS,`RTS2,`RTI,`RTD,`RTE:
fnIsFlowCtrl = 1'b1;
default:
1762,7 → 1738,7
endfunction
 
// fnCanException
// Used by issue logic.
// Used by memory issue logic.
// Returns TRUE if the instruction can cause an exception
//
function fnCanException;
1909,6 → 1885,7
opcode==`TLB || opcode==`CAS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
opcode==`LWS || opcode==`SWS || opcode==`STI ||
opcode==`INC ||
opcode==`JMPI || opcode==`JMPIX ||
opcode==`PUSH || opcode==`POP || opcode==`PEA || opcode==`LINK || opcode==`UNLINK
;
endfunction
1916,7 → 1893,8
function fnIsNdxd;
input [7:0] opcode;
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
 
1931,13 → 1909,15
opcode==`LVB || opcode==`LVH || opcode==`LVC || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
opcode==`RTS2 || opcode==`STP ||
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==`_2ADDUI || opcode==`_4ADDUI || opcode==`_8ADDUI || opcode==`_16ADDUI ||
opcode==`ANDI || opcode==`ORI || opcode==`EORI ||
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==`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==`LDI || opcode==`LDIS || opcode==`ADDUIS || opcode==`MFSPR ||
// Branch registers / Segment registers
1965,7 → 1945,7
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==`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;
endfunction
 
1977,7 → 1957,7
function fnIsIndexed;
input [7:0] opcode;
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
 
//
2043,11 → 2023,11
fnIsIllegal = `TRUE;
8'h73,8'h74,8'h75,8'h76,8'h7A,8'h7B,8'h7C,8'h7D,8'h7E,8'h7F:
fnIsIllegal = `TRUE;
8'h87,8'h88,8'h89,8'h8A,8'h8D:
8'h87,8'h88,8'h89,8'h8A:
fnIsIllegal = `TRUE;
8'h94,8'h95,8'h9C:
fnIsIllegal = `TRUE;
8'hB7,8'b10111xxx:
8'b10111xxx:
fnIsIllegal = `TRUE;
8'hC4,8'hC5,8'b11001xxx:
fnIsIllegal = `TRUE;
2083,6 → 2063,17
fnSelect = 8'hFF;
default: fnSelect = 8'h00;
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:
case(adr[1:0])
3'd0: fnSelect = 8'h11;
2133,7 → 2124,24
fnSelect = 8'hFF;
default: fnSelect = 8'h00;
endcase
`LB,`LBU,`LBX,`SB,`LVB,`LBUX,`SBX:
`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:
case(adr[2:0])
3'd0: fnSelect = 8'h01;
3'd1: fnSelect = 8'h02;
2191,6 → 2199,17
default:
fnDatai = dat[31:0];
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:
case(sel[3:0])
8'h1: fnDatai = {{24{dat[7]}},dat[7:0]};
2255,6 → 2274,25
endcase
3'd3,3'd7: fnDatai = dat;
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:
case(sel)
8'h01: fnDatai = {{DBW*7/8{dat[DBW*1/8-1]}},dat[DBW*1/8-1:0]};
2385,31 → 2423,19
// (ihit ? fetchbuf1_pc + {{DBW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} + 64'd3 : fetchbuf1_pc);
always @*
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;
else
branch_pc <= fetchbuf0_pc;
branch_pc <= fetchbuf0_pc + {{ABW-12{fetchbuf0_instr[11]}},fetchbuf0_instr[11:8],fetchbuf0_instr[23:16]} + 64'd3;
end
else if (opcode0==`LOOP && fetchbuf0_v) begin
if (ihit)
branch_pc <= fetchbuf0_pc + {{ABW-8{fetchbuf0_instr[23]}},fetchbuf0_instr[23:16]} + 64'd3;
else
branch_pc <= fetchbuf0_pc;
branch_pc <= fetchbuf0_pc + {{ABW-8{fetchbuf0_instr[23]}},fetchbuf0_instr[23:16]} + 64'd3;
end
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;
else
branch_pc <= fetchbuf1_pc;
branch_pc <= fetchbuf1_pc + {{ABW-12{fetchbuf1_instr[11]}},fetchbuf1_instr[11:8],fetchbuf1_instr[23:16]} + 64'd3;
end
else if (opcode1==`LOOP && fetchbuf1_v) begin
if (ihit)
branch_pc <= fetchbuf1_pc + {{ABW-8{fetchbuf1_instr[23]}},fetchbuf1_instr[23:16]} + 64'd3;
else
branch_pc <= fetchbuf1_pc;
branch_pc <= fetchbuf1_pc + {{ABW-8{fetchbuf1_instr[23]}},fetchbuf1_instr[23:16]} + 64'd3;
end
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
 
assign int_pending = (nmi_edge & ~StatusHWI & ~int_commit) || (irq_i & ~im & ~StatusHWI & ~int_commit);
2417,6 → 2443,8
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);
 
assign jmpi_miss = dram_v && (dram0_op==`JMPI || dram0_op==`JMPIX);
 
// "Stream" interrupt instructions into the instruction stream until an INT
// instruction commits. This avoids the problem of an INT instruction being
// stomped on by a previous branch instruction.
2511,28 → 2539,18
`SYS,`INT: fnImm = insn[31:24];
`RTS2: fnImm = {insn[31:27],3'b000};
//`CMPI,
8'h20,
8'h21,
8'h22,
8'h23,
8'h24,
8'h25,
8'h26,
8'h27,
8'h28,
8'h29,
8'h2A,
8'h2B,
8'h2C,
8'h2D,
8'h2E,
8'h2F,
8'h20,8'h21,8'h22,8'h23,
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:
fnImm = {{54{insn[31]}},insn[31:22]};
`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]};
`PUSH: fnImm = 64'hFFFFFFFFFFFFFFF8; //-8
//`LINK: fnImm = {insn[39:28],3'b000};
`JMPI,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
fnImm = {{55{insn[36]}},insn[36:28]};
2558,29 → 2576,19
`BITFIELD: fnImm8 = insn[39:32];
`SYS,`INT: fnImm8 = insn[31:24];
//`CMPI,
8'h20,
8'h21,
8'h22,
8'h23,
8'h24,
8'h25,
8'h26,
8'h27,
8'h28,
8'h29,
8'h2A,
8'h2B,
8'h2C,
8'h2D,
8'h2E,
8'h2F,
8'h20,8'h21,8'h22,8'h23,
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];
`RTS: fnImm8 = insn[19:16];
`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm8 = 8'h00;
`STI: fnImm8 = insn[35:28];
`PUSH: fnImm8 = 8'hF8;
`ifdef STACKOPS
`LINK: fnImm8 = {insn[32:28],3'b000};
`endif
`JMPI,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,
`SB,`SC,`SH,`SW,`SWCR,`LWS,`SWS,`INC,`LCL,`PEA:
fnImm8 = insn[35:28];
2605,22 → 2613,10
`JSRS:
fnImmMSB = insn[39];
//`CMPI,
8'h20,
8'h21,
8'h22,
8'h23,
8'h24,
8'h25,
8'h26,
8'h27,
8'h28,
8'h29,
8'h2A,
8'h2B,
8'h2C,
8'h2D,
8'h2E,
8'h2F,
8'h20,8'h21,8'h22,8'h23,
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:
fnImmMSB = insn[31];
`SYS,`INT,`CACHE,`LINK:
2627,9 → 2623,11
fnImmMSB = 1'b0; // SYS,INT are unsigned
`RTS,`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`RTS2,`STS:
fnImmMSB = 1'b0; // RTS is unsigned
`PUSH: fnImmMSB = 1'b1;
`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`LWX,
`SBX,`SCX,`SHX,`SWX:
fnImmMSB = insn[47];
`JMPI,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,
`SB,`SC,`SH,`SW,`SWCR,`STI,`LWS,`SWS,`INC,`LCL,`PEA:
fnImmMSB = insn[36];
2655,8 → 2653,11
 
 
// 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;
input [7:0] opcode;
input [6:0] Ra;
input [63:0] ins;
input [63:0] rfo;
input [63:0] epc;
2666,28 → 2667,42
fnOpa = ins[21:16];
else
`endif
if (opcode==`RTS) begin
fnOpa = (commit1_v && commit1_tgt[6:0]==7'h51) ? commit1_bus :
(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);
if (Ra[6])
fnOpa = fnSpr(Ra[5:0],epc);
else
fnOpa = rfo;
end
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.
function fnIsKMOnly;
input [7:0] op;
2699,7 → 2714,8
function fnIsKMOnlyReg;
input [6:0] regx;
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
 
// Returns TRUE if the register is automatically valid.
3512,6 → 3528,12
(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 &&
(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)
if (rst_i)
3779,11 → 3801,13
else begin
if (iqentry_op[alu0_id[2:0]]!=`IMM)
iqentry_done[ alu0_id[2:0] ] <= (!iqentry_mem[ alu0_id[2:0] ] || !alu0_cmt);
iqentry_res [ alu0_id[2:0] ] <= alu0_bus;
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_out [ alu0_id[2:0] ] <= `FALSE;
iqentry_cmt [ alu0_id[2:0] ] <= alu0_cmt;
iqentry_agen[ alu0_id[2:0] ] <= `TRUE;
iqentry_out [ alu0_id[2:0] ] <= `FALSE;
end
end
 
3807,11 → 3831,13
else begin
if (iqentry_op[alu1_id[2:0]]!=`IMM)
iqentry_done[ alu1_id[2:0] ] <= (!iqentry_mem[ alu1_id[2:0] ] || !alu1_cmt);
iqentry_res [ alu1_id[2:0] ] <= alu1_bus;
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_out [ alu1_id[2:0] ] <= `FALSE;
iqentry_cmt [ alu1_id[2:0] ] <= alu1_cmt;
iqentry_agen[ alu1_id[2:0] ] <= `TRUE;
iqentry_out [ alu1_id[2:0] ] <= `FALSE;
end
end
 
4155,16 → 4181,19
//
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);
iqentry_res [ dram_id[2:0] ] <= dram_bus;
if (!iqentry_jmpi[dram_id[2:0]])
iqentry_res [ dram_id[2:0] ] <= dram_bus;
// If an exception occurred, stuff an interrupt instruction into the queue
// slot. The instruction will re-issue as an ALU operation. We can change
// the queued instruction because it isn't finished yet.
if (|dram_exc)
if (|dram_exc) begin
set_exception(dram_id,
dram_exc==`EXC_DBE ? 8'hFB :
dram_exc==`EXC_DBG ? 8'd243 :
dram_exc==`EXC_SEGV ? 8'd244 :
8'hF8); // F8 = TLBMiss exception 243 = debug
$stop;
end
else begin
// Note that the predicate was already evaluated to TRUE before the
// dram operation started.
4183,19 → 4212,19
// 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
//
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;
iqentry_done[ dram0_id[2:0] ] <= `TRUE;
iqentry_cmt [ dram0_id[2:0]] <= `TRUE;
iqentry_out[ dram0_id[2:0] ] <= `FALSE;
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;
iqentry_done[ dram1_id[2:0] ] <= `TRUE;
iqentry_cmt [ dram1_id[2:0]] <= `TRUE;
iqentry_out[ dram1_id[2:0] ] <= `FALSE;
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;
iqentry_done[ dram2_id[2:0] ] <= `TRUE;
iqentry_cmt [ dram2_id[2:0]] <= `TRUE;
4414,10 → 4443,7
: 64'hDEADDEADDEADDEAD;
alu0_argC <=
`ifdef SEGMENTATION
`ifdef STACKOPS
(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} :
(iqentry_mem[n] && !iqentry_cmpmv[n]) ? {sregs[iqentry_fn[n][5:3]],12'h000} :
`endif
iqentry_a3_v[n] ? iqentry_a3[n]
: (iqentry_a3_s[n] == alu0_id) ? alu0_bus
4452,10 → 4478,7
: 64'hDEADDEADDEADDEAD;
alu1_argC <=
`ifdef SEGMENTATION
`ifdef STACKOPS
(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} :
(iqentry_mem[n] && !iqentry_cmpmv[n])? {sregs[iqentry_fn[n][5:3]],12'h000} :
`endif
iqentry_a3_v[n] ? iqentry_a3[n]
: (iqentry_a3_s[n] == alu0_id) ? alu0_bus
4472,7 → 4495,7
endcase
iqentry_out[n] <= `TRUE;
// 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_s[n] <= n[3:0];
end
4565,6 → 4588,7
dram0 <= 3'd0;
end
`ifdef SEGMENTATION
`ifdef SEGLIMITS
else if (dram0_addr[ABW-1:12] >= dram0_lmt) begin
dram_v <= `TRUE; // we are finished the memory cycle
dram_id <= dram0_id;
4574,6 → 4598,7
dram0 <= 3'd0;
end
`endif
`endif
else if (!cyc_o) dram0 <= dram0 + 3'd1;
end
 
4901,7 → 4926,7
// for rf_v[].
//
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");
if (!iqentry_cmt[n]) begin
iqentry_done[n] <= `TRUE;
4943,14 → 4968,14
dram0_op <= iqentry_op[n];
dram0_fn <= iqentry_fn[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
iqentry_op[n]==`PEA ? iqentry_a2[n] + iqentry_a0[n] :
iqentry_pea[n] ? iqentry_a2[n] + iqentry_a0[n] :
`endif
iqentry_a2[n];
dram0_datacmp <= iqentry_a2[n];
`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};
else
dram0_addr <= iqentry_a1[n];
4981,30 → 5006,8
((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_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])
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
 
5042,6 → 5045,14
StatusEXL <= StatusEXL + 8'd1;
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(commit1_v,head1);
 
5460,6 → 5471,7
6'd3: dbg_adr3 <= commit_bus;
6'd4: dbg_ctrl <= commit_bus;
6'd5: dbg_stat <= commit_bus;
default: ;
endcase
6'b111111:
begin
5466,6 → 5478,7
ld_clk_throttle <= `TRUE;
clk_throttle_new <= commit_bus[15:0];
end
default: ;
endcase
end
end
5545,12 → 5558,15
endcase
default: fnSpr = 64'd0;
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 (commit0_v && commit0_tgt=={1'b1,regno})
fnSpr = commit0_bus;
if (commit1_v && commit1_tgt=={1'b1,regno})
fnSpr = commit1_bus;
fnSpr = commit1_bus;
// Special cases where the register would not be read from the commit bus
case(regno)
5577,11 → 5593,17
StatusHWI <= `FALSE;
im <= imb;
end
`RTE,`RTD:
`RTD:
begin
StatusDBG <= `FALSE;
if (StatusEXL!=8'h00)
StatusEXL <= StatusEXL - 8'd1;
end
`RTE:
begin
if (StatusEXL!=8'h00)
StatusEXL <= StatusEXL - 8'd1;
end
`CACHE:
begin
case(iqentry_fn[head])
5612,11 → 5634,19
input [2:0] inc;
input unlink;
begin
if (fetchbuf0_pc==32'h0)
$stop;
if (fetchbuf0_pc==32'hF44)
$stop;
if (fetchbuf0_pc==32'hFFFFda49)
$stop;
`ifdef SEGMENTATION
`ifdef SEGLIMITS
// 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)
set_exception(tail,8'd244);
`endif
`endif
// If targeting a kernel mode register and not in kernel mode.
// But okay if it is an SYS or INT instruction.
if (fnIsKMOnlyReg(Rt0) && !km && !(opcode0==`SYS || opcode0==`INT))
5663,7 → 5693,14
iqentry_agen [tail] <= `INV;
iqentry_pc [tail] <= (opcode0==`INT && Rt0[3:0]==4'hE) ? interrupt_pc : fetchbuf0_pc;
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_jmpi [tail] <= opcode0==`JMPI || opcode0==`JMPIX;
iqentry_fp [tail] <= fetchbuf0_fp;
iqentry_rfw [tail] <= fetchbuf0_rfw;
iqentry_tgt [tail] <= Rt0;
5675,15 → 5712,18
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) :
fnImm(fetchbuf0_instr);
iqentry_a1 [tail] <= fnOpa(opcode0,fetchbuf0_instr,rfoa0,fetchbuf0_pc);
iqentry_a2 [tail] <= fnIsShiftiop(fetchbuf0_instr) ? {{DBW-6{1'b0}},fetchbuf0_instr[`INSTRUCTION_RB]} :
fnIsFPCtrl(fetchbuf0_instr) ? {{DBW-6{1'b0}},fetchbuf0_instr[`INSTRUCTION_RB]} :
opcode0==`INC ? {{56{fetchbuf0_instr[47]}},fetchbuf0_instr[47:40]} :
opcode0==`STI ? fetchbuf0_instr[27:22] :
Rb0[6] ? fnSpr(Rb0[5:0],fetchbuf0_pc) :
rfob0;
// These register recordings for simulation debug. They should be stripped
// out of synthesis because they don't drive any signals.
`ifdef SIMULATION
iqentry_r1 [tail] <= Ra0;
iqentry_r2 [tail] <= Rb0;
iqentry_r3 [tail] <= Rc0;
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_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).
// 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}];
5724,7 → 5764,14
iqentry_agen [tail] <= `INV;
iqentry_pc [tail] <= which ? fetchbuf1_pc : fetchbuf0_pc;
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_jmpi [tail] <= 1'b0;
iqentry_fp [tail] <= 1'b0;
iqentry_rfw [tail] <= 1'b1;
iqentry_tgt [tail] <= 7'd27;
5764,13 → 5811,25
input test_stomp;
input validate_args;
begin
if (opcode0==`NOP)
queued1 = `TRUE; // to update fetch buffers
if (`FALSE)
;
// 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
// A pop instruction takes 2 queue entries.
else if (fnIsPop(fetchbuf0_instr)|fnIsPush(fetchbuf0_instr)|opcode0==`LINK) begin
$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");
enque0a(tail,3'd2,1'b0);
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf0_instr),opcode0==`LINK,0,0);
5777,6 → 5836,7
allowq = `FALSE;
end
end
`ifdef UNLINKOP
else if (opcode0==`UNLINK) begin
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
enquePushpopAdd(tail,1'b0,1'b0,1'b1,0);
5785,6 → 5845,7
end
end
`endif
`endif
else if (iqentry_v[tail] == `INV) begin
if ((({fnIsBranch(opcode0), predict_taken0} == {`TRUE, `TRUE})||(opcode0==`LOOP)) && test_stomp)
qstomp = `TRUE;
5799,10 → 5860,18
input validate_args;
input unlink;
begin
if (fetchbuf1_pc==32'h0)
$stop;
if (fetchbuf1_pc==32'hF44)
$stop;
if (fetchbuf1_pc==32'hFFFFDA49)
$stop;
`ifdef SEGMENTATION
`ifdef SEGLIMITS
if (fetchbuf1_pc >= {sregs_lmt[7],12'h000} && fetchbuf1_pc[ABW-1:ABW-4]!=4'hF)
set_exception(tail,8'd244);
`endif
`endif
if (fnIsKMOnlyReg(Rt1) && !km && !(opcode1==`SYS || opcode1==`INT))
set_exception(tail,8'd245);
`ifdef TRAP_ILLEGALOPS
5851,7 → 5920,14
iqentry_pc [tail] <= (opcode1==`INT && Rt1[3:0]==4'hE) ? interrupt_pc : fetchbuf1_pc;
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_jmpi [tail] <= opcode1==`JMPI || opcode1==`JMPIX;
iqentry_fp [tail] <= fetchbuf1_fp;
iqentry_rfw [tail] <= fetchbuf1_rfw;
iqentry_tgt [tail] <= Rt1;
5865,15 → 5941,16
(!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) :
fnImm(fetchbuf1_instr);
iqentry_a1 [tail] <= fnOpa(opcode1,fetchbuf1_instr,rfoa1,fetchbuf1_pc);
iqentry_a2 [tail] <= fnIsShiftiop(fetchbuf1_instr) ? {{DBW-6{1'b0}},fetchbuf1_instr[`INSTRUCTION_RB]} :
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_a1 [tail] <= fnOpa(opcode1,Ra1,fetchbuf1_instr,rfoa1,fetchbuf1_pc);
iqentry_a2 [tail] <= fnOpb(opcode1,Rb1,fetchbuf1_instr,rfob1,fetchbuf1_pc);
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
// queueing two entries the source settings may be overridden in the argument valudation.
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn1}];
5898,10 → 5975,22
input test_stomp;
input validate_args;
begin
if (opcode1==`NOP) begin
if (queued1==`TRUE) queued2 = `TRUE;
queued1 = `TRUE;
if (`FALSE)
;
// 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
`endif
`ifdef STACKOPS
else if (fnIsPop(fetchbuf1_instr)|fnIsPush(fetchbuf1_instr)|opcode1==`LINK) begin
$display("1 found push/pop");
5916,6 → 6005,7
allowq = `FALSE;
end
end
`ifdef UNLINKOP
else if (opcode1==`UNLINK) begin
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
enquePushpopAdd(tail,1'b0,1'b0,1'b1,1);
5924,6 → 6014,7
end
end
`endif
`endif
else if (iqentry_v[tail] == `INV && !qstomp) begin
if ((({fnIsBranch(opcode1), predict_taken1} == {`TRUE, `TRUE})||(opcode1==`LOOP)) && test_stomp)
qstomp = `TRUE;
/trunk/rtl/verilog/Thor_TLB.v
158,6 → 158,7
`TLBIMissAdr: imiss_addr <= dati;
`TLBPageTblAddr: PageTblAddr <= dati;
`TLBPageTblCtrl: PageTblCtrl <= dati;
default: ;
endcase
end
`TLB_EN:
166,6 → 167,7
TLBenabled <= 1'b0;
`TLB_INVALL:
TLBValid <= 64'd0;
default: ;
endcase
end
else if (state==3'd2) begin
268,7 → 270,7
end
 
wire [DBW-1:0] eas = ea[DBW-1:12] >> {PageSize,1'b0};
always @(ea)
always @(eas or ASID or q or TLBG or TLBValid)
for (n = 0; n < 8; n = n + 1)
DMatch[n[2:0]] = (eas[DBW-1:3]==TLBVirtPage[{n,eas[2:0]}]) &&
((TLBASID[{n,eas[2:0]}]==ASID) || TLBG[{n,eas[2:0]}]) &&
/trunk/rtl/verilog/Thor_alu.v
380,15 → 380,17
o1[3] = 1'b0;
o <= {16{o1}};
end
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`SB,`SC,`SH,`SW,`CAS,`LVB,`LVC,`LVH,`LVH,`STI,
`LWS,`SWS,`LEA,`RTS2,`STS,`STFND,`STCMP:
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`SB,`SC,`SH,`SW,`CAS,`LVB,`LVC,`LVH,`LVW,`STI,
`LWS,`SWS,`RTS2,`STS,`STFND,`STCMP,`PUSH:
begin
o <= alu_argA + alu_argC + alu_argI;
end
`JMPI: o <= {alu_argA << alu_fn[1:0]} + alu_argC + alu_argI;
`LBX,`LBUX,`SBX,
`LCX,`LCUX,`SCX,
`LHX,`LHUX,`SHX,
`LWX,`SWX:
`LWX,`SWX,
`JMPIX:
case(alu_fn[1:0])
2'd0: o <= alu_argA + alu_argC + alu_argB;
2'd1: o <= alu_argA + alu_argC + {alu_argB,1'b0};
396,7 → 398,7
2'd3: o <= alu_argA + alu_argC + {alu_argB,3'b0};
endcase
`ifdef STACKOPS
`PUSH,`PEA,`LINK: o <= alu_argA + alu_argC - 64'd8;
`PEA,`LINK: o <= alu_argA + alu_argC - 64'd8;
`UNLINK: o <= alu_argA + alu_argC + 64'd8;
`POP: o <= alu_argA + alu_argC;
`endif
423,7 → 425,7
`ifdef BITFIELDOPS
`BITFIELD: o <= BIG ? bf_out : 64'hDEADDEADDEADDEAD;
`endif
`LOOP: o <= alu_argB > 0 ? alu_argB - 64'd1 : alu_argB;
`LOOP: o <= alu_argA > 0 ? alu_argA - 64'd1 : alu_argA;
default: o <= 64'hDEADDEADDEADDEAD;
endcase
end
/trunk/rtl/verilog/Thor_execute_combo.v
136,6 → 136,14
default:
alu1_misspc <= (alu1_bt ? alu1_pc + alu1_insnsz : alu1_pc + alu1_insnsz + alu1_argI);
endcase
always @(dram0_fn or dram0_misspc or dram_bus)
case (dram0_fn[1:0])
2'd1: jmpi_misspc <= {dram0_misspc[DBW-1:16],dram_bus[15:0]};
2'd2: jmpi_misspc <= (DBW==32) ? dram_bus[31:0] : {dram0_misspc[63:32],dram_bus[31:0]};
2'd3: jmpi_misspc <= dram_bus[DBW-1:0];
default: jmpi_misspc <= 32'h00000FA0; // unimplemented instruction vector
endcase
/*
assign alu0_misspc = (alu0_op == `JSR || alu0_op==`JSRS || alu0_op==`JSRZ ||
alu0_op==`RTS || alu0_op==`RTS2 || alu0_op == `RTE || alu0_op==`RTI || alu0_op==`LOOP) ? alu0_argA + alu0_argI :
178,17 → 186,17
((fnIsBranch(alu0_op)) ? ((alu0_cmt && !alu0_bt) || (!alu0_cmt && alu0_bt))
: (alu0_cmtw && (alu0_op==`SYNC || alu0_op == `JSR || alu0_op == `JSRS || alu0_op == `JSRZ ||
alu0_op==`SYS || alu0_op==`INT ||
alu0_op==`RTS || alu0_op==`RTS2 || alu0_op==`RTD || alu0_op == `RTE || alu0_op==`RTI || ((alu0_op==`LOOP) && (alu0_argB == 64'd0)))));
alu0_op==`RTS || alu0_op==`RTS2 || alu0_op==`RTD || alu0_op == `RTE || alu0_op==`RTI || ((alu0_op==`LOOP) && (alu0_argA == 64'd0)))));
 
assign alu1_branchmiss = alu1_dataready &&
((fnIsBranch(alu1_op)) ? ((alu1_cmt && !alu1_bt) || (!alu1_cmt && alu1_bt))
: (alu1_cmtw && (alu1_op==`SYNC || alu1_op == `JSR || alu1_op == `JSRS || alu1_op == `JSRZ ||
alu1_op==`SYS || alu1_op==`INT ||
alu1_op==`RTS || alu1_op==`RTS2 || alu1_op==`RTD || alu1_op == `RTE || alu1_op==`RTI || ((alu1_op==`LOOP) && (alu1_argB == 64'd0)))));
alu1_op==`RTS || alu1_op==`RTS2 || alu1_op==`RTD || alu1_op == `RTE || alu1_op==`RTI || ((alu1_op==`LOOP) && (alu1_argA == 64'd0)))));
 
assign branchmiss = (alu0_branchmiss | alu1_branchmiss | mem_stringmiss),
misspc = (mem_stringmiss ? dram0_misspc : alu0_branchmiss ? alu0_misspc : alu1_misspc),
missid = (mem_stringmiss ? dram0_id : alu0_branchmiss ? alu0_sourceid : alu1_sourceid);
assign branchmiss = (alu0_branchmiss | alu1_branchmiss | mem_stringmiss | jmpi_miss),
misspc = (jmpi_miss ? jmpi_misspc : mem_stringmiss ? dram0_misspc : alu0_branchmiss ? alu0_misspc : alu1_misspc),
missid = (jmpi_miss ? dram0_id : mem_stringmiss ? dram0_id : alu0_branchmiss ? alu0_sourceid : alu1_sourceid);
 
`ifdef FLOATING_POINT
wire fp0_exception;
/trunk/rtl/verilog/Thor_defines.v
28,13 → 28,15
 
`define SIMULATION 1'b1
`define SEGMENTATION 1'b1
//`define SEGLIMITS 1'b1
//`define STACKOPS 1'b1
//`define UNLINKOP 1'b1
//`define BITFIELDOPS 1'b1
//`define FLOATING_POINT 1'b1
`define STRINGOPS 1'b1
`define DEBUG_LOGIC 1'b1
//`define DEBUG_LOGIC 1'b1
//`define THREEWAY 1'b1
`define TRAP_ILLEGALOPS 1'b1
//`define TRAP_ILLEGALOPS 1'b1
 
`define TRUE 1'b1
`define FALSE 1'b0
173,7 → 175,7
`define LFD 8'h88
`define LVWAR 8'h8B
`define SWCR 8'h8C
`define LEA 8'h8D
`define JMPI 8'h8D
`define LWS 8'h8E
`define LCL 8'h8F
 
245,6 → 247,7
`define LHX 8'hB4
`define LHUX 8'hB5
`define LWX 8'hB6
`define JMPIX 8'hB7
 
`define SBX 8'hC0
`define SCX 8'hC1

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.