Line 103... |
Line 103... |
|
|
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 RSTADDR = 64'hFFFFFFFFFFFFEFF0;
|
parameter RSTCSEG = 52'h0;
|
|
parameter RSTPC = 64'hFFFFFFFFFFFFEFF0;
|
parameter STARTUP_POWER = 16'hFFFF;
|
parameter STARTUP_POWER = 16'hFFFF;
|
|
parameter IMCD = 6'h3E;
|
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 159... |
Line 161... |
output reg [DBW-1:0] dat_o;
|
output reg [DBW-1:0] dat_o;
|
|
|
integer n,i;
|
integer n,i;
|
reg [DBW/8-1:0] rsel;
|
reg [DBW/8-1:0] rsel;
|
reg [3:0] cstate;
|
reg [3:0] cstate;
|
reg [ABW+3:0] pc; // program counter (virtual)
|
reg [ABW:0] pc; // program counter (virtual)
|
wire [DBW-1:0] ppc; // physical pc address
|
wire [ABW-1:0] ppc; // physical pc address
|
reg [ABW-1:0] interrupt_pc; // working register for interrupt pc
|
reg [ABW-1:0] interrupt_pc; // working register for interrupt pc
|
reg [DBW-1:0] vadr; // data virtual address
|
reg [DBW-1:0] vadr; // data virtual address
|
reg [3:0] panic; // indexes the message structure
|
reg [3:0] panic; // indexes the message structure
|
reg [128:0] message [0:15]; // indexed by panic
|
reg [128:0] message [0:15]; // indexed by panic
|
reg [DBW-1:0] cregs [0:15]; // code address registers
|
reg [DBW-1:0] cregs [0:15]; // code address registers
|
Line 194... |
Line 196... |
wire [127:0] insn;
|
wire [127:0] insn;
|
wire iuncached;
|
wire iuncached;
|
reg [NREGS:0] rf_v;
|
reg [NREGS:0] rf_v;
|
//reg [15:0] pf_v;
|
//reg [15:0] pf_v;
|
reg im,imb;
|
reg im,imb;
|
|
reg [5:0] imcd;
|
reg fxe;
|
reg fxe;
|
reg nmi1,nmi_edge;
|
reg nmi1,nmi_edge;
|
reg StatusHWI;
|
reg StatusHWI;
|
reg StatusDBG;
|
reg StatusDBG;
|
reg [7:0] StatusEXL;
|
reg [7:0] StatusEXL;
|
Line 208... |
Line 211... |
wire int_commit;
|
wire int_commit;
|
wire int_pending;
|
wire int_pending;
|
wire sys_commit;
|
wire sys_commit;
|
wire dbg_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]==1'b1) ? 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[3'd7],12'h000} + pc[ABW-1:0];
|
`else
|
`else
|
wire [DBW-1:0] spc = pc;
|
wire [DBW-1:0] spc = pc;
|
`endif
|
`endif
|
wire [DBW-1:0] ppcp16 = ppc + 64'd16;
|
wire [DBW-1:0] ppcp16 = ppc + 64'd16;
|
reg [DBW-1:0] string_pc;
|
reg [DBW-1:0] string_pc;
|
Line 234... |
Line 237... |
reg [7:0] iqentry_v; // entry valid? -- this should be the first bit
|
reg [7:0] iqentry_v; // entry valid? -- this should be the first bit
|
reg iqentry_out [0:7]; // instruction has been issued to an ALU ...
|
reg iqentry_out [0:7]; // instruction has been issued to an ALU ...
|
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_br [0:7]; // branch instruction decode
|
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_ndx [0:7]; // TRUE if indexed memory op
|
reg iqentry_cas [0:7];
|
reg iqentry_cas [0:7];
|
reg iqentry_pushpop [0:7];
|
reg iqentry_pushpop [0:7];
|
reg iqentry_pea [0:7];
|
reg iqentry_pea [0:7];
|
reg iqentry_cmpmv [0:7];
|
reg iqentry_cmpmv [0:7];
|
|
reg iqentry_lla [0:7]; // load linear address
|
reg iqentry_tlb [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_jmpi [0:7];
|
|
reg iqentry_sync [0:7]; // sync instruction
|
|
reg iqentry_memsb[0:7];
|
|
reg iqentry_memdb[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 419... |
Line 427... |
reg [DBW-1:0] alu0_bus;
|
reg [DBW-1:0] alu0_bus;
|
reg [3:0] alu0_id;
|
reg [3:0] alu0_id;
|
wire [3:0] alu0_exc;
|
wire [3:0] alu0_exc;
|
reg alu0_v;
|
reg alu0_v;
|
wire alu0_branchmiss;
|
wire alu0_branchmiss;
|
reg [ABW+3:0] alu0_misspc;
|
reg [ABW:0] alu0_misspc;
|
|
|
reg alu1_ld;
|
reg alu1_ld;
|
reg alu1_available;
|
reg alu1_available;
|
reg alu1_dataready;
|
reg alu1_dataready;
|
reg [3:0] alu1_sourceid;
|
reg [3:0] alu1_sourceid;
|
Line 443... |
Line 451... |
reg [DBW-1:0] alu1_bus;
|
reg [DBW-1:0] alu1_bus;
|
reg [3:0] alu1_id;
|
reg [3:0] alu1_id;
|
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:0] alu1_misspc;
|
|
|
wire jmpi_miss;
|
wire jmpi_miss;
|
reg [ABW-1:0] jmpi_misspc;
|
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:0] misspc;
|
|
|
`ifdef FLOATING_POINT
|
`ifdef FLOATING_POINT
|
reg fp0_ld;
|
reg fp0_ld;
|
reg fp0_available;
|
reg fp0_available;
|
reg fp0_dataready;
|
reg fp0_dataready;
|
Line 634... |
Line 642... |
wire dbg_stat0 = dbg_imatchA0 | dbg_imatchB0 | dbg_lmatch0 | dbg_smatch0;
|
wire dbg_stat0 = dbg_imatchA0 | dbg_imatchB0 | dbg_lmatch0 | dbg_smatch0;
|
wire dbg_stat1 = dbg_imatchA1 | dbg_imatchB1 | dbg_lmatch1 | dbg_smatch1;
|
wire dbg_stat1 = dbg_imatchA1 | dbg_imatchB1 | dbg_lmatch1 | dbg_smatch1;
|
wire dbg_stat2 = dbg_imatchA2 | dbg_imatchB2 | dbg_lmatch2 | dbg_smatch2;
|
wire dbg_stat2 = dbg_imatchA2 | dbg_imatchB2 | dbg_lmatch2 | dbg_smatch2;
|
wire dbg_stat3 = dbg_imatchA3 | dbg_imatchB3 | dbg_lmatch3 | dbg_smatch3;
|
wire dbg_stat3 = dbg_imatchA3 | dbg_imatchB3 | dbg_lmatch3 | dbg_smatch3;
|
assign dbg_stat1x = {dbg_stat3,dbg_stat2,dbg_stat1,dbg_stat0};
|
assign dbg_stat1x = {dbg_stat3,dbg_stat2,dbg_stat1,dbg_stat0};
|
|
wire debug_on = |dbg_ctrl[3:0]|dbg_ctrl[7];
|
|
|
reg [11:0] spr_bir;
|
reg [11:0] spr_bir;
|
|
|
//
|
//
|
// BRANCH-MISS LOGIC: livetarget
|
// BRANCH-MISS LOGIC: livetarget
|
Line 933... |
Line 941... |
wire [8:0] Rb1 = (fnNumReadPorts(fetchbuf1_instr) < 3'd2 && fetchbuf0_v) ? fnRa(fetchbuf1_instr):fnRb(fetchbuf1_instr);
|
wire [8:0] Rb1 = (fnNumReadPorts(fetchbuf1_instr) < 3'd2 && fetchbuf0_v) ? fnRa(fetchbuf1_instr):fnRb(fetchbuf1_instr);
|
*/
|
*/
|
function [7:0] fnOpcode;
|
function [7:0] fnOpcode;
|
input [63:0] ins;
|
input [63:0] ins;
|
fnOpcode = (ins[3:0]==4'h0 && ins[7:4] > 4'h1 && ins[7:4] < 4'h9) ? `IMM :
|
fnOpcode = (ins[3:0]==4'h0 && ins[7:4] > 4'h1 && ins[7:4] < 4'h9) ? `IMM :
|
ins[7:0]==8'h10 ? `NOP :
|
ins[7:0]==8'h10 ? `NOP : ins[15:8];
|
ins[7:0]==8'h11 ? `RTS : ins[15:8];
|
|
endfunction
|
endfunction
|
|
|
wire [7:0] opcode0 = fnOpcode(fetchbuf0_instr);
|
wire [7:0] opcode0 = fnOpcode(fetchbuf0_instr);
|
wire [7:0] opcode1 = fnOpcode(fetchbuf1_instr);
|
wire [7:0] opcode1 = fnOpcode(fetchbuf1_instr);
|
wire [3:0] cond0 = fetchbuf0_instr[3:0];
|
wire [3:0] cond0 = fetchbuf0_instr[3:0];
|
Line 948... |
Line 955... |
wire [3:0] Pn1 = fetchbuf1_instr[7:4];
|
wire [3:0] Pn1 = fetchbuf1_instr[7:4];
|
wire [3:0] Pt1 = fetchbuf1_instr[11:8];
|
wire [3:0] Pt1 = fetchbuf1_instr[11:8];
|
|
|
function [6:0] fnRa;
|
function [6:0] fnRa;
|
input [63:0] isn;
|
input [63:0] isn;
|
case(isn[7:0])
|
|
8'h11: fnRa = 7'h51; // RTS short form
|
|
default:
|
|
case(isn[15:8])
|
case(isn[15:8])
|
|
`RTS2: fnRa = 7'h51;
|
`RTI: fnRa = 7'h5E;
|
`RTI: fnRa = 7'h5E;
|
`RTD: fnRa = 7'h5B;
|
`RTD: fnRa = 7'h5B;
|
`RTE: fnRa = 7'h5D;
|
`RTE: fnRa = 7'h5D;
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS:
|
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'h73;
|
`LOOP: fnRa = 7'h73;
|
`PUSH: fnRa = km ? 7'd31 : 7'd27;
|
`PUSH: fnRa = km ? 7'd31 : 7'd27;
|
Line 967... |
Line 972... |
`PEA,`POP,`LINK: fnRa = km ? 7'd31 : 7'd27;
|
`PEA,`POP,`LINK: fnRa = km ? 7'd31 : 7'd27;
|
`endif
|
`endif
|
`MFSPR,`MOVS: fnRa = {1'b1,isn[`INSTRUCTION_RA]};
|
`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
|
|
endfunction
|
endfunction
|
|
|
function [6:0] fnRb;
|
function [6:0] fnRb;
|
input [63:0] isn;
|
input [63:0] isn;
|
if (isn[7:0]==8'h11) // RTS short form
|
|
fnRb = 7'h51;
|
|
else
|
|
case(isn[15:8])
|
case(isn[15:8])
|
`RTS2: fnRb = km ? 7'd31 : 7'd27;
|
|
// `LOOP: fnRb = 7'h73;
|
// `LOOP: fnRb = 7'h73;
|
// `RTS,`STP,`TLB,`POP: fnRb = 7'd0;
|
// `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]};
|
Line 998... |
Line 998... |
fnRc = {1'b0,isn[`INSTRUCTION_RC]};
|
fnRc = {1'b0,isn[`INSTRUCTION_RC]};
|
endfunction
|
endfunction
|
|
|
function [3:0] fnCar;
|
function [3:0] fnCar;
|
input [63:0] isn;
|
input [63:0] isn;
|
if (isn[7:0]==8'h11) // RTS short form
|
|
fnCar = 4'h1;
|
|
else
|
|
case(isn[15:8])
|
case(isn[15:8])
|
|
`RTS2: fnCar = 4'h1;
|
`RTI: fnCar = 4'hE;
|
`RTI: fnCar = 4'hE;
|
`RTD: fnCar = 4'hB;
|
`RTD: fnCar = 4'hB;
|
`RTE: fnCar = 4'hD;
|
`RTE: fnCar = 4'hD;
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS:
|
fnCar = {isn[23:20]};
|
fnCar = {isn[23:20]};
|
default: fnCar = 4'h0;
|
default: fnCar = 4'h0;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function [5:0] fnFunc;
|
function [5:0] fnFunc;
|
input [63:0] isn;
|
input [63:0] isn;
|
if (isn[7:0]==8'h11) // RTS short form
|
|
fnFunc = 6'h00; // func is used as a small immediate
|
|
else
|
|
case(isn[15:8])
|
case(isn[15:8])
|
`BITFIELD: fnFunc = isn[43:40];
|
`BITFIELD: fnFunc = isn[43:40];
|
`R: fnFunc = isn[31:28];
|
`R: fnFunc = isn[31:28];
|
`R2: fnFunc = isn[31:28];
|
`R2: fnFunc = isn[31:28];
|
`DOUBLE_R: fnFunc = isn[31:28];
|
`DOUBLE_R: fnFunc = isn[31:28];
|
Line 1056... |
Line 1051... |
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];
|
`TLB: fnFunc = isn[19:16];
|
`RTS,`RTS2: 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]};
|
`JMPIX: fnFunc = {isn[39:37],1'b0,isn[33:32]};
|
`JMPIX: fnFunc = {isn[39:37],1'b0,isn[33:32]};
|
default:
|
default:
|
Line 1080... |
Line 1075... |
default: fnIsAlu0Op = `FALSE;
|
default: fnIsAlu0Op = `FALSE;
|
endcase
|
endcase
|
`RR:
|
`RR:
|
case(func)
|
case(func)
|
`DIV,`DIVU: fnIsAlu0Op = `TRUE;
|
`DIV,`DIVU: fnIsAlu0Op = `TRUE;
|
|
`MOD,`MODU: fnIsAlu0Op = `TRUE;
|
`MIN,`MAX: fnIsAlu0Op = `TRUE;
|
`MIN,`MAX: fnIsAlu0Op = `TRUE;
|
default: fnIsAlu0Op = `FALSE;
|
default: fnIsAlu0Op = `FALSE;
|
endcase
|
endcase
|
`BCD: fnIsAlu0Op = `TRUE;
|
`BCD: fnIsAlu0Op = `TRUE;
|
`DIVI,`DIVUI: fnIsAlu0Op = `TRUE;
|
`DIVI,`DIVUI: fnIsAlu0Op = `TRUE;
|
|
`MODI,`MODUI: fnIsAlu0Op = `TRUE;
|
//`DOUBLE: fnIsAlu0Op = `TRUE;
|
//`DOUBLE: fnIsAlu0Op = `TRUE;
|
`SHIFT: fnIsAlu0Op = `TRUE;
|
`SHIFT: fnIsAlu0Op = `TRUE;
|
`BITFIELD: fnIsAlu0Op = `TRUE;
|
`BITFIELD: fnIsAlu0Op = `TRUE;
|
default: fnIsAlu0Op = `FALSE;
|
default: fnIsAlu0Op = `FALSE;
|
endcase
|
endcase
|
Line 1101... |
Line 1098... |
input [5:0] func;
|
input [5:0] func;
|
case(opcode)
|
case(opcode)
|
`R: fnAluValid = `TRUE;
|
`R: fnAluValid = `TRUE;
|
`RR:
|
`RR:
|
case(func)
|
case(func)
|
`MUL,`MULU,`DIV,`DIVU: fnAluValid = `FALSE;
|
`MUL,`MULU,`DIV,`DIVU,`MOD,`MODU: fnAluValid = `FALSE;
|
default: fnAluValid = `TRUE;
|
default: fnAluValid = `TRUE;
|
endcase
|
endcase
|
`MULI,`MULUI,`DIVI,`DIVUI: fnAluValid = `FALSE;
|
`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI: fnAluValid = `FALSE;
|
default: fnAluValid = `TRUE;
|
default: fnAluValid = `TRUE;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
Thor_regfile2w6r #(DBW) urf1
|
Thor_regfile2w6r #(DBW) urf1
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
.rclk(~clk),
|
.rclk(~clk),
|
.wr0(commit0_v && ~commit0_tgt[6] && iqentry_op[head0]!=`MTSPR),
|
.wr0(commit0_v && ~commit0_tgt[6]),
|
.wr1(commit1_v && ~commit1_tgt[6] && iqentry_op[head1]!=`MTSPR),
|
.wr1(commit1_v && ~commit1_tgt[6]),
|
.wa0(commit0_tgt[5:0]),
|
.wa0(commit0_tgt[5:0]),
|
.wa1(commit1_tgt[5:0]),
|
.wa1(commit1_tgt[5:0]),
|
.ra0(pRa0[5:0]),
|
.ra0(pRa0[5:0]),
|
.ra1(pRb0[5:0]),
|
.ra1(pRb0[5:0]),
|
.ra2(pRa1[5:0]),
|
.ra2(pRa1[5:0]),
|
Line 1220... |
Line 1217... |
8'h3B: fnSource2_v = 1'b1;
|
8'h3B: fnSource2_v = 1'b1;
|
8'h3C: fnSource2_v = 1'b1;
|
8'h3C: fnSource2_v = 1'b1;
|
8'h3D: fnSource2_v = 1'b1;
|
8'h3D: fnSource2_v = 1'b1;
|
8'h3E: fnSource2_v = 1'b1;
|
8'h3E: fnSource2_v = 1'b1;
|
8'h3F: fnSource2_v = 1'b1;
|
8'h3F: fnSource2_v = 1'b1;
|
`MULI,`MULUI,`DIVI,`DIVUI:
|
`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI:
|
fnSource2_v = 1'b1;
|
fnSource2_v = 1'b1;
|
`ANDI,`BITI: fnSource2_v = 1'b1;
|
`ANDI,`BITI: fnSource2_v = 1'b1;
|
`ORI: fnSource2_v = 1'b1;
|
`ORI: fnSource2_v = 1'b1;
|
`EORI: fnSource2_v = 1'b1;
|
`EORI: fnSource2_v = 1'b1;
|
`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,
|
`CACHE,`LCL,`TLB,`LLA,
|
`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:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2:
|
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)
|
Line 1294... |
Line 1291... |
`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;
|
`SUBI,`SUBUI: fnNumReadPorts = 3'd1;
|
`SUBI,`SUBUI: fnNumReadPorts = 3'd1;
|
`MULI,`MULUI,`DIVI,`DIVUI:
|
`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
`BITI,
|
`BITI,
|
`ANDI,`ORI,`EORI: fnNumReadPorts = 3'd1;
|
`ANDI,`ORI,`EORI: fnNumReadPorts = 3'd1;
|
`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;
|
`RTS2,`CACHE,`LCL,`TLB,
|
`CACHE,`LCL,`TLB,`LLA,
|
`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,`BR:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS,`RTS2,`BR:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
`SBX,`SCX,`SHX,`SWX,
|
`SBX,`SCX,`SHX,`SWX,
|
`MUX,`CAS,`STMV,`STCMP:
|
`MUX,`CAS,`STMV,`STCMP:
|
fnNumReadPorts = 3'd3;
|
fnNumReadPorts = 3'd3;
|
`MTSPR,`MFSPR,`POP,`UNLINK: fnNumReadPorts = 3'd1;
|
`MTSPR,`MFSPR,`POP,`UNLINK: fnNumReadPorts = 3'd1;
|
Line 1355... |
Line 1352... |
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsStoreString =
|
fnIsStoreString =
|
opcode==`STS;
|
opcode==`STS;
|
endfunction
|
endfunction
|
|
|
wire xbr = (iqentry_op[head0][7:4]==`BR) || (iqentry_op[head1][7:4]==`BR);
|
reg [DBW-1:0] branch_pc;
|
wire takb = (iqentry_op[head0][7:4]==`BR) ? commit0_v : commit1_v;
|
wire xbr = iqentry_br[head0] | iqentry_br[head1];
|
wire [DBW-1:0] xbrpc = (iqentry_op[head0][7:4]==`BR) ? iqentry_pc[head0] : iqentry_pc[head1];
|
wire takb = iqentry_br[head0] ? commit0_v : commit1_v;
|
|
wire [DBW-1:0] xbrpc = iqentry_br[head0] ? iqentry_pc[head0] : iqentry_pc[head1];
|
wire predict_takenA,predict_takenB,predict_takenC,predict_takenD;
|
|
|
wire predict_taken0;
|
// There are really only two branch tables required one for fetchbuf0 and one
|
wire predict_taken1;
|
// for fetchbuf1. Synthesis removes the extra tables.
|
|
|
// This is really just a single history table with three read ports.
|
|
// One for fetchbuf0, one for fetchbuf1 and one for the branch_pc.
|
|
// Ideally, there really needs to be two write ports as well (for
|
|
// head0 and head1).
|
|
// There is only a single write port for branches committing at
|
|
// head0 or head1. If there are two branches one after the other
|
|
// in code, then the prediction will be off because the taken/
|
|
// not taken status for the second branch won't be updated. It
|
|
// doesn't happen that often that branches are piled together and
|
|
// executing during the same clock cycle.
|
|
// There's usually at least an intervening compare operation.
|
|
// Needs more work yet.
|
|
//
|
|
// ToDo: add return address stack predictor.
|
//
|
//
|
Thor_BranchHistory #(DBW) ubhtA
|
Thor_BranchHistory #(DBW) ubhtA
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk),
|
.clk(clk),
|
.advanceX(xbr),
|
.advanceX(xbr),
|
.xisBranch(xbr),
|
.xisBranch(xbr),
|
.pc(pc),
|
.pc(branch_pc),
|
.xpc(xbrpc),
|
.xpc(xbrpc),
|
.takb(takb),
|
.takb(takb),
|
.predict_taken(predict_takenA)
|
.predict_taken(predict_takenBr)
|
);
|
);
|
|
|
Thor_BranchHistory #(DBW) ubhtB
|
Thor_BranchHistory #(DBW) ubhtB
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk),
|
.clk(clk),
|
.advanceX(xbr),
|
.advanceX(xbr),
|
.xisBranch(xbr),
|
.xisBranch(xbr),
|
.pc(pc+fnInsnLength(insn)),
|
.pc(fetchbuf0_pc),
|
.xpc(xbrpc),
|
.xpc(xbrpc),
|
.takb(takb),
|
.takb(takb),
|
.predict_taken(predict_takenB)
|
.predict_taken(predict_taken0)
|
);
|
);
|
|
|
Thor_BranchHistory #(DBW) ubhtC
|
Thor_BranchHistory #(DBW) ubhtC
|
(
|
(
|
.rst(rst_i),
|
.rst(rst_i),
|
.clk(clk),
|
.clk(clk),
|
.advanceX(xbr),
|
.advanceX(xbr),
|
.xisBranch(xbr),
|
.xisBranch(xbr),
|
.pc(pc),
|
.pc(fetchbuf1_pc),
|
.xpc(xbrpc),
|
.xpc(xbrpc),
|
.takb(takb),
|
.takb(takb),
|
.predict_taken(predict_takenC)
|
.predict_taken(predict_taken1)
|
);
|
);
|
|
|
Thor_BranchHistory #(DBW) ubhtD
|
/*
|
|
Thor_BranchHistory #(DBW) ubhtC
|
|
(
|
|
.rst(rst_i),
|
|
.clk(clk),
|
|
.advanceX(xbr),
|
|
.xisBranch(xbr),
|
|
.pc(pc),
|
|
.xpc(xbrpc),
|
|
.takb(takb),
|
|
.predict_taken(predict_takenC)
|
|
);
|
|
|
|
Thor_BranchHistory #(DBW) ubhtD
|
|
(
|
|
.rst(rst_i),
|
|
.clk(clk),
|
|
.advanceX(xbr),
|
|
.xisBranch(xbr),
|
|
.pc(pc+fnInsnLength(insn)),
|
|
.xpc(xbrpc),
|
|
.takb(takb),
|
|
.predict_taken(predict_takenD)
|
|
);
|
|
*/
|
|
`ifdef PCHIST
|
|
wire [63:0] pc_histo;
|
|
reg pc_cap;
|
|
reg [5:0] pc_ndx;
|
|
vtdl #(.WID(64),.DEP(64)) uvtl1
|
(
|
(
|
.rst(rst_i),
|
|
.clk(clk),
|
.clk(clk),
|
.advanceX(xbr),
|
.ce(pc_cap),
|
.xisBranch(xbr),
|
.a(pc_ndx),
|
.pc(pc+fnInsnLength(insn)),
|
.d({fetchbuf1_pc,fetcbuf0_pc}),
|
.xpc(xbrpc),
|
.q(pc_histo)
|
.takb(takb),
|
|
.predict_taken(predict_takenD)
|
|
);
|
);
|
|
`endif
|
|
|
Thor_icachemem #(DBW) uicm1
|
Thor_icachemem #(DBW) uicm1
|
(
|
(
|
.wclk(clk),
|
.wclk(clk),
|
.wce(cstate==ICACHE1),
|
.wce(cstate==ICACHE1),
|
Line 1559... |
Line 1597... |
`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,`R2,`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,`MODI,`MODUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`ANDI,`ORI,`EORI,
|
`ANDI,`ORI,`EORI,`LLA,
|
`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 1615... |
Line 1654... |
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,`PUSH: fnTargetReg = km ? 7'd31 : 7'd27;
|
`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 1693... |
Line 1732... |
function fnHasConst;
|
function fnHasConst;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
case(opcode)
|
case(opcode)
|
`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,`MODI,`MODUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
// CMPI
|
// CMPI
|
8'h20,8'h21,8'h22,8'h23,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h28,8'h29,8'h2A,8'h2B,
|
Line 1710... |
Line 1749... |
`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,`INC,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWS,`INC,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,`STI,`JMPI,
|
`LVB,`LVC,`LVH,`LVW,`LVWAR,`STI,`JMPI,
|
`SB,`SC,`SH,`SW,`SWCR,`CAS,`SWS,
|
`SB,`SC,`SH,`SW,`SWCR,`CAS,`SWS,
|
`RTI,`RTD,`RTE,
|
`RTI,`RTD,`RTE,`LLA,
|
`JSR,`JSRS,`SYS,`INT,`RTS2,`LOOP,`PEA,`LINK,`UNLINK:
|
`JSR,`JSRS,`SYS,`INT,`LOOP,`PEA,`LINK,`UNLINK:
|
fnHasConst = 1'b1;
|
fnHasConst = 1'b1;
|
default:
|
default:
|
fnHasConst = 1'b0;
|
fnHasConst = 1'b0;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
Line 1736... |
Line 1775... |
endcase
|
endcase
|
end
|
end
|
endfunction
|
endfunction
|
|
|
// fnCanException
|
// fnCanException
|
|
//
|
// Used by memory 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.
|
|
// In debug mode any instruction could potentially cause a breakpoint exception.
|
|
// Rather than check all the addresses for potential debug exceptions it's
|
|
// simpler to just have it so that all instructions could exception. This will
|
|
// slow processing down somewhat as stores will only be done at the head of the
|
|
// instruction queue, but it's debug mode so we probably don't care.
|
//
|
//
|
function fnCanException;
|
function fnCanException;
|
input [7:0] op;
|
input [7:0] op;
|
input [5:0] func;
|
input [5:0] func;
|
|
if (debug_on)
|
|
fnCanException = `TRUE;
|
|
else
|
case(op)
|
case(op)
|
`FLOAT:
|
`FLOAT:
|
case(func)
|
case(func)
|
`FDIVS,`FMULS,`FADDS,`FSUBS,
|
`FDIVS,`FMULS,`FADDS,`FSUBS,
|
`FDIV,`FMUL,`FADD,`FSUB:
|
`FDIV,`FMUL,`FADD,`FSUB:
|
Line 1753... |
Line 1801... |
default: fnCanException = `FALSE;
|
default: fnCanException = `FALSE;
|
endcase
|
endcase
|
`SINGLE_R:
|
`SINGLE_R:
|
if (func==`FTX) fnCanException = `TRUE;
|
if (func==`FTX) fnCanException = `TRUE;
|
else fnCanException = `FALSE;
|
else fnCanException = `FALSE;
|
`ADD,`ADDI,`SUB,`SUBI,`DIV,`DIVI,`MUL,`MULI:
|
`ADDI,`SUBI,`DIVI,`MODI,`MULI:
|
fnCanException = `TRUE;
|
fnCanException = `TRUE;
|
|
`RR:
|
|
if (func==`ADD || func==`SUB || func==`MUL || func==`DIV || func==`MOD)
|
|
fnCanException = `TRUE;
|
|
else
|
|
fnCanException = `FALSE;
|
`TLB,`RTI,`RTD,`RTE,`CLI,`SEI:
|
`TLB,`RTI,`RTD,`RTE,`CLI,`SEI:
|
fnCanException = `TRUE;
|
fnCanException = `TRUE;
|
default:
|
default:
|
fnCanException = fnIsMem(op);
|
fnCanException = fnIsMem(op);
|
endcase
|
endcase
|
Line 1778... |
Line 1831... |
8'b01000000: fnInsnLength = 4'd4;
|
8'b01000000: fnInsnLength = 4'd4;
|
8'b01010000: fnInsnLength = 4'd5;
|
8'b01010000: fnInsnLength = 4'd5;
|
8'b01100000: fnInsnLength = 4'd6;
|
8'b01100000: fnInsnLength = 4'd6;
|
8'b01110000: fnInsnLength = 4'd7;
|
8'b01110000: fnInsnLength = 4'd7;
|
8'b10000000: fnInsnLength = 4'd8;
|
8'b10000000: fnInsnLength = 4'd8;
|
8'b00010001: fnInsnLength = 4'd1; // RTS short form
|
|
default:
|
default:
|
case(isn[15:8])
|
case(isn[15:8])
|
`NOP,`SEI,`CLI,`RTI,`RTD,`RTE,`MEMSB,`MEMDB,`SYNC:
|
`NOP,`SEI,`CLI,`RTI,`RTD,`RTE,`RTS2,`MEMSB,`MEMDB,`SYNC:
|
fnInsnLength = 4'd2;
|
fnInsnLength = 4'd2;
|
`JSRZ,`RTS,`CACHE,`LOOP,`PUSH,`POP,`UNLINK:
|
`JSRZ,`RTS,`CACHE,`LOOP,`PUSH,`POP,`UNLINK:
|
fnInsnLength = 4'd3;
|
fnInsnLength = 4'd3;
|
`SYS,`MTSPR,`MFSPR,`LDI,`LDIS,`ADDUIS,`R,`TLB,`MOVS,`RTS2,`STP:
|
`SYS,`MTSPR,`MFSPR,`LDI,`LDIS,`ADDUIS,`R,`TLB,`MOVS,`STP:
|
fnInsnLength = 4'd4;
|
fnInsnLength = 4'd4;
|
`BITFIELD,`JSR,`MUX,`BCD,`INC:
|
`BITFIELD,`JSR,`MUX,`BCD,`INC:
|
fnInsnLength = 4'd6;
|
fnInsnLength = 4'd6;
|
`CAS:
|
`CAS:
|
fnInsnLength = 4'd6;
|
fnInsnLength = 4'd6;
|
Line 1867... |
Line 1919... |
fetchbuf1_pc <= string_pc;
|
fetchbuf1_pc <= string_pc;
|
else
|
else
|
fetchbuf1_pc <= (fetchbuf == 1'b0) ? fetchbufB_pc : fetchbufD_pc ;
|
fetchbuf1_pc <= (fetchbuf == 1'b0) ? fetchbufB_pc : fetchbufD_pc ;
|
end
|
end
|
|
|
wire [7:0] opcodeA = fetchbufA_instr[`OPCODE];
|
wire [7:0] opcodeA = fnOpcode(fetchbufA_instr);
|
wire [7:0] opcodeB = fetchbufB_instr[`OPCODE];
|
wire [7:0] opcodeB = fnOpcode(fetchbufB_instr);
|
wire [7:0] opcodeC = fetchbufC_instr[`OPCODE];
|
wire [7:0] opcodeC = fnOpcode(fetchbufC_instr);
|
wire [7:0] opcodeD = fetchbufD_instr[`OPCODE];
|
wire [7:0] opcodeD = fnOpcode(fetchbufD_instr);
|
|
|
function fnIsMem;
|
function fnIsMem;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsMem = opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
|
fnIsMem = opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
|
opcode==`LBX || opcode==`LWX || opcode==`LBUX || opcode==`LHX || opcode==`LHUX || opcode==`LCX || opcode==`LCUX ||
|
opcode==`LBX || opcode==`LWX || opcode==`LBUX || opcode==`LHX || opcode==`LHUX || opcode==`LCX || opcode==`LCUX ||
|
Line 1888... |
Line 1940... |
opcode==`JMPI || opcode==`JMPIX ||
|
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;
|
|
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==`JMPIX
|
|
;
|
|
endfunction
|
|
|
|
// Determines which instruction write to the register file
|
// Determines which instruction write to the register file
|
function fnIsRFW;
|
function fnIsRFW;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
input [63:0] ir;
|
input [63:0] ir;
|
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==`RTS2 || opcode==`STP ||
|
opcode==`STP || opcode==`LLA || opcode==`LLAX ||
|
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==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI ||
|
opcode==`ADDI || opcode==`SUBI || opcode==`ADDUI || opcode==`SUBUI ||
|
|
opcode==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI || opcode==`MODI || opcode==`MODUI ||
|
opcode==`_2ADDUI || opcode==`_4ADDUI || opcode==`_8ADDUI || opcode==`_16ADDUI ||
|
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==`SHIFT || opcode==`LOGIC ||
|
opcode==`AND || opcode==`OR || opcode==`EOR || opcode==`NAND || opcode==`NOR || opcode==`ENOR || opcode==`ANDC || opcode==`ORC ||
|
opcode==`R || opcode==`R2 || opcode==`RR || opcode==`P || opcode==`LOOP ||
|
opcode==`SHIFT ||
|
|
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 ||
|
|
`ifdef FLOATING_POINT
|
|
opcode==`DOUBLE_R || opcode==`FLOAT_RR || opcode==`SINGLE_R ||
|
|
`endif
|
// 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 ||
|
// predicate registers
|
// predicate registers
|
(opcode[7:4] < 4'h3) ||
|
(opcode[7:4] < 4'h3) ||
|
Line 1970... |
Line 2016... |
function fnIsIllegal;
|
function fnIsIllegal;
|
input [7:0] op;
|
input [7:0] op;
|
input [5:0] fn;
|
input [5:0] fn;
|
casex(op)
|
casex(op)
|
8'h40:
|
8'h40:
|
if (fn > 6'h11)
|
if (fn > 6'h17)
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
else if (fn==6'hC || fn==6'hD || fn==6'hE || fn==6'hF)
|
else if (fn==6'hC || fn==6'hD || fn==6'hE || fn==6'hF || fn==6'h12 || fn==6'h14 || fn==6'h15 || fn==6'h16)
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
else fnIsIllegal = `FALSE;
|
else fnIsIllegal = `FALSE;
|
8'h41:
|
8'h41:
|
if (fn > 6'd3) fnIsIllegal = `TRUE;
|
if (fn > 6'd3) fnIsIllegal = `TRUE;
|
else fnIsIllegal = `FALSE;
|
else fnIsIllegal = `FALSE;
|
Line 2015... |
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'h5B,8'h5C,8'h5D,8'h5E,8'h5F:
|
8'h52,8'h56,8'h57,8'h59,8'h5A,8'h5C,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'h6A:
|
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;
|
8'h87,8'h88,8'h89,8'h8A:
|
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'b10111xxx:
|
8'hB9,8'hBA,8'hBB,8'hBC,8'hBD,8'hBE,8'hBF:
|
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 2390... |
Line 2436... |
`SB,`SBX: fnDatao = {8{dat[DBW/8-1:0]}};
|
`SB,`SBX: fnDatao = {8{dat[DBW/8-1:0]}};
|
default: fnDatao = dat;
|
default: fnDatao = dat;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
assign fetchbuf0_mem = fetchbuf ? fnIsMem(opcodeC) : fnIsMem(opcodeA);
|
assign fetchbuf0_mem = fnIsMem(opcode0);
|
assign fetchbuf0_jmp = fnIsFlowCtrl(opcode0);
|
assign fetchbuf0_jmp = fnIsFlowCtrl(opcode0);
|
assign fetchbuf0_fp = fnIsFP(opcode0);
|
assign fetchbuf0_fp = fnIsFP(opcode0);
|
assign fetchbuf0_rfw = fetchbuf ? fnIsRFW(opcodeC,fetchbufC_instr) : fnIsRFW(opcodeA,fetchbufA_instr);
|
assign fetchbuf0_rfw = fnIsRFW(opcode0,fetchbuf0_instr);
|
assign fetchbuf0_pfw = fetchbuf ? fnIsPFW(opcodeC) : fnIsPFW(opcodeA);
|
assign fetchbuf0_pfw = fnIsPFW(opcode0);
|
assign fetchbuf1_mem = fetchbuf ? fnIsMem(opcodeD) : fnIsMem(opcodeB);
|
assign fetchbuf1_mem = fnIsMem(opcode1);
|
assign fetchbuf1_jmp = fnIsFlowCtrl(opcode1);
|
assign fetchbuf1_jmp = fnIsFlowCtrl(opcode1);
|
assign fetchbuf1_fp = fnIsFP(opcode1);
|
assign fetchbuf1_fp = fnIsFP(opcode1);
|
assign fetchbuf1_rfw = fetchbuf ? fnIsRFW(opcodeD,fetchbufD_instr) : fnIsRFW(opcodeB,fetchbufB_instr);
|
assign fetchbuf1_rfw = fnIsRFW(opcode1,fetchbuf1_instr);
|
assign fetchbuf1_pfw = fetchbuf ? fnIsPFW(opcodeD) : fnIsPFW(opcodeB);
|
assign fetchbuf1_pfw = fnIsPFW(opcode1);
|
|
|
wire predict_taken0 = fetchbuf ? predict_takenC : predict_takenA;
|
|
wire predict_taken1 = fetchbuf ? predict_takenD : predict_takenB;
|
|
//
|
//
|
// set branchback and backpc values ... ignore branches in fetchbuf slots not ready for enqueue yet
|
// set branchback and backpc values ... ignore branches in fetchbuf slots not ready for enqueue yet
|
//
|
//
|
assign take_branch0 = ({fetchbuf0_v, fnIsBranch(opcode0), predict_taken0} == {`VAL, `TRUE, `TRUE}) ||
|
assign take_branch0 = ({fetchbuf0_v, fnIsBranch(opcode0), predict_taken0} == {`VAL, `TRUE, `TRUE}) ||
|
({fetchbuf0_v, opcode0==`LOOP} == {`VAL, `TRUE})
|
({fetchbuf0_v, opcode0==`LOOP} == {`VAL, `TRUE})
|
Line 2415... |
Line 2459... |
({fetchbuf1_v, opcode1==`LOOP} == {`VAL, `TRUE})
|
({fetchbuf1_v, opcode1==`LOOP} == {`VAL, `TRUE})
|
;
|
;
|
assign take_branch = take_branch0 || take_branch1
|
assign take_branch = take_branch0 || take_branch1
|
;
|
;
|
|
|
reg [DBW-1:0] branch_pc;// =
|
|
// ({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):
|
|
// (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
|
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;
|
end
|
end
|
else if (opcode0==`LOOP && fetchbuf0_v) begin
|
else if (opcode0==`LOOP && fetchbuf0_v) begin
|
Line 2433... |
Line 2473... |
end
|
end
|
else if (opcode1==`LOOP && fetchbuf1_v) begin
|
else if (opcode1==`LOOP && fetchbuf1_v) begin
|
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;
|
end
|
end
|
else begin
|
else begin
|
branch_pc <= RSTADDR; // set to something to prevent a latch
|
branch_pc <= RSTPC; // 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 && !mem_stringmiss) ||
|
((dram0_op==`STMV || dram0_op==`STCMP) && int_pending && lc != 0 && stmv_flag);
|
((dram0_op==`STMV || dram0_op==`STCMP) && int_pending && lc != 0 && !mem_stringmiss && stmv_flag);
|
|
|
assign jmpi_miss = dram_v && (dram0_op==`JMPI || dram0_op==`JMPIX);
|
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
|
Line 2520... |
Line 2560... |
endcase
|
endcase
|
|
|
// Return the immediate field of an instruction
|
// Return the immediate field of an instruction
|
function [63:0] fnImm;
|
function [63:0] fnImm;
|
input [127:0] insn;
|
input [127:0] insn;
|
case(insn[7:0])
|
|
8'b00010001: // RTS short form
|
|
fnImm = 64'd0;
|
|
default:
|
|
case(insn[15:8])
|
case(insn[15:8])
|
`P: fnImm = insn[33:16];
|
`P: fnImm = insn[33:16];
|
`CAS: fnImm = {{56{insn[47]}},insn[47:40]};
|
`CAS: fnImm = {{56{insn[47]}},insn[47:40]};
|
`BCD: fnImm = insn[47:40];
|
`BCD: fnImm = insn[47:40];
|
`TLB: fnImm = insn[23:16];
|
`TLB: fnImm = insn[23:16];
|
`LOOP: fnImm = {{56{insn[23]}},insn[23:16]};
|
`LOOP: fnImm = {{56{insn[23]}},insn[23:16]};
|
`STP: fnImm = insn[31:16];
|
`STP: fnImm = insn[31:16];
|
`JSR: fnImm = {{40{insn[47]}},insn[47:24]};
|
`JSR: fnImm = {{40{insn[47]}},insn[47:24]};
|
`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],4'h0};
|
`RTS2: fnImm = {insn[31:27],3'b000};
|
|
//`CMPI,
|
//`CMPI,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h2C,8'h2D,8'h2E,8'h2F,
|
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 = 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,
|
`JMPI,`LLA,
|
`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]};
|
endcase
|
endcase
|
endcase
|
|
|
|
endfunction
|
endfunction
|
|
|
function [7:0] fnImm8;
|
function [7:0] fnImm8;
|
input [127:0] insn;
|
input [127:0] insn;
|
if (insn[7:0]==8'h11)
|
|
fnImm8 = 8'h00;
|
|
else
|
|
case(insn[15:8])
|
case(insn[15:8])
|
`CAS: fnImm8 = insn[47:40];
|
`CAS: fnImm8 = insn[47:40];
|
`BCD: fnImm8 = insn[47:40];
|
`BCD: fnImm8 = insn[47:40];
|
`TLB: fnImm8 = insn[23:16];
|
`TLB: fnImm8 = insn[23:16];
|
`LOOP: fnImm8 = insn[23:16];
|
`LOOP: fnImm8 = insn[23:16];
|
`STP: fnImm8 = insn[23:16];
|
`STP: fnImm8 = insn[23:16];
|
`JSR,`JSRS,`RTS2: fnImm8 = insn[31:24];
|
`JSR,`JSRS: fnImm8 = insn[31:24];
|
`BITFIELD: fnImm8 = insn[39:32];
|
`BITFIELD: fnImm8 = insn[39:32];
|
`SYS,`INT: fnImm8 = insn[31:24];
|
`SYS,`INT: fnImm8 = {insn[27:24],4'h0};
|
//`CMPI,
|
//`CMPI,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h20,8'h21,8'h22,8'h23,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h24,8'h25,8'h26,8'h27,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h28,8'h29,8'h2A,8'h2B,
|
8'h2C,8'h2D,8'h2E,8'h2F,
|
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,`RTS2,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm8 = 8'h00;
|
`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,
|
`JMPI,`LLA,
|
`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
|
endfunction
|
endfunction
|
|
|
// Return MSB of immediate value for instruction
|
// Return MSB of immediate value for instruction
|
function fnImmMSB;
|
function fnImmMSB;
|
input [127:0] insn;
|
input [127:0] insn;
|
if (insn[7:0]==8'h11)
|
|
fnImmMSB = 1'b0;
|
|
else
|
|
case(insn[15:8])
|
case(insn[15:8])
|
`CAS: fnImmMSB = insn[47];
|
`CAS: fnImmMSB = insn[47];
|
`TLB,`BCD,`STP:
|
`TLB,`BCD,`STP:
|
fnImmMSB = 1'b0; // TLB regno is unsigned
|
fnImmMSB = 1'b0; // TLB regno is unsigned
|
`LOOP:
|
`LOOP:
|
Line 2625... |
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,
|
`JMPI,`LLA,
|
`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 2704... |
Line 2732... |
endfunction
|
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;
|
|
`ifdef PRIVCHKS
|
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 ||
|
op==`STP
|
op==`STP
|
;
|
;
|
|
`else
|
|
fnIsKMOnly = `FALSE;
|
|
`endif
|
endfunction
|
endfunction
|
|
|
function fnIsKMOnlyReg;
|
function fnIsKMOnlyReg;
|
input [6:0] regx;
|
input [6:0] regx;
|
|
`ifdef PRIVCHKS
|
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;
|
regx==7'h60 || regx==7'h68;
|
|
`else
|
|
fnIsKMOnlyReg = `FALSE;
|
|
`endif
|
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 2833... |
Line 2869... |
endgenerate
|
endgenerate
|
|
|
// The (old) simulator didn't handle the asynchronous race loop properly in the
|
// The (old) simulator didn't handle the asynchronous race loop properly in the
|
// original code. It would issue two instructions to the same islot. So the
|
// original code. It would issue two instructions to the same islot. So the
|
// issue logic has been re-written to eliminate the asynchronous loop.
|
// issue logic has been re-written to eliminate the asynchronous loop.
|
|
// Can't issue to the ALU if it's busy doing a long running operation like a
|
|
// divide.
|
always @*//(could_issue or head0 or head1 or head2 or head3 or head4 or head5 or head6 or head7)
|
always @*//(could_issue or head0 or head1 or head2 or head3 or head4 or head5 or head6 or head7)
|
begin
|
begin
|
iqentry_issue = 8'h00;
|
iqentry_issue = 8'h00;
|
iqentry_islot[0] = 2'b00;
|
iqentry_islot[0] = 2'b00;
|
iqentry_islot[1] = 2'b00;
|
iqentry_islot[1] = 2'b00;
|
Line 2844... |
Line 2882... |
iqentry_islot[3] = 2'b00;
|
iqentry_islot[3] = 2'b00;
|
iqentry_islot[4] = 2'b00;
|
iqentry_islot[4] = 2'b00;
|
iqentry_islot[5] = 2'b00;
|
iqentry_islot[5] = 2'b00;
|
iqentry_islot[6] = 2'b00;
|
iqentry_islot[6] = 2'b00;
|
iqentry_islot[7] = 2'b00;
|
iqentry_islot[7] = 2'b00;
|
if (could_issue[head0] & !iqentry_fp[head0]) begin
|
if (could_issue[head0] & !iqentry_fp[head0] & alu0_idle) begin
|
iqentry_issue[head0] = `TRUE;
|
iqentry_issue[head0] = `TRUE;
|
iqentry_islot[head0] = 2'b00;
|
iqentry_islot[head0] = 2'b00;
|
end
|
end
|
else if (could_issue[head1] & !iqentry_fp[head1]
|
else if (could_issue[head1] & !iqentry_fp[head1] & alu0_idle
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC))
|
&& !(iqentry_v[head0] && iqentry_sync[head0]))
|
begin
|
begin
|
iqentry_issue[head1] = `TRUE;
|
iqentry_issue[head1] = `TRUE;
|
iqentry_islot[head1] = 2'b00;
|
iqentry_islot[head1] = 2'b00;
|
end
|
end
|
else if (could_issue[head2] & !iqentry_fp[head2]
|
else if (could_issue[head2] & !iqentry_fp[head2] & alu0_idle
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
)
|
)
|
begin
|
begin
|
iqentry_issue[head2] = `TRUE;
|
iqentry_issue[head2] = `TRUE;
|
iqentry_islot[head2] = 2'b00;
|
iqentry_islot[head2] = 2'b00;
|
end
|
end
|
else if (could_issue[head3] & !iqentry_fp[head3]
|
else if (could_issue[head3] & !iqentry_fp[head3] & alu0_idle
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
) begin
|
) begin
|
iqentry_issue[head3] = `TRUE;
|
iqentry_issue[head3] = `TRUE;
|
iqentry_islot[head3] = 2'b00;
|
iqentry_islot[head3] = 2'b00;
|
end
|
end
|
else if (could_issue[head4] & !iqentry_fp[head4]
|
else if (could_issue[head4] & !iqentry_fp[head4] & alu0_idle
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
) begin
|
) begin
|
iqentry_issue[head4] = `TRUE;
|
iqentry_issue[head4] = `TRUE;
|
iqentry_islot[head4] = 2'b00;
|
iqentry_islot[head4] = 2'b00;
|
end
|
end
|
else if (could_issue[head5] & !iqentry_fp[head5]
|
else if (could_issue[head5] & !iqentry_fp[head5] & alu0_idle
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
) begin
|
) begin
|
iqentry_issue[head5] = `TRUE;
|
iqentry_issue[head5] = `TRUE;
|
iqentry_islot[head5] = 2'b00;
|
iqentry_islot[head5] = 2'b00;
|
end
|
end
|
else if (could_issue[head6] & !iqentry_fp[head6]
|
else if (could_issue[head6] & !iqentry_fp[head6] & alu0_idle
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
|
&& !(iqentry_v[head5] && iqentry_sync[head5])
|
) begin
|
) begin
|
iqentry_issue[head6] = `TRUE;
|
iqentry_issue[head6] = `TRUE;
|
iqentry_islot[head6] = 2'b00;
|
iqentry_islot[head6] = 2'b00;
|
end
|
end
|
else if (could_issue[head7] & !iqentry_fp[head7]
|
else if (could_issue[head7] & !iqentry_fp[head7] & alu0_idle
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
|
&& !(iqentry_v[head5] && iqentry_sync[head5])
|
&& !(iqentry_v[head6] && iqentry_op[head6]==`SYNC)
|
&& !(iqentry_v[head6] && iqentry_sync[head6])
|
) begin
|
) begin
|
iqentry_issue[head7] = `TRUE;
|
iqentry_issue[head7] = `TRUE;
|
iqentry_islot[head7] = 2'b00;
|
iqentry_islot[head7] = 2'b00;
|
end
|
end
|
|
|
// Don't bother checking head0, it should have issued to the first
|
// Don't bother checking head0, it should have issued to the first
|
// instruction.
|
// instruction.
|
if (could_issue[head1] && !iqentry_fp[head1] && !iqentry_issue[head1]
|
if (could_issue[head1] && !iqentry_fp[head1] && !iqentry_issue[head1] & alu1_idle
|
&& !fnIsAlu0Op(iqentry_op[head1],iqentry_fn[head1])
|
&& !fnIsAlu0Op(iqentry_op[head1],iqentry_fn[head1])
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC))
|
&& !(iqentry_v[head0] && iqentry_sync[head0]))
|
begin
|
begin
|
iqentry_issue[head1] = `TRUE;
|
iqentry_issue[head1] = `TRUE;
|
iqentry_islot[head1] = 2'b01;
|
iqentry_islot[head1] = 2'b01;
|
end
|
end
|
else if (could_issue[head2] && !iqentry_fp[head2] && !iqentry_issue[head2]
|
else if (could_issue[head2] && !iqentry_fp[head2] && !iqentry_issue[head2] & alu1_idle
|
&& !fnIsAlu0Op(iqentry_op[head2],iqentry_fn[head2])
|
&& !fnIsAlu0Op(iqentry_op[head2],iqentry_fn[head2])
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
)
|
)
|
begin
|
begin
|
iqentry_issue[head2] = `TRUE;
|
iqentry_issue[head2] = `TRUE;
|
iqentry_islot[head2] = 2'b01;
|
iqentry_islot[head2] = 2'b01;
|
end
|
end
|
else if (could_issue[head3] & !iqentry_fp[head3] && !iqentry_issue[head3]
|
else if (could_issue[head3] & !iqentry_fp[head3] && !iqentry_issue[head3] & alu1_idle
|
&& !fnIsAlu0Op(iqentry_op[head3],iqentry_fn[head3])
|
&& !fnIsAlu0Op(iqentry_op[head3],iqentry_fn[head3])
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
) begin
|
) begin
|
iqentry_issue[head3] = `TRUE;
|
iqentry_issue[head3] = `TRUE;
|
iqentry_islot[head3] = 2'b01;
|
iqentry_islot[head3] = 2'b01;
|
end
|
end
|
else if (could_issue[head4] & !iqentry_fp[head4] && !iqentry_issue[head4]
|
else if (could_issue[head4] & !iqentry_fp[head4] && !iqentry_issue[head4] & alu1_idle
|
&& !fnIsAlu0Op(iqentry_op[head4],iqentry_fn[head4])
|
&& !fnIsAlu0Op(iqentry_op[head4],iqentry_fn[head4])
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
) begin
|
) begin
|
iqentry_issue[head4] = `TRUE;
|
iqentry_issue[head4] = `TRUE;
|
iqentry_islot[head4] = 2'b01;
|
iqentry_islot[head4] = 2'b01;
|
end
|
end
|
else if (could_issue[head5] & !iqentry_fp[head5] && !iqentry_issue[head5]
|
else if (could_issue[head5] & !iqentry_fp[head5] && !iqentry_issue[head5] & alu1_idle
|
&& !fnIsAlu0Op(iqentry_op[head5],iqentry_fn[head5])
|
&& !fnIsAlu0Op(iqentry_op[head5],iqentry_fn[head5])
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
) begin
|
) begin
|
iqentry_issue[head5] = `TRUE;
|
iqentry_issue[head5] = `TRUE;
|
iqentry_islot[head5] = 2'b01;
|
iqentry_islot[head5] = 2'b01;
|
end
|
end
|
else if (could_issue[head6] & !iqentry_fp[head6] && !iqentry_issue[head6]
|
else if (could_issue[head6] & !iqentry_fp[head6] && !iqentry_issue[head6] & alu1_idle
|
&& !fnIsAlu0Op(iqentry_op[head6],iqentry_fn[head6])
|
&& !fnIsAlu0Op(iqentry_op[head6],iqentry_fn[head6])
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
|
&& !(iqentry_v[head5] && iqentry_sync[head5])
|
) begin
|
) begin
|
iqentry_issue[head6] = `TRUE;
|
iqentry_issue[head6] = `TRUE;
|
iqentry_islot[head6] = 2'b01;
|
iqentry_islot[head6] = 2'b01;
|
end
|
end
|
else if (could_issue[head7] & !iqentry_fp[head7] && !iqentry_issue[head7]
|
else if (could_issue[head7] & !iqentry_fp[head7] && !iqentry_issue[head7] & alu1_idle
|
&& !fnIsAlu0Op(iqentry_op[head7],iqentry_fn[head7])
|
&& !fnIsAlu0Op(iqentry_op[head7],iqentry_fn[head7])
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
|
&& !(iqentry_v[head5] && iqentry_sync[head5])
|
&& !(iqentry_v[head6] && iqentry_op[head6]==`SYNC)
|
&& !(iqentry_v[head6] && iqentry_sync[head6])
|
) begin
|
) begin
|
iqentry_issue[head7] = `TRUE;
|
iqentry_issue[head7] = `TRUE;
|
iqentry_islot[head7] = 2'b01;
|
iqentry_islot[head7] = 2'b01;
|
end
|
end
|
end
|
end
|
Line 3009... |
Line 3047... |
iqentry_fpissue[head0] = `TRUE;
|
iqentry_fpissue[head0] = `TRUE;
|
iqentry_fpislot[head0] = 2'b00;
|
iqentry_fpislot[head0] = 2'b00;
|
fpispot = head0;
|
fpispot = head0;
|
end
|
end
|
else if (could_issue[head1] & iqentry_fp[head1]
|
else if (could_issue[head1] & iqentry_fp[head1]
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC))
|
&& !(iqentry_v[head0] && iqentry_sync[head0]))
|
begin
|
begin
|
iqentry_fpissue[head1] = `TRUE;
|
iqentry_fpissue[head1] = `TRUE;
|
iqentry_fpislot[head1] = 2'b00;
|
iqentry_fpislot[head1] = 2'b00;
|
fpispot = head1;
|
fpispot = head1;
|
end
|
end
|
else if (could_issue[head2] & iqentry_fp[head2]
|
else if (could_issue[head2] & iqentry_fp[head2]
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
)
|
)
|
begin
|
begin
|
iqentry_fpissue[head2] = `TRUE;
|
iqentry_fpissue[head2] = `TRUE;
|
iqentry_fpislot[head2] = 2'b00;
|
iqentry_fpislot[head2] = 2'b00;
|
fpispot = head2;
|
fpispot = head2;
|
end
|
end
|
else if (could_issue[head3] & iqentry_fp[head3]
|
else if (could_issue[head3] & iqentry_fp[head3]
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
) begin
|
) begin
|
iqentry_fpissue[head3] = `TRUE;
|
iqentry_fpissue[head3] = `TRUE;
|
iqentry_fpislot[head3] = 2'b00;
|
iqentry_fpislot[head3] = 2'b00;
|
fpispot = head3;
|
fpispot = head3;
|
end
|
end
|
else if (could_issue[head4] & iqentry_fp[head4]
|
else if (could_issue[head4] & iqentry_fp[head4]
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
) begin
|
) begin
|
iqentry_fpissue[head4] = `TRUE;
|
iqentry_fpissue[head4] = `TRUE;
|
iqentry_fpislot[head4] = 2'b00;
|
iqentry_fpislot[head4] = 2'b00;
|
fpispot = head4;
|
fpispot = head4;
|
end
|
end
|
else if (could_issue[head5] & iqentry_fp[head5]
|
else if (could_issue[head5] & iqentry_fp[head5]
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
) begin
|
) begin
|
iqentry_fpissue[head5] = `TRUE;
|
iqentry_fpissue[head5] = `TRUE;
|
iqentry_fpislot[head5] = 2'b00;
|
iqentry_fpislot[head5] = 2'b00;
|
fpispot = head5;
|
fpispot = head5;
|
end
|
end
|
else if (could_issue[head6] & iqentry_fp[head6]
|
else if (could_issue[head6] & iqentry_fp[head6]
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
|
&& !(iqentry_v[head5] && iqentry_sync[head5])
|
) begin
|
) begin
|
iqentry_fpissue[head6] = `TRUE;
|
iqentry_fpissue[head6] = `TRUE;
|
iqentry_fpislot[head6] = 2'b00;
|
iqentry_fpislot[head6] = 2'b00;
|
fpispot = head6;
|
fpispot = head6;
|
end
|
end
|
else if (could_issue[head7] & iqentry_fp[head7]
|
else if (could_issue[head7] & iqentry_fp[head7]
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`SYNC)
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`SYNC)
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`SYNC)
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`SYNC)
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`SYNC)
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head5] && iqentry_op[head5]==`SYNC)
|
&& !(iqentry_v[head5] && iqentry_sync[head5])
|
&& !(iqentry_v[head6] && iqentry_op[head6]==`SYNC)
|
&& !(iqentry_v[head6] && iqentry_sync[head6])
|
) begin
|
) begin
|
iqentry_fpissue[head7] = `TRUE;
|
iqentry_fpissue[head7] = `TRUE;
|
iqentry_fpislot[head7] = 2'b00;
|
iqentry_fpislot[head7] = 2'b00;
|
fpispot = head7;
|
fpispot = head7;
|
end
|
end
|
Line 3120... |
Line 3158... |
// "ready" means that the instruction has valid operands but has not gone yet
|
// "ready" means that the instruction has valid operands but has not gone yet
|
//
|
//
|
// Stores can only issue if there is no possibility of a change of program flow.
|
// Stores can only issue if there is no possibility of a change of program flow.
|
// That means no flow control operations or instructions that can cause an
|
// That means no flow control operations or instructions that can cause an
|
// exception can be before the store.
|
// exception can be before the store.
|
|
|
|
// ToDo: if debugging matches are enabled in theory any instruction could cause
|
|
// a debug exception. The memory issue logic should check to see a debug address
|
|
// match will occur, and avoid a store operation. It may be simpler to have stores
|
|
// only occur if they are at the head of the queue if debugging matches are turned
|
|
// on.
|
assign iqentry_memissue_head0 = iqentry_memready[ head0 ] && cstate==IDLE && !dcache_access_pending && dram0==0; // first in line ... go as soon as ready
|
assign iqentry_memissue_head0 = iqentry_memready[ head0 ] && cstate==IDLE && !dcache_access_pending && dram0==0; // first in line ... go as soon as ready
|
|
|
assign iqentry_memissue_head1 = ~iqentry_stomp[head1] && iqentry_memready[ head1 ] // addr and data are valid
|
assign iqentry_memissue_head1 = ~iqentry_stomp[head1] && iqentry_memready[ head1 ] // addr and data are valid
|
// ... and no preceding instruction is ready to go
|
// ... and no preceding instruction is ready to go
|
&& ~iqentry_memready[head0]
|
&& ~iqentry_memready[head0]
|
Line 3131... |
Line 3175... |
&& (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
|
&& (!iqentry_mem[head0] || (iqentry_agen[head0] & iqentry_out[head0])
|
|| (iqentry_a1_v[head0] && iqentry_a1[head1][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
|
|| (iqentry_a1_v[head0] && iqentry_a1[head1][DBW-1:3] != iqentry_a1[head0][DBW-1:3]))
|
// ... and, if it is a SW, there is no chance of it being undone
|
// ... and, if it is a SW, there is no chance of it being undone
|
&& (fnIsStore(iqentry_op[head1]) ? !fnIsFlowCtrl(iqentry_op[head0])
|
&& (fnIsStore(iqentry_op[head1]) ? !fnIsFlowCtrl(iqentry_op[head0])
|
&& !fnCanException(iqentry_op[head0],iqentry_fn[head0]) : `TRUE)
|
&& !fnCanException(iqentry_op[head0],iqentry_fn[head0]) : `TRUE)
|
&& (iqentry_op[head1]!=`CAS)
|
&& (!iqentry_cas[head1])
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_memdb[head0])
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
|
&& !(iqentry_v[head0] && iqentry_memsb[head0])
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
;
|
;
|
|
|
assign iqentry_memissue_head2 = ~iqentry_stomp[head2] && iqentry_memready[ head2 ] // addr and data are valid
|
assign iqentry_memissue_head2 = ~iqentry_stomp[head2] && iqentry_memready[ head2 ] // addr and data are valid
|
// ... and no preceding instruction is ready to go
|
// ... and no preceding instruction is ready to go
|
Line 3151... |
Line 3195... |
// ... and, if it is a SW, there is no chance of it being undone
|
// ... and, if it is a SW, there is no chance of it being undone
|
&& (fnIsStore(iqentry_op[head2]) ?
|
&& (fnIsStore(iqentry_op[head2]) ?
|
!fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
|
!fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
|
!fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1])
|
!fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1])
|
: `TRUE)
|
: `TRUE)
|
&& (iqentry_op[head2]!=`CAS)
|
&& (!iqentry_cas[head2])
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_memdb[head0])
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_memdb[head1])
|
// ... and there is no instruction barrier
|
// ... and there is no instruction barrier
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
|
&& !(iqentry_v[head0] && iqentry_memsb[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
|
&& !(iqentry_v[head1] && iqentry_memsb[head1])
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
;
|
;
|
// ( !fnIsFlowCtrl(iqentry_op[head0])
|
// ( !fnIsFlowCtrl(iqentry_op[head0])
|
// && !fnIsFlowCtrl(iqentry_op[head1])));
|
// && !fnIsFlowCtrl(iqentry_op[head1])));
|
|
|
Line 3180... |
Line 3224... |
&& (fnIsStore(iqentry_op[head3]) ?
|
&& (fnIsStore(iqentry_op[head3]) ?
|
!fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
|
!fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
|
!fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
|
!fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
|
!fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2])
|
!fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2])
|
: `TRUE)
|
: `TRUE)
|
&& (iqentry_op[head3]!=`CAS)
|
&& (!iqentry_cas[head3])
|
// ... and there is no memory barrier
|
// ... and there is no memory barrier
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_memdb[head0])
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_memdb[head1])
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_memdb[head2])
|
// ... and there is no instruction barrier
|
// ... and there is no instruction barrier
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
|
&& !(iqentry_v[head0] && iqentry_memsb[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
|
&& !(iqentry_v[head1] && iqentry_memsb[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
|
&& !(iqentry_v[head2] && iqentry_memsb[head2])
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
;
|
;
|
/* ( !fnIsFlowCtrl(iqentry_op[head0])
|
/* ( !fnIsFlowCtrl(iqentry_op[head0])
|
&& !fnIsFlowCtrl(iqentry_op[head1])
|
&& !fnIsFlowCtrl(iqentry_op[head1])
|
&& !fnIsFlowCtrl(iqentry_op[head2])));
|
&& !fnIsFlowCtrl(iqentry_op[head2])));
|
Line 3217... |
Line 3261... |
!fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
|
!fnIsFlowCtrl(iqentry_op[head0]) && !fnCanException(iqentry_op[head0],iqentry_fn[head0]) &&
|
!fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
|
!fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
|
!fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
|
!fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
|
!fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3])
|
!fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3])
|
: `TRUE)
|
: `TRUE)
|
&& (iqentry_op[head4]!=`CAS)
|
&& (!iqentry_cas[head4])
|
// ... and there is no memory barrier
|
// ... and there is no memory barrier
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_memdb[head0])
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_memdb[head1])
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_memdb[head2])
|
&& !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_op[head3]==`MEMDB)
|
&& !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_memdb[head3])
|
// ... and there is no instruction barrier
|
// ... and there is no instruction barrier
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
|
&& !(iqentry_v[head0] && iqentry_memsb[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
|
&& !(iqentry_v[head1] && iqentry_memsb[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
|
&& !(iqentry_v[head2] && iqentry_memsb[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`MEMSB)
|
&& !(iqentry_v[head3] && iqentry_memsb[head3])
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
;
|
;
|
/* ||
|
/* ||
|
( !fnIsFlowCtrl(iqentry_op[head0])
|
( !fnIsFlowCtrl(iqentry_op[head0])
|
&& !fnIsFlowCtrl(iqentry_op[head1])
|
&& !fnIsFlowCtrl(iqentry_op[head1])
|
Line 3262... |
Line 3306... |
!fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
|
!fnIsFlowCtrl(iqentry_op[head1]) && !fnCanException(iqentry_op[head1],iqentry_fn[head1]) &&
|
!fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
|
!fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
|
!fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
|
!fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
|
!fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4])
|
!fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4])
|
: `TRUE)
|
: `TRUE)
|
&& (iqentry_op[head5]!=`CAS)
|
&& (!iqentry_cas[head5])
|
// ... and there is no memory barrier
|
// ... and there is no memory barrier
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_memdb[head0])
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_memdb[head1])
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_memdb[head2])
|
&& !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_op[head3]==`MEMDB)
|
&& !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_memdb[head3])
|
&& !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_op[head4]==`MEMDB)
|
&& !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_memdb[head4])
|
// ... and there is no instruction barrier
|
// ... and there is no instruction barrier
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
|
&& !(iqentry_v[head0] && iqentry_memsb[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
|
&& !(iqentry_v[head1] && iqentry_memsb[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
|
&& !(iqentry_v[head2] && iqentry_memsb[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`MEMSB)
|
&& !(iqentry_v[head3] && iqentry_memsb[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`MEMSB)
|
&& !(iqentry_v[head4] && iqentry_memsb[head4])
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
;
|
;
|
/*||
|
/*||
|
( !fnIsFlowCtrl(iqentry_op[head0])
|
( !fnIsFlowCtrl(iqentry_op[head0])
|
&& !fnIsFlowCtrl(iqentry_op[head1])
|
&& !fnIsFlowCtrl(iqentry_op[head1])
|
Line 3314... |
Line 3358... |
!fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
|
!fnIsFlowCtrl(iqentry_op[head2]) && !fnCanException(iqentry_op[head2],iqentry_fn[head2]) &&
|
!fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
|
!fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
|
!fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4]) &&
|
!fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4]) &&
|
!fnIsFlowCtrl(iqentry_op[head5]) && !fnCanException(iqentry_op[head5],iqentry_fn[head5])
|
!fnIsFlowCtrl(iqentry_op[head5]) && !fnCanException(iqentry_op[head5],iqentry_fn[head5])
|
: `TRUE)
|
: `TRUE)
|
&& (iqentry_op[head6]!=`CAS)
|
&& (!iqentry_cas[head6])
|
// ... and there is no memory barrier
|
// ... and there is no memory barrier
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_memdb[head0])
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_memdb[head1])
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_memdb[head2])
|
&& !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_op[head3]==`MEMDB)
|
&& !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_memdb[head3])
|
&& !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_op[head4]==`MEMDB)
|
&& !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_memdb[head4])
|
&& !(iqentry_v[head5] && fnIsMem(iqentry_op[head5]) && iqentry_op[head5]==`MEMDB)
|
&& !(iqentry_v[head5] && fnIsMem(iqentry_op[head5]) && iqentry_memdb[head5])
|
// ... and there is no instruction barrier
|
// ... and there is no instruction barrier
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
|
&& !(iqentry_v[head0] && iqentry_memsb[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
|
&& !(iqentry_v[head1] && iqentry_memsb[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
|
&& !(iqentry_v[head2] && iqentry_memsb[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`MEMSB)
|
&& !(iqentry_v[head3] && iqentry_memsb[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`MEMSB)
|
&& !(iqentry_v[head4] && iqentry_memsb[head4])
|
&& !(iqentry_v[head5] && iqentry_op[head5]==`MEMSB)
|
&& !(iqentry_v[head5] && iqentry_memsb[head5])
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
;
|
;
|
/*||
|
/*||
|
( !fnIsFlowCtrl(iqentry_op[head0])
|
( !fnIsFlowCtrl(iqentry_op[head0])
|
&& !fnIsFlowCtrl(iqentry_op[head1])
|
&& !fnIsFlowCtrl(iqentry_op[head1])
|
Line 3373... |
Line 3417... |
!fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
|
!fnIsFlowCtrl(iqentry_op[head3]) && !fnCanException(iqentry_op[head3],iqentry_fn[head3]) &&
|
!fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4]) &&
|
!fnIsFlowCtrl(iqentry_op[head4]) && !fnCanException(iqentry_op[head4],iqentry_fn[head4]) &&
|
!fnIsFlowCtrl(iqentry_op[head5]) && !fnCanException(iqentry_op[head5],iqentry_fn[head5]) &&
|
!fnIsFlowCtrl(iqentry_op[head5]) && !fnCanException(iqentry_op[head5],iqentry_fn[head5]) &&
|
!fnIsFlowCtrl(iqentry_op[head6]) && !fnCanException(iqentry_op[head6],iqentry_fn[head6])
|
!fnIsFlowCtrl(iqentry_op[head6]) && !fnCanException(iqentry_op[head6],iqentry_fn[head6])
|
: `TRUE)
|
: `TRUE)
|
&& (iqentry_op[head7]!=`CAS)
|
&& (!iqentry_cas[head7])
|
// ... and there is no memory barrier
|
// ... and there is no memory barrier
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_op[head0]==`MEMDB)
|
&& !(iqentry_v[head0] && fnIsMem(iqentry_op[head0]) && iqentry_memdb[head0])
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_op[head1]==`MEMDB)
|
&& !(iqentry_v[head1] && fnIsMem(iqentry_op[head1]) && iqentry_memdb[head1])
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_op[head2]==`MEMDB)
|
&& !(iqentry_v[head2] && fnIsMem(iqentry_op[head2]) && iqentry_memdb[head2])
|
&& !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_op[head3]==`MEMDB)
|
&& !(iqentry_v[head3] && fnIsMem(iqentry_op[head3]) && iqentry_memdb[head3])
|
&& !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_op[head4]==`MEMDB)
|
&& !(iqentry_v[head4] && fnIsMem(iqentry_op[head4]) && iqentry_memdb[head4])
|
&& !(iqentry_v[head5] && fnIsMem(iqentry_op[head5]) && iqentry_op[head5]==`MEMDB)
|
&& !(iqentry_v[head5] && fnIsMem(iqentry_op[head5]) && iqentry_memdb[head5])
|
&& !(iqentry_v[head6] && fnIsMem(iqentry_op[head6]) && iqentry_op[head6]==`MEMDB)
|
&& !(iqentry_v[head6] && fnIsMem(iqentry_op[head6]) && iqentry_memdb[head6])
|
// ... and there is no instruction barrier
|
// ... and there is no instruction barrier
|
&& !(iqentry_v[head0] && iqentry_op[head0]==`MEMSB)
|
&& !(iqentry_v[head0] && iqentry_memsb[head0])
|
&& !(iqentry_v[head1] && iqentry_op[head1]==`MEMSB)
|
&& !(iqentry_v[head1] && iqentry_memsb[head1])
|
&& !(iqentry_v[head2] && iqentry_op[head2]==`MEMSB)
|
&& !(iqentry_v[head2] && iqentry_memsb[head2])
|
&& !(iqentry_v[head3] && iqentry_op[head3]==`MEMSB)
|
&& !(iqentry_v[head3] && iqentry_memsb[head3])
|
&& !(iqentry_v[head4] && iqentry_op[head4]==`MEMSB)
|
&& !(iqentry_v[head4] && iqentry_memsb[head4])
|
&& !(iqentry_v[head5] && iqentry_op[head5]==`MEMSB)
|
&& !(iqentry_v[head5] && iqentry_memsb[head5])
|
&& !(iqentry_v[head6] && iqentry_op[head6]==`MEMSB)
|
&& !(iqentry_v[head6] && iqentry_memsb[head6])
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
&& cstate==IDLE && !dcache_access_pending && dram0==0
|
;
|
;
|
|
|
`include "Thor_execute_combo.v"
|
`include "Thor_execute_combo.v"
|
//`include "Thor_memory_combo.v"
|
//`include "Thor_memory_combo.v"
|
Line 3426... |
Line 3470... |
|
|
generate
|
generate
|
begin : memr
|
begin : memr
|
for (g = 0; g < QENTRIES; g = g + 1)
|
for (g = 0; g < QENTRIES; g = g + 1)
|
begin
|
begin
|
assign iqentry_memopsvalid[g] = (iqentry_mem[g] & iqentry_a2_v[g] & iqentry_a3_v[g] & iqentry_agen[g]);
|
assign iqentry_memopsvalid[g] = (iqentry_mem[g] & iqentry_a2_v[g] & iqentry_a3_v[g] & iqentry_agen[g] & iqentry_T_v[g]);
|
assign iqentry_memready[g] = (iqentry_v[g] & iqentry_memopsvalid[g] & ~iqentry_memissue[g] & !iqentry_issue[g] & ~iqentry_done[g] & ~iqentry_out[g] & ~iqentry_stomp[g]);
|
assign iqentry_memready[g] = (iqentry_v[g] & iqentry_memopsvalid[g] & ~iqentry_memissue[g] /*& !iqentry_issue[g]*/ & ~iqentry_done[g] & ~iqentry_out[g] & ~iqentry_stomp[g]);
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
/*
|
/*
|
assign
|
assign
|
iqentry_memopsvalid[0] = (iqentry_mem[0] & iqentry_a2_v[0] & iqentry_a3_v[0] & iqentry_agen[0]),
|
|
iqentry_memopsvalid[1] = (iqentry_mem[1] & iqentry_a2_v[1] & iqentry_a3_v[1] & iqentry_agen[1]),
|
|
iqentry_memopsvalid[2] = (iqentry_mem[2] & iqentry_a2_v[2] & iqentry_a3_v[2] & iqentry_agen[2]),
|
|
iqentry_memopsvalid[3] = (iqentry_mem[3] & iqentry_a2_v[3] & iqentry_a3_v[3] & iqentry_agen[3]),
|
|
iqentry_memopsvalid[4] = (iqentry_mem[4] & iqentry_a2_v[4] & iqentry_a3_v[4] & iqentry_agen[4]),
|
|
iqentry_memopsvalid[5] = (iqentry_mem[5] & iqentry_a2_v[5] & iqentry_a3_v[5] & iqentry_agen[5]),
|
|
iqentry_memopsvalid[6] = (iqentry_mem[6] & iqentry_a2_v[6] & iqentry_a3_v[6] & iqentry_agen[6]),
|
|
iqentry_memopsvalid[7] = (iqentry_mem[7] & iqentry_a2_v[7] & iqentry_a3_v[7] & iqentry_agen[7]);
|
|
|
|
assign
|
|
iqentry_memready[0] = (iqentry_v[0] & iqentry_memopsvalid[0] & ~iqentry_memissue[0] & ~iqentry_done[0] & ~iqentry_out[0] & ~iqentry_stomp[0]),
|
iqentry_memready[0] = (iqentry_v[0] & iqentry_memopsvalid[0] & ~iqentry_memissue[0] & ~iqentry_done[0] & ~iqentry_out[0] & ~iqentry_stomp[0]),
|
iqentry_memready[1] = (iqentry_v[1] & iqentry_memopsvalid[1] & ~iqentry_memissue[1] & ~iqentry_done[1] & ~iqentry_out[1] & ~iqentry_stomp[1]),
|
|
iqentry_memready[2] = (iqentry_v[2] & iqentry_memopsvalid[2] & ~iqentry_memissue[2] & ~iqentry_done[2] & ~iqentry_out[2] & ~iqentry_stomp[2]),
|
|
iqentry_memready[3] = (iqentry_v[3] & iqentry_memopsvalid[3] & ~iqentry_memissue[3] & ~iqentry_done[3] & ~iqentry_out[3] & ~iqentry_stomp[3]),
|
|
iqentry_memready[4] = (iqentry_v[4] & iqentry_memopsvalid[4] & ~iqentry_memissue[4] & ~iqentry_done[4] & ~iqentry_out[4] & ~iqentry_stomp[4]),
|
|
iqentry_memready[5] = (iqentry_v[5] & iqentry_memopsvalid[5] & ~iqentry_memissue[5] & ~iqentry_done[5] & ~iqentry_out[5] & ~iqentry_stomp[5]),
|
|
iqentry_memready[6] = (iqentry_v[6] & iqentry_memopsvalid[6] & ~iqentry_memissue[6] & ~iqentry_done[6] & ~iqentry_out[6] & ~iqentry_stomp[6]),
|
|
iqentry_memready[7] = (iqentry_v[7] & iqentry_memopsvalid[7] & ~iqentry_memissue[7] & ~iqentry_done[7] & ~iqentry_out[7] & ~iqentry_stomp[7]);
|
|
*/
|
*/
|
assign outstanding_stores = (dram0 && fnIsStore(dram0_op)) || (dram1 && fnIsStore(dram1_op)) || (dram2 && fnIsStore(dram2_op));
|
assign outstanding_stores = (dram0 && fnIsStore(dram0_op)) || (dram1 && fnIsStore(dram1_op)) || (dram2 && fnIsStore(dram2_op));
|
|
|
// This signal needed to stave off an instruction cache access.
|
// This signal needed to stave off an instruction cache access.
|
assign mem_issue =
|
assign mem_issue =
|
Line 3467... |
Line 3494... |
iqentry_memissue_head5 |
|
iqentry_memissue_head5 |
|
iqentry_memissue_head6 |
|
iqentry_memissue_head6 |
|
iqentry_memissue_head7
|
iqentry_memissue_head7
|
;
|
;
|
|
|
wire [DBW-1:0] argA = iqentry_a1_v[n] ? iqentry_a1[n]
|
// Nybble slices for predicate register forwarding
|
: (iqentry_a1_s[n] == alu0_id) ? alu0_bus
|
|
: (iqentry_a1_s[n] == alu1_id) ? alu1_bus
|
|
: (iqentry_a1_s[n] == commit1_id) ? commit1_bus
|
|
: (iqentry_a1_s[n] == commit0_id) ? commit0_bus
|
|
: 64'hDEADDEADDEADDEAD;
|
|
|
|
wire [3:0] alu0nyb[0:15];
|
wire [3:0] alu0nyb[0:15];
|
wire [3:0] alu1nyb[0:15];
|
wire [3:0] alu1nyb[0:15];
|
wire [3:0] cmt0nyb[0:15];
|
wire [3:0] cmt0nyb[0:15];
|
wire [3:0] cmt1nyb[0:15];
|
wire [3:0] cmt1nyb[0:15];
|
|
|
Line 3492... |
Line 3513... |
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
//`include "Thor_commit_combo.v"
|
//`include "Thor_commit_combo.v"
|
// If trying to write to two branch registers at once, or trying to write
|
|
// to two predicate registers at once, then limit the processor to single
|
|
// commit.
|
|
// The processor does not support writing two registers in the same register
|
|
// group at the same time for anything other than the general purpose
|
|
// registers. It is possible for the processor to write to two diffent groups
|
|
// at the same time.
|
|
//assign limit_cmt = (iqentry_rfw[head0] && iqentry_rfw[head1] && iqentry_tgt[head0][8]==1'b1 && iqentry_tgt[head1][8]==1'b1);
|
|
assign limit_cmt = 1'b0;
|
|
//assign committing2 = (iqentry_v[head0] && iqentry_v[head1] && !limit_cmt) || (head0 != tail0 && head1 != tail0);
|
|
|
|
assign commit0_v = ({iqentry_v[head0], iqentry_done[head0]} == 2'b11 && ~|panic);
|
assign commit0_v = ({iqentry_v[head0], iqentry_done[head0]} == 2'b11 && ~|panic);
|
assign commit1_v = ({iqentry_v[head0], iqentry_done[head0]} != 2'b10
|
assign commit1_v = ({iqentry_v[head0], iqentry_done[head0]} != 2'b10
|
&& {iqentry_v[head1], iqentry_done[head1]} == 2'b11 && ~|panic && !limit_cmt);
|
&& {iqentry_v[head1], iqentry_done[head1]} == 2'b11 && ~|panic);
|
|
|
assign commit0_id = {iqentry_mem[head0], head0}; // if a memory op, it has a DRAM-bus id
|
assign commit0_id = {iqentry_mem[head0], head0}; // if a memory op, it has a DRAM-bus id
|
assign commit1_id = {iqentry_mem[head1], head1}; // if a memory op, it has a DRAM-bus id
|
assign commit1_id = {iqentry_mem[head1], head1}; // if a memory op, it has a DRAM-bus id
|
|
|
assign commit0_tgt = iqentry_tgt[head0];
|
assign commit0_tgt = iqentry_tgt[head0];
|
Line 3599... |
Line 3610... |
alu1_ld <= 1'b0;
|
alu1_ld <= 1'b0;
|
`ifdef FLOATING_POINT
|
`ifdef FLOATING_POINT
|
fp0_ld <= 1'b0;
|
fp0_ld <= 1'b0;
|
`endif
|
`endif
|
|
|
|
// Interrupt enable countdown delay.
|
|
if (imcd!=6'h3f)
|
|
imcd <= {imcd[4:0],1'b0};
|
|
if (imcd==6'd0) begin
|
|
im <= 1'b0;
|
|
imcd <= 6'h3f;
|
|
end
|
|
|
mem_stringmiss <= `FALSE;
|
mem_stringmiss <= `FALSE;
|
if (mem_stringmissx) begin
|
if (mem_stringmissx) begin
|
mem_stringmiss <= `TRUE;
|
mem_stringmiss <= `TRUE;
|
dram0_op <= `NOP; // clears string miss
|
// dram0_op <= `NOP; // clears string miss
|
end
|
end
|
ic_invalidate <= `FALSE;
|
ic_invalidate <= `FALSE;
|
dc_invalidate <= `FALSE;
|
dc_invalidate <= `FALSE;
|
ic_invalidate_line <= `FALSE;
|
ic_invalidate_line <= `FALSE;
|
dc_invalidate_line <= `FALSE;
|
dc_invalidate_line <= `FALSE;
|
alu0_dataready <= `FALSE;
|
alu0_dataready <= `FALSE;
|
alu1_dataready <= `FALSE;
|
alu1_dataready <= `FALSE;
|
|
|
// Reset segmentation flag once operating in non-segmented area.
|
// Reset segmentation flag once operating in non-segmented area.
|
if (pc[ABW-1:ABW-4]==4'hF)
|
if (pc[ABW-1:ABW-4]==4'hF)
|
pc[ABW+3:ABW] <= 4'h0;
|
pc[ABW] <= 1'b0;
|
|
|
if (rst_i)
|
if (rst_i)
|
cstate <= RESET1;
|
cstate <= RESET1;
|
if (rst_i||cstate==RESET1||cstate==RESET2) begin
|
if (rst_i||cstate==RESET1||cstate==RESET2) begin
|
|
imcd <= 6'h3F;
|
wb_nack();
|
wb_nack();
|
|
`ifdef PCHIST
|
|
pc_cap <= `TRUE;
|
|
`endif
|
ierr <= 1'b0;
|
ierr <= 1'b0;
|
GM <= 8'hFF;
|
GM <= 8'hFF;
|
nmi_edge <= 1'b0;
|
nmi_edge <= 1'b0;
|
pc <= RSTADDR[ABW-1:0];
|
pc <= RSTPC[ABW-1:0];
|
StatusHWI <= `TRUE; // disables interrupts at startup until an RTI instruction is executed.
|
StatusHWI <= `TRUE; // disables interrupts at startup until an RTI instruction is executed.
|
im <= 1'b1;
|
im <= 1'b1;
|
imb <= 1'b1;
|
imb <= 1'b1;
|
ic_invalidate <= `TRUE;
|
ic_invalidate <= `TRUE;
|
dc_invalidate <= `TRUE;
|
dc_invalidate <= `TRUE;
|
Line 3706... |
Line 3729... |
panic <= `PANIC_NONE;
|
panic <= `PANIC_NONE;
|
string_pc <= 64'd0;
|
string_pc <= 64'd0;
|
// The pc wraps around to address zero while fetching the reset vector.
|
// The pc wraps around to address zero while fetching the reset vector.
|
// This causes the processor to use the code segement register so the
|
// This causes the processor to use the code segement register so the
|
// CS has to be defined for reset.
|
// CS has to be defined for reset.
|
sregs[7] <= 52'd0;
|
sregs[7] <= RSTCSEG;
|
for (i=0; i < 16; i=i+1)
|
for (i=0; i < 16; i=i+1)
|
pregs[i] <= 4'd0;
|
pregs[i] <= 4'd0;
|
asid <= 8'h00;
|
asid <= 8'h00;
|
rrmapno <= 3'd0;
|
rrmapno <= 3'd0;
|
dram0_id <= 0;
|
dram0_id <= 0;
|
Line 3783... |
Line 3806... |
// put results into the appropriate instruction entries
|
// put results into the appropriate instruction entries
|
//
|
//
|
if ((alu0_op==`RR && (alu0_fn==`MUL || alu0_fn==`MULU)) || alu0_op==`MULI || alu0_op==`MULUI) begin
|
if ((alu0_op==`RR && (alu0_fn==`MUL || alu0_fn==`MULU)) || alu0_op==`MULI || alu0_op==`MULUI) begin
|
if (alu0_done) begin
|
if (alu0_done) begin
|
alu0_dataready <= `TRUE;
|
alu0_dataready <= `TRUE;
|
alu0_op <= `NOP;
|
|
end
|
end
|
end
|
end
|
else if ((alu0_op==`RR && (alu0_fn==`DIV || alu0_fn==`DIVU)) || alu0_op==`DIVI || alu0_op==`DIVUI) begin
|
else if ((alu0_op==`RR && (alu0_fn==`DIV || alu0_fn==`DIVU || alu0_fn==`MOD || alu0_fn==`MODU)) ||
|
|
alu0_op==`DIVI || alu0_op==`DIVUI || alu0_op==`MODI || alu0_op==`MODUI) begin
|
if (alu0_done) begin
|
if (alu0_done) begin
|
alu0_dataready <= `TRUE;
|
alu0_dataready <= `TRUE;
|
alu0_op <= `NOP;
|
|
end
|
end
|
end
|
end
|
|
|
if (alu0_v) begin
|
if (alu0_v) begin
|
if (|alu0_exc)
|
if (|alu0_exc)
|
Line 3813... |
Line 3835... |
|
|
|
|
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
|
if (alu1_done) begin
|
if (alu1_done) begin
|
alu1_dataready <= `TRUE;
|
alu1_dataready <= `TRUE;
|
alu1_op <= `NOP;
|
|
end
|
end
|
end
|
end
|
else if (((alu1_op==`RR && (alu1_fn==`DIV || alu1_fn==`DIVU)) || alu1_op==`DIVI || alu1_op==`DIVUI) && ALU1BIG) begin
|
else if (((alu1_op==`RR && (alu1_fn==`DIV || alu1_fn==`DIVU || alu1_fn==`MOD || alu1_fn==`MODU)) ||
|
|
alu1_op==`DIVI || alu1_op==`DIVUI || alu1_op==`MODI || alu1_op==`MODUI) && ALU1BIG) begin
|
if (alu1_done) begin
|
if (alu1_done) begin
|
alu1_dataready <= `TRUE;
|
alu1_dataready <= `TRUE;
|
alu1_op <= `NOP;
|
|
end
|
end
|
end
|
end
|
|
|
if (alu1_v) begin
|
if (alu1_v) begin
|
if (|alu1_exc)
|
if (|alu1_exc)
|
Line 3966... |
Line 3987... |
end
|
end
|
4'b1100:
|
4'b1100:
|
// Note that there is no point to loading C,D here because
|
// Note that there is no point to loading C,D here because
|
// there is a predicted taken branch that would stomp on the
|
// there is a predicted taken branch that would stomp on the
|
// instructions anyways.
|
// instructions anyways.
|
if ((fnIsBranch(opcodeA) && predict_takenA)||opcodeA==`LOOP) begin
|
if ((fnIsBranch(opcodeA) && predict_takenBr)||opcodeA==`LOOP) begin
|
pc <= branch_pc;
|
pc <= branch_pc;
|
fetchbufA_v <= !(queued1|queued2);
|
fetchbufA_v <= !(queued1|queued2);
|
fetchbufB_v <= `INV; // stomp on it
|
fetchbufB_v <= `INV; // stomp on it
|
// may as well stick with same fetchbuf
|
// may as well stick with same fetchbuf
|
end
|
end
|
Line 4046... |
Line 4067... |
fetchbuf <= 1'b0;
|
fetchbuf <= 1'b0;
|
if (queued2|queued3)
|
if (queued2|queued3)
|
panic <= `PANIC_INVALIDIQSTATE;
|
panic <= `PANIC_INVALIDIQSTATE;
|
end
|
end
|
4'b1100:
|
4'b1100:
|
if ((fnIsBranch(opcodeC) && predict_takenC)||opcodeC==`LOOP) begin
|
if ((fnIsBranch(opcodeC) && predict_takenBr)||opcodeC==`LOOP) begin
|
pc <= branch_pc;
|
pc <= branch_pc;
|
fetchbufC_v <= !(queued1|queued2);
|
fetchbufC_v <= !(queued1|queued2);
|
fetchbufD_v <= `INV; // stomp on it
|
fetchbufD_v <= `INV; // stomp on it
|
// may as well stick with same fetchbuf
|
// may as well stick with same fetchbuf
|
end
|
end
|
Line 4441... |
Line 4462... |
: (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
|
(iqentry_mem[n] && !iqentry_cmpmv[n]) ? {sregs[iqentry_fn[n][5:3]],12'h000} :
|
((iqentry_mem[n] && !iqentry_cmpmv[n]) || iqentry_lla[n]) ? {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 4453... |
Line 4474... |
: (iqentry_T_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_T_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_T_s[n] == alu1_id) ? alu1_bus
|
: (iqentry_T_s[n] == alu1_id) ? alu1_bus
|
: 64'hDEADDEADDEADDEAD;
|
: 64'hDEADDEADDEADDEAD;
|
alu0_argI <= iqentry_a0[n];
|
alu0_argI <= iqentry_a0[n];
|
alu0_dataready <= fnAluValid(iqentry_op[n],iqentry_fn[n]);
|
alu0_dataready <= fnAluValid(iqentry_op[n],iqentry_fn[n]);
|
|
iqentry_out[n] <= `TRUE;
|
end
|
end
|
2'd1: if (alu1_available) begin
|
2'd1: if (alu1_available) begin
|
alu1_ld <= 1'b1;
|
alu1_ld <= 1'b1;
|
alu1_sourceid <= n[3:0];
|
alu1_sourceid <= n[3:0];
|
alu1_insnsz <= iqentry_insnsz[n];
|
alu1_insnsz <= iqentry_insnsz[n];
|
Line 4476... |
Line 4498... |
: (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
|
(iqentry_mem[n] && !iqentry_cmpmv[n])? {sregs[iqentry_fn[n][5:3]],12'h000} :
|
((iqentry_mem[n] && !iqentry_cmpmv[n]) || iqentry_lla[n]) ? {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 4488... |
Line 4510... |
: (iqentry_T_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_T_s[n] == alu0_id) ? alu0_bus
|
: (iqentry_T_s[n] == alu1_id) ? alu1_bus
|
: (iqentry_T_s[n] == alu1_id) ? alu1_bus
|
: 64'hDEADDEADDEADDEAD;
|
: 64'hDEADDEADDEADDEAD;
|
alu1_argI <= iqentry_a0[n];
|
alu1_argI <= iqentry_a0[n];
|
alu1_dataready <= fnAluValid(iqentry_op[n],iqentry_fn[n]);
|
alu1_dataready <= fnAluValid(iqentry_op[n],iqentry_fn[n]);
|
|
iqentry_out[n] <= `TRUE;
|
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_tlb[n]) 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
|
Line 4677... |
Line 4700... |
`STS:
|
`STS:
|
if (lc != 0 && !int_pending) begin
|
if (lc != 0 && !int_pending) begin
|
dram0_addr <= dram0_addr + fnIndexAmt(dram0_fn);
|
dram0_addr <= dram0_addr + fnIndexAmt(dram0_fn);
|
lc <= lc - 64'd1;
|
lc <= lc - 64'd1;
|
dram0 <= 3'd1;
|
dram0 <= 3'd1;
|
dram_bus <= dram0_addr + fnIndexAmt(dram0_fn);
|
// dram_bus <= dram0_addr + fnIndexAmt(dram0_fn) - dram0_seg;
|
end
|
end
|
else begin
|
else begin
|
dram_bus <= dram0_addr + fnIndexAmt(dram0_fn) - dram0_seg;
|
dram_bus <= dram0_addr + fnIndexAmt(dram0_fn) - dram0_seg;
|
dram_v <= `VAL;
|
dram_v <= `VAL;
|
|
dram0_op <= `NOP;
|
end
|
end
|
`STMV,`STCMP:
|
`STMV,`STCMP:
|
begin
|
begin
|
dram_bus <= index;
|
dram_bus <= index;
|
if (lc != 0 && !(int_pending && stmv_flag)) begin
|
if (lc != 0 && !(int_pending && stmv_flag)) begin
|
Line 4709... |
Line 4733... |
inc_index(dram0_fn);
|
inc_index(dram0_fn);
|
stmv_flag <= ~stmv_flag;
|
stmv_flag <= ~stmv_flag;
|
end
|
end
|
else begin
|
else begin
|
dram_v <= `VAL;
|
dram_v <= `VAL;
|
|
dram0_op <= `NOP;
|
end
|
end
|
end
|
end
|
`STFND:
|
`STFND:
|
if (lc != 0 && !int_pending) begin
|
if (lc != 0 && !int_pending) begin
|
dram0_addr <= src_addr + index;
|
dram0_addr <= src_addr + index;
|
Line 4726... |
Line 4751... |
dram0 <= 3'd1;
|
dram0 <= 3'd1;
|
end
|
end
|
else begin
|
else begin
|
dram_bus <= index;
|
dram_bus <= index;
|
dram_v <= `VAL;
|
dram_v <= `VAL;
|
|
dram0_op <= `NOP;
|
end
|
end
|
`endif
|
`endif
|
`CAS:
|
`CAS:
|
if (dram0_datacmp == dat_i) begin
|
if (dram0_datacmp == dat_i) begin
|
$display("CAS match");
|
$display("CAS match");
|
Line 4835... |
Line 4861... |
inc_index(dram0_fn);
|
inc_index(dram0_fn);
|
end
|
end
|
else begin
|
else begin
|
dram_v <= `VAL;
|
dram_v <= `VAL;
|
dram0 <= 3'd7;
|
dram0 <= 3'd7;
|
|
dram0_op <= `NOP;
|
end
|
end
|
end
|
end
|
`STFND:
|
`STFND:
|
begin
|
begin
|
dram_id <= dram0_id;
|
dram_id <= dram0_id;
|
Line 4855... |
Line 4882... |
end
|
end
|
end
|
end
|
else begin
|
else begin
|
dram_v <= `VAL;
|
dram_v <= `VAL;
|
dram0 <= 3'd7;
|
dram0 <= 3'd7;
|
|
dram0_op <= `NOP;
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
`INC:
|
`INC:
|
begin
|
begin
|
Line 5035... |
Line 5063... |
// Reset the nmi edge sense circuit but only for an NMI
|
// Reset the nmi edge sense circuit but only for an NMI
|
if ((iqentry_a0[head0][7:0]==8'hFE && commit0_v && iqentry_op[head0]==`INT) ||
|
if ((iqentry_a0[head0][7:0]==8'hFE && commit0_v && iqentry_op[head0]==`INT) ||
|
(iqentry_a0[head1][7:0]==8'hFE && commit1_v && iqentry_op[head1]==`INT))
|
(iqentry_a0[head1][7:0]==8'hFE && commit1_v && iqentry_op[head1]==`INT))
|
nmi_edge <= 1'b0;
|
nmi_edge <= 1'b0;
|
string_pc <= 64'd0;
|
string_pc <= 64'd0;
|
|
`ifdef PCHIST
|
|
pc_cap <= `FALSE;
|
|
`endif
|
end
|
end
|
|
|
if (sys_commit)
|
if (sys_commit)
|
begin
|
begin
|
if (StatusEXL!=8'hFF)
|
if (StatusEXL!=8'hFF)
|
Line 5469... |
Line 5500... |
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;
|
|
`ifdef PCHIST
|
|
6'd18: pc_ndx <= commit_bus[5:0];
|
|
`endif
|
default: ;
|
default: ;
|
endcase
|
endcase
|
6'b111111:
|
6'b111111:
|
begin
|
begin
|
ld_clk_throttle <= `TRUE;
|
ld_clk_throttle <= `TRUE;
|
Line 5545... |
Line 5579... |
fnSpr[15] = im;
|
fnSpr[15] = im;
|
fnSpr[12] = fxe;
|
fnSpr[12] = fxe;
|
end
|
end
|
6'd60: fnSpr = spr_bir;
|
6'd60: fnSpr = spr_bir;
|
6'd61:
|
6'd61:
|
case(spr_bir[5:0])
|
casex(spr_bir[5:0])
|
6'd0: fnSpr = dbg_adr0;
|
6'd0: fnSpr = dbg_adr0;
|
6'd1: fnSpr = dbg_adr1;
|
6'd1: fnSpr = dbg_adr1;
|
6'd2: fnSpr = dbg_adr2;
|
6'd2: fnSpr = dbg_adr2;
|
6'd3: fnSpr = dbg_adr3;
|
6'd3: fnSpr = dbg_adr3;
|
6'd4: fnSpr = dbg_ctrl;
|
6'd4: fnSpr = dbg_ctrl;
|
6'd5: fnSpr = dbg_stat;
|
6'd5: fnSpr = dbg_stat;
|
|
`ifdef PCHIST
|
|
6'd16: fnSpr = pc_histo[31:0];
|
|
6'd17: fnSpr = pc_histo[63:31];
|
|
`endif
|
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 ?
|
// 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
|
// 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
|
// Shaves a clock cycle off register updates. rf_v is being set valid on the
|
// clock cycle of the commit.
|
// 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}) begin
|
|
if (regno[5:4]==2'b00) begin
|
|
if (DBW==32)
|
|
fnSpr = {8{cmt0nyb[regno[2:0]]}};
|
|
else
|
|
fnSpr = {16{cmt0nyb[regno[3:0]]}};
|
|
end
|
|
else
|
fnSpr = commit0_bus;
|
fnSpr = commit0_bus;
|
if (commit1_v && commit1_tgt=={1'b1,regno})
|
end
|
|
if (commit1_v && commit1_tgt=={1'b1,regno}) begin
|
|
if (regno[5:4]==2'b00) begin
|
|
if (DBW==32)
|
|
fnSpr = {8{cmt1nyb[regno[2:0]]}};
|
|
else
|
|
fnSpr = {16{cmt1nyb[regno[3:0]]}};
|
|
end
|
|
else
|
fnSpr = commit1_bus;
|
fnSpr = commit1_bus;
|
|
end
|
|
|
// Special cases where the register would not be read from the commit bus
|
// Special cases where the register would not be read from the commit bus
|
case(regno)
|
case(regno)
|
`TICK: fnSpr = tick;
|
`TICK: fnSpr = tick;
|
6'b010000: fnSpr = 64'd0; // code address zero
|
6'b010000: fnSpr = 64'd0; // code address zero
|
Line 5584... |
Line 5638... |
input commit_v;
|
input commit_v;
|
input [2:0] head;
|
input [2:0] head;
|
begin
|
begin
|
if (commit_v)
|
if (commit_v)
|
case(iqentry_op[head])
|
case(iqentry_op[head])
|
`CLI: begin im <= 1'b0; imb <= 1'b0; end
|
`CLI: begin imcd <= IMCD; imb <= 1'b0; end
|
`SEI: begin im <= 1'b1; imb <= 1'b1; end
|
`SEI: begin im <= 1'b1; imb <= 1'b1; end
|
// 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;
|
if (imb)
|
|
im <= 1'b1;
|
|
else
|
|
imcd <= IMCD;
|
end
|
end
|
`RTD:
|
`RTD:
|
begin
|
begin
|
StatusDBG <= `FALSE;
|
StatusDBG <= `FALSE;
|
if (StatusEXL!=8'h00)
|
if (StatusEXL!=8'h00)
|
Line 5636... |
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'hFFFFda49)
|
if (fetchbuf0_pc==32'hFFFFD09B)
|
$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[7],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)
|
set_exception(tail,8'd244);
|
set_exception(tail,8'd244);
|
`endif
|
`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.
|
Line 5688... |
Line 5745... |
iqentry_insnsz[tail] <= fnInsnLength(fetchbuf0_instr);
|
iqentry_insnsz[tail] <= fnInsnLength(fetchbuf0_instr);
|
iqentry_op [tail] <= opcode0;
|
iqentry_op [tail] <= opcode0;
|
iqentry_fn [tail] <= opcode0==`MLO ? rfoc0[5:0] : fnFunc(fetchbuf0_instr);
|
iqentry_fn [tail] <= opcode0==`MLO ? rfoc0[5:0] : fnFunc(fetchbuf0_instr);
|
iqentry_cond [tail] <= cond0;
|
iqentry_cond [tail] <= cond0;
|
iqentry_bt [tail] <= fnIsFlowCtrl(opcode0) && predict_taken0;
|
iqentry_bt [tail] <= fnIsFlowCtrl(opcode0) && predict_taken0;
|
|
iqentry_br [tail] <= opcode0[7:4]==`BR;
|
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_ndx [tail] <= fnIsIndexed(opcode0);
|
iqentry_cas [tail] <= opcode0==`CAS;
|
iqentry_cas [tail] <= opcode0==`CAS;
|
iqentry_pushpop[tail] <= opcode0==`PUSH || opcode0==`POP;
|
iqentry_pushpop[tail] <= opcode0==`PUSH || opcode0==`POP;
|
iqentry_pea [tail] <= opcode0==`PEA;
|
iqentry_pea [tail] <= opcode0==`PEA;
|
iqentry_cmpmv[tail] <= opcode0==`STCMP || opcode0==`STMV;
|
iqentry_cmpmv[tail] <= opcode0==`STCMP || opcode0==`STMV;
|
|
iqentry_lla [tail] <= opcode0==`LLA || opcode0==`LLAX;
|
iqentry_tlb [tail] <= opcode0==`TLB;
|
iqentry_tlb [tail] <= opcode0==`TLB;
|
iqentry_jmp [tail] <= fetchbuf0_jmp;
|
iqentry_jmp [tail] <= fetchbuf0_jmp;
|
iqentry_jmpi [tail] <= opcode0==`JMPI || opcode0==`JMPIX;
|
iqentry_jmpi [tail] <= opcode0==`JMPI || opcode0==`JMPIX;
|
|
iqentry_sync [tail] <= opcode0==`SYNC;
|
|
iqentry_memsb[tail] <= opcode0==`MEMSB;
|
|
iqentry_memdb[tail] <= opcode0==`MEMDB;
|
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];
|
// Need the bypassing on the preg file for write-through register effect.
|
|
iqentry_pred [tail] <= fnSpr({2'h0,Pn0},fetchbuf0_pc);//pregs[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
|
iqentry_a0[tail] <= opcode0==`INT ? fnImm(fetchbuf0_instr) :
|
iqentry_a0[tail] <= (opcode0==`INT || opcode0==`SYS) ? 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);
|
// These register recordings for simulation debug. They should be stripped
|
// These register recordings for simulation debug. They should be stripped
|
// out of synthesis because they don't drive any signals.
|
// out of synthesis because they don't drive any signals.
|
`ifdef SIMULATION
|
`ifdef SIMULATION
|
Line 5767... |
Line 5830... |
iqentry_ndx [tail] <= 1'b0;
|
iqentry_ndx [tail] <= 1'b0;
|
iqentry_cas [tail] <= 1'b0;
|
iqentry_cas [tail] <= 1'b0;
|
iqentry_pushpop[tail] <= 1'b0;
|
iqentry_pushpop[tail] <= 1'b0;
|
iqentry_pea [tail] <= 1'b0;
|
iqentry_pea [tail] <= 1'b0;
|
iqentry_cmpmv[tail] <= 1'b0;
|
iqentry_cmpmv[tail] <= 1'b0;
|
|
iqentry_lla [tail] <= 1'b0;
|
iqentry_tlb [tail] <= 1'b0;
|
iqentry_tlb [tail] <= 1'b0;
|
iqentry_jmp [tail] <= 1'b0;
|
iqentry_jmp [tail] <= 1'b0;
|
iqentry_jmpi [tail] <= 1'b0;
|
iqentry_jmpi [tail] <= 1'b0;
|
|
iqentry_sync [tail] <= 1'b0;
|
|
iqentry_memsb[tail] <= 1'b0;
|
|
iqentry_memdb[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 5862... |
Line 5929... |
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'hFFFFDA49)
|
if (fetchbuf1_pc==32'hFFFFD09B)
|
$stop;
|
$stop;
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
`ifdef SEGLIMITS
|
`ifdef SEGLIMITS
|
if (fetchbuf1_pc >= {sregs_lmt[7],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);
|
`endif
|
`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);
|
Line 5909... |
Line 5976... |
iqentry_insnsz[tail] <= fnInsnLength(fetchbuf1_instr);
|
iqentry_insnsz[tail] <= fnInsnLength(fetchbuf1_instr);
|
iqentry_op [tail] <= opcode1;
|
iqentry_op [tail] <= opcode1;
|
iqentry_fn [tail] <= opcode1==`MLO ? rfoc1[5:0] : fnFunc(fetchbuf1_instr);
|
iqentry_fn [tail] <= opcode1==`MLO ? rfoc1[5:0] : fnFunc(fetchbuf1_instr);
|
iqentry_cond [tail] <= cond1;
|
iqentry_cond [tail] <= cond1;
|
iqentry_bt [tail] <= fnIsFlowCtrl(opcode1) && predict_taken1;
|
iqentry_bt [tail] <= fnIsFlowCtrl(opcode1) && predict_taken1;
|
|
iqentry_br [tail] <= opcode1[7:4]==`BR;
|
iqentry_agen [tail] <= `INV;
|
iqentry_agen [tail] <= `INV;
|
// If an interrupt is being enqueued and the previous instruction was an immediate prefix, then
|
// If an interrupt is being enqueued and the previous instruction was an immediate prefix, then
|
// inherit the address of the previous instruction, so that the prefix will be executed on return
|
// inherit the address of the previous instruction, so that the prefix will be executed on return
|
// from interrupt.
|
// from interrupt.
|
// 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
|
Line 5923... |
Line 5991... |
iqentry_ndx [tail] <= fnIsIndexed(opcode1);
|
iqentry_ndx [tail] <= fnIsIndexed(opcode1);
|
iqentry_cas [tail] <= opcode1==`CAS;
|
iqentry_cas [tail] <= opcode1==`CAS;
|
iqentry_pushpop[tail] <= opcode1==`PUSH || opcode1==`POP;
|
iqentry_pushpop[tail] <= opcode1==`PUSH || opcode1==`POP;
|
iqentry_pea [tail] <= opcode1==`PEA;
|
iqentry_pea [tail] <= opcode1==`PEA;
|
iqentry_cmpmv[tail] <= opcode1==`STCMP || opcode1==`STMV;
|
iqentry_cmpmv[tail] <= opcode1==`STCMP || opcode1==`STMV;
|
|
iqentry_lla [tail] <= opcode1==`LLA || opcode1==`LLAX;
|
iqentry_tlb [tail] <= opcode1==`TLB;
|
iqentry_tlb [tail] <= opcode1==`TLB;
|
iqentry_jmp [tail] <= fetchbuf1_jmp;
|
iqentry_jmp [tail] <= fetchbuf1_jmp;
|
iqentry_jmpi [tail] <= opcode1==`JMPI || opcode1==`JMPIX;
|
iqentry_jmpi [tail] <= opcode1==`JMPI || opcode1==`JMPIX;
|
|
iqentry_sync [tail] <= opcode1==`SYNC;
|
|
iqentry_memsb[tail] <= opcode1==`MEMSB;
|
|
iqentry_memdb[tail] <= opcode1==`MEMDB;
|
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] <= fnSpr({2'h0,Pn1},fetchbuf1_pc);//pregs[Pn1];
|
// 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
|
// But don't allow it for a branch
|
// But don't allow it for a branch
|
iqentry_a0[tail] <= opcode1==`INT ? fnImm(fetchbuf1_instr) :
|
iqentry_a0[tail] <= (opcode1==`INT || opcode1==`SYS) ? fnImm(fetchbuf1_instr) :
|
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);
|