Line 104... |
Line 104... |
module Thor(corenum, rst_i, clk_i, clk_o, km, nmi_i, irq_i, vec_i, bte_o, cti_o, bl_o, lock_o, resv_o, resv_i, cres_o,
|
module Thor(corenum, rst_i, clk_i, clk_o, km, nmi_i, irq_i, vec_i, bte_o, cti_o, bl_o, lock_o, resv_o, resv_i, cres_o,
|
cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o);
|
cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o);
|
parameter DBW = 32; // databus width
|
parameter DBW = 32; // databus width
|
parameter ABW = 32; // address bus width
|
parameter ABW = 32; // address bus width
|
parameter RSTCSEG = 52'h0;
|
parameter RSTCSEG = 52'h0;
|
parameter RSTPC = 64'hFFFFFFFFFFFFEFF0;
|
parameter RSTPC = 64'hFFFFFFFFFFFC0000;
|
parameter STARTUP_POWER = 16'hFFFF;
|
parameter STARTUP_POWER = 16'hFFFF;
|
parameter IMCD = 6'h3E;
|
parameter IMCD = 6'h30;
|
localparam AMSB = ABW-1;
|
localparam AMSB = ABW-1;
|
parameter QENTRIES = 8;
|
parameter QENTRIES = 8;
|
parameter ALU1BIG = 0;
|
parameter ALU1BIG = 0;
|
parameter RESET1 = 4'd0;
|
parameter RESET1 = 4'd0;
|
parameter RESET2 = 4'd1;
|
parameter RESET2 = 4'd1;
|
Line 1049... |
Line 1049... |
8'h0B: fnFunc = isn[23:22];
|
8'h0B: fnFunc = isn[23:22];
|
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[39:37],isn[24:22]};
|
`TLB: fnFunc = isn[19:16];
|
`TLB: fnFunc = isn[19:16];
|
`RTS: fnFunc = isn[19:16]; // used to pass a small immediate
|
`RTS: 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
|
`PUSH,`PEA: fnFunc = km ? 6'b0 : 6'b110000; // select segment register #6
|
`JMPI: fnFunc = {isn[39:37],1'b0,isn[27:26]};
|
`JMPI: fnFunc = {isn[39:37],1'b0,isn[27:26]};
|
Line 1227... |
Line 1227... |
`SHIFT:
|
`SHIFT:
|
if (func>=6'h10)
|
if (func>=6'h10)
|
fnSource2_v = `TRUE;
|
fnSource2_v = `TRUE;
|
else
|
else
|
fnSource2_v = `FALSE;
|
fnSource2_v = `FALSE;
|
`CACHE,`LCL,`TLB,`LLA,
|
`CACHE,`LCL,`TLB,`LLA,`LEA,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`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,`RTS2:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2:
|
fnSource2_v = 1'b1;
|
fnSource2_v = 1'b1;
|
Line 1300... |
Line 1300... |
`SHIFT:
|
`SHIFT:
|
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;
|
`CACHE,`LCL,`TLB,`LLA,
|
`CACHE,`LCL,`TLB,`LLA,`LEA,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LVB,`LVC,`LVH,`LVW,`LVWAR,`LWS,`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,`RTS2,`BR:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2,`BR:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
`SBX,`SCX,`SHX,`SWX,
|
`SBX,`SCX,`SHX,`SWX,
|
Line 1450... |
Line 1450... |
.d({fetchbuf1_pc,fetcbuf0_pc}),
|
.d({fetchbuf1_pc,fetcbuf0_pc}),
|
.q(pc_histo)
|
.q(pc_histo)
|
);
|
);
|
`endif
|
`endif
|
|
|
Thor_icachemem #(DBW) uicm1
|
Thor_icachemem #(.DBW(DBW),.ABW(ABW)) uicm1
|
(
|
(
|
.wclk(clk),
|
.wclk(clk),
|
.wce(cstate==ICACHE1),
|
.wce(cstate==ICACHE1),
|
.wr(ack_i|err_i),
|
.wr(ack_i|err_i),
|
.wa(adr_o),
|
.wa(adr_o),
|
Line 1600... |
Line 1600... |
fnTargetReg = {1'b0,ir[33:28]};
|
fnTargetReg = {1'b0,ir[33:28]};
|
`R,`R2,`DOUBLE_R,`SINGLE_R,
|
`R,`R2,`DOUBLE_R,`SINGLE_R,
|
`ADDI,`ADDUI,`SUBI,`SUBUI,
|
`ADDI,`ADDUI,`SUBI,`SUBUI,
|
`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI,
|
`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`ANDI,`ORI,`EORI,`LLA,
|
`ANDI,`ORI,`EORI,`LLA,`LEA,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`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]};
|
Line 1949... |
Line 1949... |
begin
|
begin
|
fnIsRFW = // General registers
|
fnIsRFW = // General registers
|
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==`STP || opcode==`LLA || opcode==`LLAX ||
|
opcode==`STP || opcode==`LLA || opcode==`LLAX || opcode==`LEA ||
|
opcode==`CAS || opcode==`LWS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
|
opcode==`CAS || opcode==`LWS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
|
opcode==`STS || opcode==`PUSH || opcode==`POP || opcode==`LINK || opcode==`UNLINK ||
|
opcode==`STS || opcode==`PUSH || opcode==`POP || opcode==`LINK || opcode==`UNLINK ||
|
opcode==`JMPI || opcode==`JMPIX ||
|
opcode==`JMPI || opcode==`JMPIX ||
|
opcode==`ADDI || opcode==`SUBI || opcode==`ADDUI || opcode==`SUBUI ||
|
opcode==`ADDI || opcode==`SUBI || opcode==`ADDUI || opcode==`SUBUI ||
|
opcode==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI || opcode==`MODI || opcode==`MODUI ||
|
opcode==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI || opcode==`MODI || opcode==`MODUI ||
|
Line 2061... |
Line 2061... |
if (fn > 4'd2)
|
if (fn > 4'd2)
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
else
|
else
|
fnIsIllegal = `FALSE;
|
fnIsIllegal = `FALSE;
|
8'h43,8'h44,8'h45: fnIsIllegal = `TRUE;
|
8'h43,8'h44,8'h45: fnIsIllegal = `TRUE;
|
8'h52,8'h56,8'h57,8'h59,8'h5A,8'h5C,8'h5D,8'h5E:
|
8'h52,8'h56,8'h57,8'h59,8'h5A,8'h5D,8'h5E:
|
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'h60,8'h61,8'h62,8'h63,8'h64,8'h65,8'h66,8'h67,8'h68,8'h69:
|
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;
|
Line 2583... |
Line 2583... |
`RTS: fnImm = insn[19:16];
|
`RTS: fnImm = insn[19:16];
|
`RTD,`RTE,`RTI,`RTS2,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm = 64'h0;
|
`RTD,`RTE,`RTI,`RTS2,`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
|
`PUSH: fnImm = 64'hFFFFFFFFFFFFFFF8; //-8
|
//`LINK: fnImm = {insn[39:28],3'b000};
|
//`LINK: fnImm = {insn[39:28],3'b000};
|
`JMPI,`LLA,
|
`JMPI,`LLA,`LEA,
|
`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 2617... |
Line 2617... |
`STI: fnImm8 = insn[35:28];
|
`STI: fnImm8 = insn[35:28];
|
`PUSH: fnImm8 = 8'hF8;
|
`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,`LLA,
|
`JMPI,`LLA,`LEA,
|
`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 2653... |
Line 2653... |
fnImmMSB = 1'b0; // RTS is unsigned
|
fnImmMSB = 1'b0; // RTS is unsigned
|
`PUSH: fnImmMSB = 1'b1;
|
`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,`LLA,
|
`JMPI,`LLA,`LEA,
|
`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 4231... |
Line 4231... |
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 && dram0_op != `STMV) begin
|
if (dram0 == 2'd2 && fnIsStore(dram0_op) && dram0_op != `STS && dram0_op != `STMV && dram0_op != `SWCR) 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 && dram1_op != `STMV) begin
|
if (dram1 == 2'd2 && fnIsStore(dram1_op) && dram1_op != `STS && dram1_op != `STMV && dram1_op != `SWCR) 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 && dram2_op != `STMV) begin
|
if (dram2 == 2'd2 && fnIsStore(dram2_op) && dram2_op != `STS && dram2_op != `STMV && dram2_op != `SWCR) 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 5693... |
Line 5693... |
begin
|
begin
|
if (fetchbuf0_pc==32'h0)
|
if (fetchbuf0_pc==32'h0)
|
$stop;
|
$stop;
|
if (fetchbuf0_pc==32'hF44)
|
if (fetchbuf0_pc==32'hF44)
|
$stop;
|
$stop;
|
if (fetchbuf0_pc==32'hFFFFD09B)
|
if (fetchbuf0_pc==32'hFFFC2F71)
|
$stop;
|
$stop;
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
`ifdef SEGLIMITS
|
`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[3'd7],12'h000} && fetchbuf0_pc[ABW-1:ABW-4]!=4'hF)
|
if (fetchbuf0_pc >= {sregs_lmt[3'd7],12'h000} && fetchbuf0_pc[ABW-1:ABW-4]!=4'hF)
|
Line 5876... |
Line 5876... |
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 (`FALSE)
|
if (opcode0==`NOP)
|
;
|
queued1 = `TRUE; // to update fetch buffers
|
// if (opcode0==`NOP)
|
|
// queued1 = `TRUE; // to update fetch buffers
|
|
`ifdef DEBUG_LOGIC
|
`ifdef DEBUG_LOGIC
|
else
|
else
|
if (dbg_ctrl[7] && !StatusDBG) begin
|
if (dbg_ctrl[7] && !StatusDBG) 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
|
enque0a(tail,3'd2,1'b0);
|
enque0a(tail,3'd2,1'b0);
|
Line 5929... |
Line 5927... |
begin
|
begin
|
if (fetchbuf1_pc==32'h0)
|
if (fetchbuf1_pc==32'h0)
|
$stop;
|
$stop;
|
if (fetchbuf1_pc==32'hF44)
|
if (fetchbuf1_pc==32'hF44)
|
$stop;
|
$stop;
|
if (fetchbuf1_pc==32'hFFFFD09B)
|
if (fetchbuf1_pc==32'hFFFC2F71)
|
$stop;
|
$stop;
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
`ifdef SEGLIMITS
|
`ifdef SEGLIMITS
|
if (fetchbuf1_pc >= {sregs_lmt[3'd7],12'h000} && fetchbuf1_pc[ABW-1:ABW-4]!=4'hF)
|
if (fetchbuf1_pc >= {sregs_lmt[3'd7],12'h000} && fetchbuf1_pc[ABW-1:ABW-4]!=4'hF)
|
set_exception(tail,8'd244);
|
set_exception(tail,8'd244);
|
Line 6045... |
Line 6043... |
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 (`FALSE)
|
if (opcode1==`NOP) begin
|
;
|
if (queued1==`TRUE) queued2 = `TRUE;
|
// if (opcode1==`NOP) begin
|
queued1 = `TRUE;
|
// if (queued1==`TRUE) queued2 = `TRUE;
|
end
|
// queued1 = `TRUE;
|
|
// end
|
|
`ifdef DEBUG_LOGIC
|
`ifdef DEBUG_LOGIC
|
else
|
else
|
if (dbg_ctrl[7] && !StatusDBG) begin
|
if (dbg_ctrl[7] && !StatusDBG) 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
|
enque1a(tail,3'd2,1,0);
|
enque1a(tail,3'd2,1,0);
|