Line 99... |
Line 99... |
//
|
//
|
// ============================================================================
|
// ============================================================================
|
//
|
//
|
`include "Thor_defines.v"
|
`include "Thor_defines.v"
|
|
|
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, clk2x_i, clk_o, km, nmi_i, irq_i, vec_i, bte_o, cti_o, bl_o, lock_o, resv_o, resv_i, cres_o,
|
cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o);
|
cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o);
|
parameter DBW = 32; // databus width
|
parameter DBW = 32; // databus width
|
parameter ABW = 32; // address bus width
|
parameter ABW = 32; // address bus width
|
parameter RSTCSEG = 52'h0;
|
parameter RSTCSEG = 52'h0;
|
parameter RSTPC = 64'hFFFFFFFFFFFC0000;
|
parameter RSTPC = 64'hFFFFFFFFFFFC0000;
|
Line 120... |
Line 120... |
parameter IBUF1 = 4'd5;
|
parameter IBUF1 = 4'd5;
|
parameter IBUF2 = 4'd6;
|
parameter IBUF2 = 4'd6;
|
parameter IBUF3 = 4'd7;
|
parameter IBUF3 = 4'd7;
|
parameter IBUF4 = 4'd8;
|
parameter IBUF4 = 4'd8;
|
parameter IBUF5 = 4'd9;
|
parameter IBUF5 = 4'd9;
|
|
`ifdef VECTOROPS
|
|
parameter NREGS = 511;
|
|
`else
|
parameter NREGS = 127;
|
parameter NREGS = 127;
|
|
`endif
|
parameter PF = 4'd0;
|
parameter PF = 4'd0;
|
parameter PT = 4'd1;
|
parameter PT = 4'd1;
|
parameter PEQ = 4'd2;
|
parameter PEQ = 4'd2;
|
parameter PNE = 4'd3;
|
parameter PNE = 4'd3;
|
parameter PLE = 4'd4;
|
parameter PLE = 4'd4;
|
Line 136... |
Line 140... |
parameter PGEU = 4'd10;
|
parameter PGEU = 4'd10;
|
parameter PLTU = 4'd11;
|
parameter PLTU = 4'd11;
|
input [63:0] corenum;
|
input [63:0] corenum;
|
input rst_i;
|
input rst_i;
|
input clk_i;
|
input clk_i;
|
|
input clk2x_i;
|
output clk_o;
|
output clk_o;
|
output km;
|
output km;
|
input nmi_i;
|
input nmi_i;
|
input irq_i;
|
input irq_i;
|
input [7:0] vec_i;
|
input [7:0] vec_i;
|
Line 160... |
Line 165... |
input [DBW-1:0] dat_i;
|
input [DBW-1:0] dat_i;
|
output reg [DBW-1:0] dat_o;
|
output reg [DBW-1:0] dat_o;
|
|
|
integer n,i;
|
integer n,i;
|
reg [1:0] mode;
|
reg [1:0] mode;
|
|
reg [1:0] smode;
|
|
reg [2:0] regset;
|
reg [DBW/8-1:0] rsel;
|
reg [DBW/8-1:0] rsel;
|
reg [3:0] cstate;
|
reg [3:0] cstate;
|
reg [ABW:0] pc; // program counter (virtual)
|
reg [ABW:0] pc; // program counter (virtual)
|
wire [ABW-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
|
Line 171... |
Line 178... |
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
|
reg [ 3:0] pregs [0:15]; // predicate registers
|
reg [ 3:0] pregs [0:15]; // predicate registers
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
reg [DBW-1:12] sregs [0:7]; // segment registers
|
reg [31:0] LDT;
|
reg [DBW-1:12] sregs_lmt [0:7];
|
reg [DBW-1:0] GDT;
|
|
reg [3:0] segsw; //
|
|
reg [31:0] sregs [0:8]; // segment selector registers
|
|
reg [DBW-1:12] sregs_base [0:8];
|
|
reg [DBW-1:12] sregs_lmt [0:8];
|
|
reg [15:0] sregs_acr [0:8];
|
|
wire [7:0] CPL = sregs[7][31:24]; // currently running privilege level
|
`endif
|
`endif
|
|
`ifdef VECTOROPS
|
|
reg [3:0] vpregs [1:0][0:15]; // two, sixteen element
|
|
`endif
|
|
reg [7:0] VL = 0;
|
|
reg [DBW-1:0] intarg1;
|
reg [2:0] rrmapno; // register rename map number
|
reg [2:0] rrmapno; // register rename map number
|
wire ITLBMiss;
|
wire ITLBMiss;
|
wire DTLBMiss;
|
wire DTLBMiss;
|
wire uncached;
|
wire uncached;
|
wire [DBW-1:0] cdat;
|
wire [DBW-1:0] cdat;
|
Line 213... |
Line 231... |
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]==1'b1) ? 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[3'd7],12'h000} + pc[ABW-1:0];
|
(pc[ABW-1:ABW-4]==4'hF) ? pc[ABW-1:0] : {sregs_base[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;
|
reg stmv_flag;
|
reg stmv_flag;
|
reg [7:0] asid;
|
reg [7:0] asid;
|
|
wire [DBW-1:0] operandA0, operandA1;
|
|
|
wire clk;
|
wire clk;
|
|
|
// Operand registers
|
// Operand registers
|
wire take_branch;
|
wire take_branch;
|
Line 241... |
Line 260... |
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_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_vec [0:7]; // is a vector instruction
|
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];
|
Line 265... |
Line 285... |
reg iqentry_p_v [0:7]; // predicate is valid
|
reg iqentry_p_v [0:7]; // predicate is valid
|
reg [3:0] iqentry_p_s [0:7]; // predicate source
|
reg [3:0] iqentry_p_s [0:7]; // predicate source
|
reg [7:0] iqentry_op [0:7]; // instruction opcode
|
reg [7:0] iqentry_op [0:7]; // instruction opcode
|
reg [5:0] iqentry_fn [0:7]; // instruction function
|
reg [5:0] iqentry_fn [0:7]; // instruction function
|
reg [2:0] iqentry_renmapno [0:7]; // register rename map number
|
reg [2:0] iqentry_renmapno [0:7]; // register rename map number
|
reg [6:0] iqentry_tgt [0:7]; // Rt field or ZERO -- this is the instruction's target (if any)
|
reg [9:0] iqentry_tgt [0:7]; // Rt field or ZERO -- this is the instruction's target (if any)
|
reg [DBW-1:0] iqentry_a0 [0:7]; // argument 0 (immediate)
|
reg [DBW-1:0] iqentry_a0 [0:7]; // argument 0 (immediate)
|
reg [DBW-1:0] iqentry_a1 [0:7]; // argument 1
|
reg [DBW-1:0] iqentry_a1 [0:7]; // argument 1
|
reg [6:0] iqentry_r1 [0:7];
|
reg [7:0] iqentry_r1 [0:7];
|
reg iqentry_a1_v [0:7]; // arg1 valid
|
reg iqentry_a1_v [0:7]; // arg1 valid
|
reg [3:0] iqentry_a1_s [0:7]; // arg1 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [3:0] iqentry_a1_s [0:7]; // arg1 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [6:0] iqentry_r2 [0:7];
|
reg [7:0] iqentry_r2 [0:7];
|
reg [DBW-1:0] iqentry_a2 [0:7]; // argument 2
|
reg [DBW-1:0] iqentry_a2 [0:7]; // argument 2
|
reg iqentry_a2_v [0:7]; // arg2 valid
|
reg iqentry_a2_v [0:7]; // arg2 valid
|
reg [3:0] iqentry_a2_s [0:7]; // arg2 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [3:0] iqentry_a2_s [0:7]; // arg2 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [6:0] iqentry_r3 [0:7];
|
reg iqentry_a2_sv [0:7]; // source is vector register
|
|
reg [7:0] iqentry_r3 [0:7];
|
reg [DBW-1:0] iqentry_a3 [0:7]; // argument 3
|
reg [DBW-1:0] iqentry_a3 [0:7]; // argument 3
|
reg iqentry_a3_v [0:7]; // arg3 valid
|
reg iqentry_a3_v [0:7]; // arg3 valid
|
reg [3:0] iqentry_a3_s [0:7]; // arg3 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [3:0] iqentry_a3_s [0:7]; // arg3 source (iq entry # with top bit representing ALU/DRAM bus)
|
reg [6:0] iqentry_rt [0:7];
|
`ifdef VECTOROPS
|
|
reg [7:0] iqentry_r4 [0:7];
|
|
reg [DBW-1:0] iqentry_a4 [0:7]; // argument 4
|
|
reg iqentry_a4_v [0:7];
|
|
reg [3:0] iqentry_a4_s [0:7];
|
|
`endif
|
|
reg [7:0] iqentry_rt [0:7];
|
reg [DBW-1:0] iqentry_T [0:7];
|
reg [DBW-1:0] iqentry_T [0:7];
|
reg iqentry_T_v [0:7];
|
reg iqentry_T_v [0:7];
|
reg [3:0] iqentry_T_s [0:7];
|
reg [3:0] iqentry_T_s [0:7];
|
reg [DBW-1:0] iqentry_pc [0:7]; // program counter for this instruction
|
reg [DBW-1:0] iqentry_pc [0:7]; // program counter for this instruction
|
|
reg iqentry_velv [0:7];
|
|
|
reg [7:0] iqentry_source;
|
reg [7:0] iqentry_source;
|
wire iqentry_imm [0:7];
|
wire iqentry_imm [0:7];
|
wire iqentry_memready [0:7];
|
wire iqentry_memready [0:7];
|
wire iqentry_memopsvalid [0:7];
|
wire iqentry_memopsvalid [0:7];
|
Line 317... |
Line 345... |
reg [1:0] iqentry_islot[0:7];
|
reg [1:0] iqentry_islot[0:7];
|
reg [1:0] iqentry_fpislot[0:7];
|
reg [1:0] iqentry_fpislot[0:7];
|
|
|
reg queued1,queued2;
|
reg queued1,queued2;
|
reg queued3; // for three-way config
|
reg queued3; // for three-way config
|
|
reg queued1v,queued2v;
|
|
reg queued3v; // for three-way config
|
reg allowq;
|
reg allowq;
|
|
|
wire [NREGS:1] livetarget;
|
wire [NREGS:1] livetarget;
|
wire [NREGS:1] iqentry_0_livetarget;
|
wire [NREGS:1] iqentry_0_livetarget;
|
wire [NREGS:1] iqentry_1_livetarget;
|
wire [NREGS:1] iqentry_1_livetarget;
|
Line 366... |
Line 396... |
|
|
reg [63:0] fetchbuf0_instr;
|
reg [63:0] fetchbuf0_instr;
|
reg [DBW-1:0] fetchbuf0_pc;
|
reg [DBW-1:0] fetchbuf0_pc;
|
reg fetchbuf0_v;
|
reg fetchbuf0_v;
|
wire fetchbuf0_mem;
|
wire fetchbuf0_mem;
|
|
wire fetchbuf0_vec;
|
wire fetchbuf0_jmp;
|
wire fetchbuf0_jmp;
|
wire fetchbuf0_fp;
|
wire fetchbuf0_fp;
|
wire fetchbuf0_rfw;
|
wire fetchbuf0_rfw;
|
wire fetchbuf0_pfw;
|
wire fetchbuf0_pfw;
|
reg [63:0] fetchbuf1_instr;
|
reg [63:0] fetchbuf1_instr;
|
reg [DBW-1:0] fetchbuf1_pc;
|
reg [DBW-1:0] fetchbuf1_pc;
|
reg fetchbuf1_v;
|
reg fetchbuf1_v;
|
wire fetchbuf1_mem;
|
wire fetchbuf1_mem;
|
|
wire fetchbuf1_vec;
|
wire fetchbuf1_jmp;
|
wire fetchbuf1_jmp;
|
wire fetchbuf1_fp;
|
wire fetchbuf1_fp;
|
wire fetchbuf1_rfw;
|
wire fetchbuf1_rfw;
|
wire fetchbuf1_pfw;
|
wire fetchbuf1_pfw;
|
wire fetchbuf1_bfw;
|
wire fetchbuf1_bfw;
|
reg [63:0] fetchbuf2_instr;
|
reg [63:0] fetchbuf2_instr;
|
reg [DBW-1:0] fetchbuf2_pc;
|
reg [DBW-1:0] fetchbuf2_pc;
|
reg fetchbuf2_v;
|
reg fetchbuf2_v;
|
wire fetchbuf2_mem;
|
wire fetchbuf2_mem;
|
|
wire fetchbuf2_vec;
|
wire fetchbuf2_jmp;
|
wire fetchbuf2_jmp;
|
wire fetchbuf2_fp;
|
wire fetchbuf2_fp;
|
wire fetchbuf2_rfw;
|
wire fetchbuf2_rfw;
|
wire fetchbuf2_pfw;
|
wire fetchbuf2_pfw;
|
wire fetchbuf2_bfw;
|
wire fetchbuf2_bfw;
|
Line 425... |
Line 458... |
reg [DBW-1:0] alu0_argI;
|
reg [DBW-1:0] alu0_argI;
|
reg [3:0] alu0_pred;
|
reg [3:0] alu0_pred;
|
reg [DBW-1:0] alu0_pc;
|
reg [DBW-1:0] alu0_pc;
|
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 [8:0] alu0_exc;
|
reg alu0_v;
|
reg alu0_v;
|
wire alu0_branchmiss;
|
wire alu0_branchmiss;
|
reg [ABW:0] alu0_misspc;
|
reg [ABW:0] alu0_misspc;
|
|
|
reg alu1_ld;
|
reg alu1_ld;
|
Line 449... |
Line 482... |
reg [DBW-1:0] alu1_argI;
|
reg [DBW-1:0] alu1_argI;
|
reg [3:0] alu1_pred;
|
reg [3:0] alu1_pred;
|
reg [DBW-1:0] alu1_pc;
|
reg [DBW-1:0] alu1_pc;
|
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 [8:0] alu1_exc;
|
reg alu1_v;
|
reg alu1_v;
|
wire alu1_branchmiss;
|
wire alu1_branchmiss;
|
reg [ABW:0] alu1_misspc;
|
reg [ABW:0] alu1_misspc;
|
|
|
wire jmpi_miss;
|
wire jmpi_miss;
|
Line 503... |
Line 536... |
reg [DBW-1:0] dram0_addr;
|
reg [DBW-1:0] dram0_addr;
|
reg [DBW-1:0] dram0_seg; // value of segment register associated with memory operation
|
reg [DBW-1:0] dram0_seg; // value of segment register associated with memory operation
|
reg [ABW-1:12] dram0_lmt; // value of segment limit associated with memory operation
|
reg [ABW-1:12] dram0_lmt; // value of segment limit associated with memory operation
|
reg [7:0] dram0_op;
|
reg [7:0] dram0_op;
|
reg [5:0] dram0_fn;
|
reg [5:0] dram0_fn;
|
reg [8:0] dram0_tgt;
|
reg [9:0] dram0_tgt;
|
reg [3:0] dram0_id;
|
reg [3:0] dram0_id;
|
reg [3:0] dram0_exc;
|
reg [8:0] dram0_exc;
|
reg [ABW-1:0] dram0_misspc;
|
reg [ABW-1:0] dram0_misspc;
|
reg dram1_owns_bus;
|
reg dram1_owns_bus;
|
reg [DBW-1:0] dram1_data;
|
reg [DBW-1:0] dram1_data;
|
reg [DBW-1:0] dram1_datacmp;
|
reg [DBW-1:0] dram1_datacmp;
|
reg [DBW-1:0] dram1_addr;
|
reg [DBW-1:0] dram1_addr;
|
reg [7:0] dram1_op;
|
reg [7:0] dram1_op;
|
reg [5:0] dram1_fn;
|
reg [5:0] dram1_fn;
|
reg [6:0] dram1_tgt;
|
reg [9:0] dram1_tgt;
|
reg [3:0] dram1_id;
|
reg [3:0] dram1_id;
|
reg [3:0] dram1_exc;
|
reg [8:0] dram1_exc;
|
reg [DBW-1:0] dram2_data;
|
reg [DBW-1:0] dram2_data;
|
reg [DBW-1:0] dram2_datacmp;
|
reg [DBW-1:0] dram2_datacmp;
|
reg [DBW-1:0] dram2_addr;
|
reg [DBW-1:0] dram2_addr;
|
reg [7:0] dram2_op;
|
reg [7:0] dram2_op;
|
reg [5:0] dram2_fn;
|
reg [5:0] dram2_fn;
|
reg [6:0] dram2_tgt;
|
reg [9:0] dram2_tgt;
|
reg [3:0] dram2_id;
|
reg [3:0] dram2_id;
|
reg [3:0] dram2_exc;
|
reg [8:0] dram2_exc;
|
|
|
reg [DBW-1:0] dram_bus;
|
reg [DBW-1:0] dram_bus;
|
reg [6:0] dram_tgt;
|
reg [9:0] dram_tgt;
|
reg [3:0] dram_id;
|
reg [3:0] dram_id;
|
reg [3:0] dram_exc;
|
reg [8:0] dram_exc;
|
reg dram_v;
|
reg dram_v;
|
|
|
reg [DBW-1:0] index;
|
reg [DBW-1:0] index;
|
reg [DBW-1:0] src_addr,dst_addr;
|
reg [DBW-1:0] src_addr,dst_addr;
|
wire mem_issue;
|
wire mem_issue;
|
Line 540... |
Line 573... |
wire outstanding_stores;
|
wire outstanding_stores;
|
reg [DBW-1:0] I; // instruction count
|
reg [DBW-1:0] I; // instruction count
|
|
|
wire commit0_v;
|
wire commit0_v;
|
wire [3:0] commit0_id;
|
wire [3:0] commit0_id;
|
wire [6:0] commit0_tgt;
|
wire [7:0] commit0_tgt;
|
wire [DBW-1:0] commit0_bus;
|
wire [DBW-1:0] commit0_bus;
|
wire commit1_v;
|
wire commit1_v;
|
wire [3:0] commit1_id;
|
wire [3:0] commit1_id;
|
wire [6:0] commit1_tgt;
|
wire [7:0] commit1_tgt;
|
wire [DBW-1:0] commit1_bus;
|
wire [DBW-1:0] commit1_bus;
|
|
wire commit2_v;
|
|
wire [3:0] commit2_id;
|
|
wire [7:0] commit2_tgt;
|
|
wire [DBW-1:0] commit2_bus;
|
wire limit_cmt;
|
wire limit_cmt;
|
wire committing2;
|
wire committing2;
|
|
|
wire [63:0] alu0_divq;
|
wire [63:0] alu0_divq;
|
wire [63:0] alu0_rem;
|
wire [63:0] alu0_rem;
|
Line 868... |
Line 905... |
// A single instruction can require 3 read ports. Only a total of four read
|
// A single instruction can require 3 read ports. Only a total of four read
|
// ports are supported because most of the time that's enough.
|
// ports are supported because most of the time that's enough.
|
// If there aren't enough read ports available then the second instruction
|
// If there aren't enough read ports available then the second instruction
|
// isn't enqueued (it'll be enqueued in the next cycle).
|
// isn't enqueued (it'll be enqueued in the next cycle).
|
reg [1:0] ports_avail; // available read ports for instruction #3.
|
reg [1:0] ports_avail; // available read ports for instruction #3.
|
reg [6:0] pRa0,pRb0,pRa1,pRb1,pRt0,pRt1;
|
reg [9:0] pRa0,pRb0,pRa1,pRb1,pRt0,pRt1;
|
|
wire [9:0] pRc0,pRd0,pRc1,pRd1;
|
wire [DBW-1:0] prfoa0,prfob0,prfoa1,prfob1;
|
wire [DBW-1:0] prfoa0,prfob0,prfoa1,prfob1;
|
|
wire [DBW-1:0] pvrfoa0,pvrfob0,pvrfoa1,pvrfob1,pvrfoc0,pvrfoc1;
|
wire [DBW-1:0] prfot0,prfot1;
|
wire [DBW-1:0] prfot0,prfot1;
|
|
wire [DBW-1:0] vrfot0,vrfot1;
|
|
|
|
reg [2:0] vele;
|
|
wire [7:0] Ra0 = fnRa(fetchbuf0_instr);
|
|
wire [7:0] Rb0 = fnRb(fetchbuf0_instr);
|
|
wire [7:0] Rc0 = fnRc(fetchbuf0_instr);
|
|
wire [7:0] Rd0 = fnRd(fetchbuf0_instr);
|
|
wire [7:0] Ra1 = fnRa(fetchbuf1_instr);
|
|
wire [7:0] Rb1 = fnRb(fetchbuf1_instr);
|
|
wire [7:0] Rc1 = fnRc(fetchbuf1_instr);
|
|
wire [7:0] Rd1 = fnRd(fetchbuf1_instr);
|
|
wire [7:0] Rt0 = fnTargetReg(fetchbuf0_instr);
|
|
wire [7:0] Rt1 = fnTargetReg(fetchbuf1_instr);
|
|
assign pRc0 = Rc0;
|
|
assign pRd0 = Rd0;
|
|
assign pRc1 = Rc1;
|
|
assign pRd1 = Rd1;
|
|
|
wire [6:0] Ra0 = fnRa(fetchbuf0_instr);
|
|
wire [6:0] Rb0 = fnRb(fetchbuf0_instr);
|
|
wire [6:0] Rc0 = fnRc(fetchbuf0_instr);
|
|
wire [6:0] Ra1 = fnRa(fetchbuf1_instr);
|
|
wire [6:0] Rb1 = fnRb(fetchbuf1_instr);
|
|
wire [6:0] Rc1 = fnRc(fetchbuf1_instr);
|
|
wire [6:0] Rt0 = fnTargetReg(fetchbuf0_instr);
|
|
wire [6:0] Rt1 = fnTargetReg(fetchbuf1_instr);
|
|
always @*
|
always @*
|
begin
|
begin
|
pRt0 = Rt0;
|
pRt0 = Rt0;
|
pRt1 = Rt1;
|
pRt1 = Rt1;
|
rfot0 = prfot0;
|
rfot0 = prfot0;
|
rfot1 = prfot1;
|
rfot1 = prfot1;
|
case(fetchbuf0_v ? fnNumReadPorts(fetchbuf0_instr) : 2'd0)
|
case(fetchbuf0_v ? fnNumReadPorts(fetchbuf0_instr) : 2'd0)
|
2'd0: begin
|
3'd0: begin
|
pRa0 = 7'd0;
|
pRa0 = 8'd0;
|
pRb0 = Rc1;
|
pRb0 = Rc1;
|
pRa1 = Ra1;
|
pRa1 = Ra1;
|
pRb1 = Rb1;
|
pRb1 = Rb1;
|
rfoa0 = 64'd0;
|
rfoa0 = 64'd0;
|
rfob0 = 64'd0;
|
rfob0 = 64'd0;
|
Line 900... |
Line 948... |
rfoa1 = prfoa1;
|
rfoa1 = prfoa1;
|
rfob1 = prfob1;
|
rfob1 = prfob1;
|
rfoc1 = prfob0;
|
rfoc1 = prfob0;
|
ports_avail = 2'd3;
|
ports_avail = 2'd3;
|
end
|
end
|
2'd1: begin
|
3'd1: begin
|
pRa0 = Ra0;
|
pRa0 = Ra0;
|
pRb0 = Rc1;
|
pRb0 = Rc1;
|
pRa1 = Ra1;
|
pRa1 = Ra1;
|
pRb1 = Rb1;
|
pRb1 = Rb1;
|
rfoa0 = prfoa0;
|
rfoa0 = prfoa0;
|
Line 913... |
Line 961... |
rfoa1 = prfoa1;
|
rfoa1 = prfoa1;
|
rfob1 = prfob1;
|
rfob1 = prfob1;
|
rfoc1 = prfob0;
|
rfoc1 = prfob0;
|
ports_avail = 2'd3;
|
ports_avail = 2'd3;
|
end
|
end
|
2'd2: begin
|
3'd2: begin
|
pRa0 = Ra0;
|
pRa0 = Ra0;
|
pRb0 = Rb0;
|
pRb0 = Rb0;
|
pRa1 = Ra1;
|
pRa1 = Ra1;
|
pRb1 = Rb1;
|
pRb1 = Rb1;
|
rfoa0 = prfoa0;
|
rfoa0 = prfoa0;
|
Line 926... |
Line 974... |
rfoa1 = prfoa1;
|
rfoa1 = prfoa1;
|
rfob1 = prfob1;
|
rfob1 = prfob1;
|
rfoc1 = 64'd0;
|
rfoc1 = 64'd0;
|
ports_avail = 2'd2;
|
ports_avail = 2'd2;
|
end
|
end
|
2'd3: begin
|
3'd3: begin
|
pRa0 = Ra0;
|
pRa0 = Ra0;
|
pRb0 = Rb0;
|
pRb0 = Rb0;
|
pRa1 = Rc0;
|
pRa1 = Rc0;
|
pRb1 = Ra1;
|
pRb1 = Ra1;
|
rfoa0 = prfoa0;
|
rfoa0 = prfoa0;
|
Line 939... |
Line 987... |
rfoa1 = prfob1;
|
rfoa1 = prfob1;
|
rfob1 = 64'd0;
|
rfob1 = 64'd0;
|
rfoc1 = 64'd0;
|
rfoc1 = 64'd0;
|
ports_avail = 2'd1;
|
ports_avail = 2'd1;
|
end
|
end
|
|
default: begin
|
|
pRa0 = 8'd0;
|
|
pRb0 = Rc1;
|
|
pRa1 = Ra1;
|
|
pRb1 = Rb1;
|
|
rfoa0 = 64'd0;
|
|
rfob0 = 64'd0;
|
|
rfoc0 = 64'd0;
|
|
rfoa1 = prfoa1;
|
|
rfob1 = prfob1;
|
|
rfoc1 = prfob0;
|
|
ports_avail = 2'd3;
|
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
/*
|
/*
|
wire [8:0] Rb0 = ((fnNumReadPorts(fetchbuf0_instr) < 3'd2) || !fetchbuf0_v) ? {1'b0,fetchbuf1_instr[`INSTRUCTION_RC]} :
|
wire [8:0] Rb0 = ((fnNumReadPorts(fetchbuf0_instr) < 3'd2) || !fetchbuf0_v) ? {1'b0,fetchbuf1_instr[`INSTRUCTION_RC]} :
|
Line 960... |
Line 1021... |
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];
|
wire [3:0] cond1 = fetchbuf1_instr[3:0];
|
wire [3:0] cond1 = fetchbuf1_instr[3:0];
|
wire [3:0] Pn0 = fetchbuf0_instr[7:4];
|
wire [3:0] Pn0 = fetchbuf0_instr[7:4];
|
wire [3:0] Pt0 = fetchbuf0_instr[11:8];
|
|
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 [6:0] r27 = 7'd27 + mode;
|
wire [6:0] r27 = 7'd27 + mode;
|
|
|
function [6:0] fnRa;
|
function [7:0] fnRa;
|
input [63:0] isn;
|
input [63:0] isn;
|
case(isn[15:8])
|
case(isn[15:8])
|
`RTS2: fnRa = 7'h51;
|
`RTF,`JSF: fnRa = 8'h5C; // cregs[12]
|
`RTI: fnRa = 7'h5E;
|
`RTS2: fnRa = 8'h51;
|
`RTD: fnRa = 7'h5B;
|
`RTI: fnRa = 8'h5E;
|
`RTE: fnRa = 7'h5D;
|
`RTD: fnRa = 8'h5B;
|
|
`RTE: fnRa = 8'h5D;
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS:
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`RTS:
|
fnRa = {3'h5,isn[23:20]};
|
fnRa = {4'h5,isn[23:20]};
|
`TLB: fnRa = {1'b0,isn[29:24]};
|
`TLB: fnRa = {4'b0,isn[29:24]};
|
`P: fnRa = 7'h70;
|
`P: fnRa = 8'h70;
|
`LOOP: fnRa = 7'h73;
|
`LOOP: fnRa = 8'h73;
|
`PUSH: fnRa = r27;
|
`PUSH: fnRa = r27;
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
`PEA,`POP,`LINK: fnRa = r27;
|
`PEA,`POP,`LINK: fnRa = r27;
|
`endif
|
`endif
|
`MFSPR,`MOVS:
|
`MFSPR,`MOVS:
|
if (isn[`INSTRUCTION_RA]==`USP)
|
if (isn[`INSTRUCTION_RA]==`USP)
|
fnRa = 7'd27;
|
fnRa = 8'd27;
|
else
|
else
|
fnRa = {1'b1,isn[`INSTRUCTION_RA]};
|
fnRa = {4'd1,isn[`INSTRUCTION_RA]};
|
default:
|
default:
|
if (isn[`INSTRUCTION_RA]==6'd27)
|
if (isn[`INSTRUCTION_RA]==6'd27)
|
fnRa = r27;
|
fnRa = r27;
|
else
|
else
|
fnRa = {1'b0,isn[`INSTRUCTION_RA]};
|
fnRa = {4'b0,isn[`INSTRUCTION_RA]};
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function [6:0] fnRb;
|
function [7:0] fnRb;
|
input [63:0] isn;
|
input [63:0] isn;
|
case(isn[15:8])
|
case(isn[15:8])
|
// `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:
|
Line 1011... |
Line 1071... |
`PUSH: fnRb = isn[22:16];
|
`PUSH: fnRb = isn[22:16];
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
`LINK: fnRb = {1'b0,isn[27:22]};
|
`LINK: fnRb = {1'b0,isn[27:22]};
|
`PEA: fnRb = {1'b0,isn[21:16]};
|
`PEA: fnRb = {1'b0,isn[21:16]};
|
`endif
|
`endif
|
|
`ifdef VECTOROPS
|
|
`VR:
|
|
case(isn[39:34])
|
|
`VBITS2V: fnRb = {4'd0,isn[25:22]};
|
|
`VEINS: fnRb = {4'd0,isn[25:22]};
|
|
default: fnRb = {1'b1,vele,isn[25:22]};
|
|
endcase
|
|
`VRR:
|
|
case(isn[47:43])
|
|
`VSCALE: fnRb = {4'd0,isn[25:22]};
|
|
`VSCALEL: fnRb = {4'd0,isn[25:22]};
|
|
default: fnRb = {1'b1,vele,isn[25:22]};
|
|
endcase
|
|
`endif
|
default:
|
default:
|
if (isn[`INSTRUCTION_RB]==6'd27)
|
if (isn[`INSTRUCTION_RB]==6'd27)
|
fnRb = r27;
|
fnRb = r27;
|
else
|
else
|
fnRb = {1'b0,isn[`INSTRUCTION_RB]};
|
fnRb = {1'b0,isn[`INSTRUCTION_RB]};
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
function [6:0] fnRc;
|
function [7:0] fnRc;
|
input [63:0] isn;
|
input [63:0] isn;
|
if (isn[`INSTRUCTION_RC]==6'd27)
|
case(isn[15:8])
|
|
`VRR,`VMAC:
|
|
fnRc = {1'b1,vele,isn[37:34]};
|
|
default:
|
|
if (isn[39:34]==6'd27)
|
fnRc = r27;
|
fnRc = r27;
|
else
|
else
|
fnRc = {1'b0,isn[`INSTRUCTION_RC]};
|
fnRc = {4'b0,isn[`INSTRUCTION_RC]};
|
|
endcase
|
|
|
|
endfunction
|
|
|
|
function [7:0] fnRd;
|
|
input [63:0] isn;
|
|
fnRd = {1'b1,vele,isn[43:40]};
|
endfunction
|
endfunction
|
|
|
function [3:0] fnCar;
|
function [3:0] fnCar;
|
input [63:0] isn;
|
input [63:0] isn;
|
case(isn[15:8])
|
case(isn[15:8])
|
Line 1087... |
Line 1172... |
`RTS: fnFunc = isn[19:16]; // used to pass a small immediate
|
`RTS: fnFunc = isn[19:16]; // used to pass a small immediate
|
`CACHE: fnFunc = isn[31:26];
|
`CACHE: fnFunc = isn[31:26];
|
`PUSH,`PEA: fnFunc = km ? 6'b0 : 6'b110000; // select segment register #6
|
`PUSH,`PEA: fnFunc = km ? 6'b0 : 6'b110000; // select segment register #6
|
`JMPI: fnFunc = {isn[39:37],1'b0,isn[27:26]};
|
`JMPI: fnFunc = {isn[39:37],1'b0,isn[27:26]};
|
`JMPIX: fnFunc = {isn[39:37],1'b0,isn[33:32]};
|
`JMPIX: fnFunc = {isn[39:37],1'b0,isn[33:32]};
|
|
`MTSPR: fnFunc = isn[31:28];
|
|
`ifdef VECTOROPS
|
|
`VRR: fnFunc = isn[47:43];
|
|
`VR: fnFunc = isn[39:34];
|
|
`endif
|
default:
|
default:
|
fnFunc = isn[39:34];
|
fnFunc = isn[39:34];
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
|
function fnVelv;
|
|
input [63:0] isn;
|
|
case(isn[15:8])
|
|
`VR:
|
|
case(isn[39:34])
|
|
6'd0: fnVelv = `FALSE;
|
|
default: fnVelv = `TRUE;
|
|
endcase
|
|
default: fnVelv = `TRUE;
|
|
endcase
|
|
endfunction
|
|
|
|
function fnVecL;
|
|
input [63:0] isn;
|
|
case(isn[15:8])
|
|
`VRR: fnVecL = isn[47];
|
|
`VR: fnVecL = isn[39];
|
|
`VMAC: fnVecL = isn[55];
|
|
default: fnVecL = 1'b0;
|
|
endcase
|
|
endfunction
|
|
|
// Returns true if the operation is limited to ALU #0
|
// Returns true if the operation is limited to ALU #0
|
function fnIsAlu0Op;
|
function fnIsAlu0Op;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
input [5:0] func;
|
input [5:0] func;
|
case(opcode)
|
case(opcode)
|
Line 1106... |
Line 1218... |
default: fnIsAlu0Op = `FALSE;
|
default: fnIsAlu0Op = `FALSE;
|
endcase
|
endcase
|
`R2: fnIsAlu0Op = `TRUE;
|
`R2: fnIsAlu0Op = `TRUE;
|
`RR:
|
`RR:
|
case(func)
|
case(func)
|
|
`MUL,`MULU: fnIsAlu0Op = `TRUE;
|
`DIV,`DIVU: fnIsAlu0Op = `TRUE;
|
`DIV,`DIVU: fnIsAlu0Op = `TRUE;
|
`MOD,`MODU: 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;
|
|
`MULI,`MULUI: fnIsAlu0Op = `TRUE;
|
`DIVI,`DIVUI: fnIsAlu0Op = `TRUE;
|
`DIVI,`DIVUI: fnIsAlu0Op = `TRUE;
|
`MODI,`MODUI: fnIsAlu0Op = `TRUE;
|
`MODI,`MODUI: fnIsAlu0Op = `TRUE;
|
//`DOUBLE: fnIsAlu0Op = `TRUE;
|
//`DOUBLE: fnIsAlu0Op = `TRUE;
|
`SHIFT: fnIsAlu0Op = `TRUE;
|
`SHIFT: fnIsAlu0Op = `TRUE;
|
`BITFIELD: fnIsAlu0Op = `TRUE;
|
`BITFIELD: fnIsAlu0Op = `TRUE;
|
Line 1141... |
Line 1255... |
endfunction
|
endfunction
|
|
|
Thor_regfile2w6r #(DBW) urf1
|
Thor_regfile2w6r #(DBW) urf1
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
|
.clk2x(clk2x_i),
|
.rclk(~clk),
|
.rclk(~clk),
|
.wr0(commit0_v && ~commit0_tgt[6]),
|
.regset(regset),
|
.wr1(commit1_v && ~commit1_tgt[6]),
|
.wr0(commit0_v && commit0_tgt[7:6]==2'h0),
|
|
.wr1(commit1_v && commit1_tgt[7:6]==2'h0),
|
.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 1162... |
Line 1278... |
.o3(prfob1),
|
.o3(prfob1),
|
.o4(prfot0),
|
.o4(prfot0),
|
.o5(prfot1)
|
.o5(prfot1)
|
);
|
);
|
|
|
|
`ifdef VECTOROPS
|
|
Thor_vregfile2w6r #(DBW) uvrf1
|
|
(
|
|
.clk(clk),
|
|
.rclk(~clk),
|
|
.wr0(commit0_v && commit0_tgt[7]),
|
|
.wr1(commit1_v && commit1_tgt[7]),
|
|
.wa0(commit0_tgt[6:0]),
|
|
.wa1(commit1_tgt[6:0]),
|
|
.ra0(pRb0[6:0]),
|
|
.ra1(pRc0[6:0]),
|
|
.ra2(pRd0[6:0]),
|
|
.ra3(pRb1[6:0]),
|
|
.ra4(pRc1[6:0]),
|
|
.ra5(pRd1[6:0]),
|
|
.ra6(pRt0[6:0]),
|
|
.ra7(pRt1[6:0]),
|
|
.i0(commit0_bus),
|
|
.i1(commit1_bus),
|
|
.o0(pvrfoa0),
|
|
.o1(pvrfob0),
|
|
.o2(pvrfoc0),
|
|
.o3(pvrfoa1),
|
|
.o4(pvrfob1),
|
|
.o5(pvrfoc1),
|
|
.o6(vrfot0),
|
|
.o7(vrfot1)
|
|
);
|
|
`endif
|
|
|
wire [63:0] cregs0 = fnCar(fetchbuf0_instr)==4'd0 ? 64'd0 : fnCar(fetchbuf0_instr)==4'hF ? fetchbuf0_pc : cregs[fnCar(fetchbuf0_instr)];
|
wire [63:0] cregs0 = fnCar(fetchbuf0_instr)==4'd0 ? 64'd0 : fnCar(fetchbuf0_instr)==4'hF ? fetchbuf0_pc : cregs[fnCar(fetchbuf0_instr)];
|
wire [63:0] cregs1 = fnCar(fetchbuf1_instr)==4'd0 ? 64'd0 : fnCar(fetchbuf1_instr)==4'hF ? fetchbuf1_pc : cregs[fnCar(fetchbuf1_instr)];
|
wire [63:0] cregs1 = fnCar(fetchbuf1_instr)==4'd0 ? 64'd0 : fnCar(fetchbuf1_instr)==4'hF ? fetchbuf1_pc : cregs[fnCar(fetchbuf1_instr)];
|
//
|
//
|
// 1 if the the operand is automatically valid,
|
// 1 if the the operand is automatically valid,
|
// 0 if we need a RF value
|
// 0 if we need a RF value
|
function fnSource1_v;
|
function fnSource1_v;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
case(opcode)
|
case(opcode)
|
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`STP:
|
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`STP,`RTF,`JSF:
|
fnSource1_v = 1'b1;
|
fnSource1_v = 1'b1;
|
`LDI,`LDIS,`IMM: fnSource1_v = 1'b1;
|
`LDI,`LDIS,`IMM: fnSource1_v = 1'b1;
|
default:
|
default:
|
case(opcode[7:4])
|
case(opcode[7:4])
|
`BR: fnSource1_v = 1'b1;
|
`BR: fnSource1_v = 1'b1;
|
Line 1263... |
Line 1409... |
fnSource2_v = `FALSE;
|
fnSource2_v = `FALSE;
|
`CACHE,`LCL,`TLB,`LLA,
|
`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,`RTS2:
|
`JSR,`JSRS,`JSRZ,`JSF,`SYS,`INT,`RTS,`RTS2,`RTF:
|
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 1289... |
Line 1435... |
input [7:0] opcode;
|
input [7:0] opcode;
|
input [5:0] func;
|
input [5:0] func;
|
case(opcode)
|
case(opcode)
|
`RR:
|
`RR:
|
case(func)
|
case(func)
|
`CHK: fnSource3_v = 1'b0;
|
`CHK,`CHKX: fnSource3_v = 1'b0;
|
default: fnSource3_v = 1'b1;
|
default: fnSource3_v = 1'b1;
|
endcase
|
endcase
|
`SBX,`SCX,`SHX,`SWX,`CAS,`STMV,`STCMP,`STFND: fnSource3_v = 1'b0;
|
`SBX,`SCX,`SHX,`SWX,`CAS,`STMV,`STCMP,`STFND: fnSource3_v = 1'b0;
|
`MUX: fnSource3_v = 1'b0;
|
`MUX: fnSource3_v = 1'b0;
|
default: fnSource3_v = 1'b1;
|
default: fnSource3_v = 1'b1;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
|
// Source #4 valid
|
|
// Since most instructions don't use a fourth source the default it to return
|
|
// a valid status.
|
|
// 1 if the the operand is automatically valid,
|
|
// 0 if we need a RF value
|
|
function fnSource4_v;
|
|
input [7:0] opcode;
|
|
input [5:0] func;
|
|
case(opcode)
|
|
`VMAC: fnSource4_v = 1'b0;
|
|
default: fnSource4_v = 1'b1;
|
|
endcase
|
|
endfunction
|
|
|
function fnSourceT_v;
|
function fnSourceT_v;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
input [5:0] func;
|
input [5:0] func;
|
case(opcode)
|
case(opcode)
|
`RR:
|
`RR:
|
case(func)
|
case(func)
|
`CHK: fnSourceT_v = 1'b1;
|
`CHK,`CHKX: fnSourceT_v = 1'b1;
|
default: fnSourceT_v = 1'b0;
|
default: fnSourceT_v = 1'b0;
|
endcase
|
endcase
|
// BR
|
// BR
|
8'h30,8'h31,8'h32,8'h33,
|
8'h30,8'h31,8'h32,8'h33,
|
8'h34,8'h35,8'h36,8'h37,
|
8'h34,8'h35,8'h36,8'h37,
|
8'h38,8'h39,8'h3A,8'h3B,
|
8'h38,8'h39,8'h3A,8'h3B,
|
8'h3C,8'h3D,8'h3E,8'h3F,
|
8'h3C,8'h3D,8'h3E,8'h3F,
|
`SB,`SC,`SH,`SW,`SBX,`SCX,`SHX,`SWX,`SWS,
|
`SB,`SC,`SH,`SW,`SBX,`SCX,`SHX,`SWX,`SWS,`SV,`SVWS,`SVX,
|
`CACHE,`CHKI,
|
`CACHE,`CHKI,`CHKXI,
|
`SEI,`CLI,`NOP,`STP,`RTI,`RTD,`RTE,
|
`SEI,`CLI,`NOP,`STP,`RTI,`RTD,`RTE,
|
`MEMSB,`MEMDB,`SYNC:
|
`MEMSB,`MEMDB,`SYNC:
|
fnSourceT_v = 1'b1;
|
fnSourceT_v = 1'b1;
|
default: fnSourceT_v = 1'b0;
|
default: fnSourceT_v = 1'b0;
|
endcase
|
endcase
|
Line 1329... |
Line 1489... |
case(fnOpcode(ins))
|
case(fnOpcode(ins))
|
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`MOVS,`STP:
|
`SEI,`CLI,`MEMSB,`MEMDB,`SYNC,`NOP,`MOVS,`STP:
|
fnNumReadPorts = 3'd0;
|
fnNumReadPorts = 3'd0;
|
`LDI,`LDIS,`IMM: fnNumReadPorts = 3'd0;
|
`LDI,`LDIS,`IMM: fnNumReadPorts = 3'd0;
|
`R,`P,`STI,`LOOP,`JMPI: fnNumReadPorts = 3'd1;
|
`R,`P,`STI,`LOOP,`JMPI: fnNumReadPorts = 3'd1;
|
`RTI,`RTD,`RTE: fnNumReadPorts = 3'd1;
|
`RTI,`RTD,`RTE,`RTF,`JSF: fnNumReadPorts = 3'd1;
|
`ADDI,`ADDUI,`ADDUIS:
|
`ADDI,`ADDUI,`ADDUIS:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI:
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI:
|
fnNumReadPorts = 3'd1;
|
fnNumReadPorts = 3'd1;
|
`SUBI,`SUBUI: fnNumReadPorts = 3'd1;
|
`SUBI,`SUBUI: fnNumReadPorts = 3'd1;
|
Line 1356... |
Line 1516... |
fnNumReadPorts = 3'd3;
|
fnNumReadPorts = 3'd3;
|
`MTSPR,`MFSPR,`POP,`UNLINK: fnNumReadPorts = 3'd1;
|
`MTSPR,`MFSPR,`POP,`UNLINK: fnNumReadPorts = 3'd1;
|
`STFND: fnNumReadPorts = 3'd2; // *** TLB reads on Rb we say 2 for simplicity
|
`STFND: fnNumReadPorts = 3'd2; // *** TLB reads on Rb we say 2 for simplicity
|
`RR:
|
`RR:
|
case(ins[39:34])
|
case(ins[39:34])
|
`CHK: fnNumReadPorts = 3'd3;
|
`CHK,`CHKX: fnNumReadPorts = 3'd3;
|
default: fnNumReadPorts = 3'd2;
|
default: fnNumReadPorts = 3'd2;
|
endcase
|
endcase
|
`BITFIELD:
|
`BITFIELD:
|
case(ins[43:40])
|
case(ins[43:40])
|
`BFSET,`BFCLR,`BFCHG,`BFEXT,`BFEXTU,`BFINSI:
|
`BFSET,`BFCLR,`BFCHG,`BFEXT,`BFEXTU,`BFINSI:
|
Line 1623... |
Line 1783... |
// 70 = predicate register horizontal
|
// 70 = predicate register horizontal
|
// 73 = loop counter
|
// 73 = loop counter
|
// 7C = breakout index register
|
// 7C = breakout index register
|
// 7D = broken out register
|
// 7D = broken out register
|
// 7F = power shift register
|
// 7F = power shift register
|
function [6:0] fnTargetReg;
|
// 80 vector reg #0, element #0
|
|
// 81 vector reg #1, element #0
|
|
// ...
|
|
// 8F vector reg #15, element #0
|
|
// 90 vector reg #0, element #1
|
|
// ...
|
|
// FF vector reg #15, element #7
|
|
|
|
function [7:0] fnTargetReg;
|
input [63:0] ir;
|
input [63:0] ir;
|
begin
|
begin
|
// Process special predicates (NOP, IMM)
|
// Process special predicates (NOP, IMM)
|
// Note that BRK (00) is already translated to a SYS instruction
|
// Note that BRK (00) is already translated to a SYS instruction
|
if (ir[3:0]==4'h0)
|
if (ir[3:0]==4'h0)
|
fnTargetReg = 7'h000;
|
fnTargetReg = 10'h000;
|
else
|
else
|
case(fnOpcode(ir))
|
case(fnOpcode(ir))
|
|
`ifdef VECTOROPS
|
|
`VR:
|
|
case(ir[39:34])
|
|
`VEX: fnTargetReg = {5'h0,ir[30:28]};
|
|
default: fnTargetReg = {1'b1,vele,ir[30:28]};
|
|
endcase
|
|
`LV: fnTargetReg = {1'b1,vele,ir[24:22]};
|
|
`LVWS,`LVX: fnTargetReg = {1'b1,vele,ir[30:28]};
|
|
`VLOG,`VADDSUB,`VMULDIV: fnTargetReg = {1'b1,vele,ir[30:28]};
|
|
// ToDo: assign register range for vector predicates
|
|
// `VCMPS:
|
|
`VMAC: fnTargetReg = {1'b1,vele,ir[43:40]};
|
|
`endif
|
`POP: fnTargetReg = ir[22:16];
|
`POP: fnTargetReg = ir[22:16];
|
`LDI,`ADDUIS,`STS,`LINK,`UNLINK:
|
`LDI,`ADDUIS,`STS,`LINK,`UNLINK:
|
if (ir[21:16]==6'd27)
|
if (ir[21:16]==6'd27)
|
fnTargetReg = r27;
|
fnTargetReg = r27;
|
else
|
else
|
fnTargetReg = {1'b0,ir[21:16]};
|
fnTargetReg = {4'b0,ir[21:16]};
|
`LDIS:
|
`LDIS:
|
fnTargetReg = {1'b1,ir[21:16]};
|
fnTargetReg = {4'd1,ir[21:16]};
|
`RR,
|
`RR,
|
`SHIFT,
|
`SHIFT,
|
`BCD,
|
`BCD,
|
`LOGIC,`FLOAT,
|
`LOGIC,`FLOAT,
|
`LWX,`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`STMV,`STCMP,`STFND:
|
`LWX,`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`STMV,`STCMP,`STFND:
|
if (ir[33:28]==6'd27)
|
if (ir[33:28]==6'd27)
|
fnTargetReg = r27;
|
fnTargetReg = r27;
|
else
|
else
|
fnTargetReg = {1'b0,ir[33:28]};
|
fnTargetReg = {4'b0,ir[33:28]};
|
`R,`R2,`DOUBLE_R,`SINGLE_R,
|
`R,`R2,`DOUBLE_R,`SINGLE_R,
|
`ADDI,`ADDUI,`SUBI,`SUBUI,
|
`ADDI,`ADDUI,`SUBI,`SUBUI,
|
`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI,
|
`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,
|
`ANDI,`ORI,`EORI,`LLA,
|
`ANDI,`ORI,`EORI,`LLA,
|
Line 1660... |
Line 1841... |
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LINK,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LINK,
|
`BITFIELD,`MFSPR:
|
`BITFIELD,`MFSPR:
|
if (ir[27:22]==6'd27)
|
if (ir[27:22]==6'd27)
|
fnTargetReg = r27;
|
fnTargetReg = r27;
|
else
|
else
|
fnTargetReg = {1'b0,ir[27:22]};
|
fnTargetReg = {4'b0,ir[27:22]};
|
`CAS:
|
`CAS:
|
fnTargetReg = {1'b0,ir[39:34]};
|
fnTargetReg = {4'b0,ir[39:34]};
|
`TLB:
|
`TLB:
|
if (ir[19:16]==`TLB_RDREG)
|
if (ir[19:16]==`TLB_RDREG)
|
fnTargetReg = {1'b0,ir[29:24]};
|
fnTargetReg = {4'b0,ir[29:24]};
|
else
|
else
|
fnTargetReg = 7'h00;
|
fnTargetReg = 10'h00;
|
`BITI:
|
`BITI:
|
fnTargetReg = {3'h4,ir[25:22]};
|
fnTargetReg = {6'h4,ir[25:22]};
|
|
`CHKI:
|
|
fnTargetReg = {6'h4,ir[43:40]};
|
// TST
|
// TST
|
8'h00,8'h01,8'h02,8'h03,
|
8'h00,8'h01,8'h02,8'h03,
|
8'h04,8'h05,8'h06,8'h07,
|
8'h04,8'h05,8'h06,8'h07,
|
8'h08,8'h09,8'h0A,8'h0B,
|
8'h08,8'h09,8'h0A,8'h0B,
|
8'h0C,8'h0D,8'h0E,8'h0F,
|
8'h0C,8'h0D,8'h0E,8'h0F,
|
Line 1686... |
Line 1869... |
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:
|
begin
|
begin
|
fnTargetReg = {3'h4,ir[11:8]};
|
fnTargetReg = {6'h4,ir[11:8]};
|
end
|
end
|
`SWCR: fnTargetReg = {3'h4,4'h0};
|
`SWCR: fnTargetReg = {6'h4,4'h0};
|
`JSR,`JSRZ,`JSRS,`SYS,`INT:
|
`JSR,`JSRZ,`JSRS,`SYS,`INT:
|
fnTargetReg = {3'h5,ir[19:16]};
|
fnTargetReg = {4'h5,ir[19:16]};
|
|
`JSF: fnTargetReg = 8'h51;
|
`JMPI:
|
`JMPI:
|
fnTargetReg = {3'h5,ir[25:22]};
|
fnTargetReg = {4'h5,ir[25:22]};
|
`JMPIX:
|
`JMPIX:
|
fnTargetReg = {3'h5,ir[31:28]};
|
fnTargetReg = {4'h5,ir[31:28]};
|
`MTSPR,`MOVS,`LWS:
|
`MTSPR,`MOVS,`LWS:
|
if (ir[27:22]==`USP)
|
if (ir[27:22]==`USP)
|
fnTargetReg = {1'b0,6'd27};
|
fnTargetReg = {4'b0,6'd27};
|
else
|
else
|
fnTargetReg = {1'b1,ir[27:22]};
|
fnTargetReg = {4'd1,ir[27:22]};
|
/*
|
/*
|
if (ir[27:26]==2'h1) // Move to code address register
|
if (ir[27:26]==2'h1) // Move to code address register
|
fnTargetReg = {3'h5,ir[25:22]};
|
fnTargetReg = {3'h5,ir[25:22]};
|
else if (ir[27:26]==2'h2) // Move to seg. reg.
|
else if (ir[27:26]==2'h2) // Move to seg. reg.
|
fnTargetReg = {3'h6,ir[25:22]};
|
fnTargetReg = {3'h6,ir[25:22]};
|
Line 1711... |
Line 1895... |
fnTargetReg = 7'h70;
|
fnTargetReg = 7'h70;
|
else
|
else
|
fnTargetReg = 7'h00;
|
fnTargetReg = 7'h00;
|
*/
|
*/
|
`PUSH: fnTargetReg = r27;
|
`PUSH: fnTargetReg = r27;
|
`LOOP: fnTargetReg = 7'h73;
|
`LOOP: fnTargetReg = 10'h73;
|
`STP: fnTargetReg = 7'h7F;
|
`STP: fnTargetReg = 10'h7F;
|
`P: fnTargetReg = 7'h70;
|
`P: fnTargetReg = 10'h70;
|
default: fnTargetReg = 7'h00;
|
default: fnTargetReg = 10'h00;
|
endcase
|
endcase
|
end
|
end
|
endfunction
|
endfunction
|
/*
|
/*
|
function fnAllowedReg;
|
function fnAllowedReg;
|
Line 1731... |
Line 1915... |
begin
|
begin
|
if (ir[3:0]==4'h0)
|
if (ir[3:0]==4'h0)
|
fnTargetsCa = `FALSE;
|
fnTargetsCa = `FALSE;
|
else begin
|
else begin
|
case(fnOpcode(ir))
|
case(fnOpcode(ir))
|
`JSR,`JSRZ,`JSRS,`SYS,`INT:
|
`JSR,`JSRZ,`JSRS,`JSF,`SYS,`INT:
|
fnTargetsCa = `TRUE;
|
fnTargetsCa = `TRUE;
|
`JMPI,`JMPIX:
|
`JMPI,`JMPIX:
|
fnTargetsCa = `TRUE;
|
fnTargetsCa = `TRUE;
|
`LWS:
|
`LWS:
|
if (ir[27:26]==2'h1)
|
if (ir[27:26]==2'h1)
|
Line 1765... |
Line 1949... |
if (ir[3:0]==4'h0)
|
if (ir[3:0]==4'h0)
|
fnTargetsSegreg = `FALSE;
|
fnTargetsSegreg = `FALSE;
|
else
|
else
|
case(fnOpcode(ir))
|
case(fnOpcode(ir))
|
`LWS:
|
`LWS:
|
if (ir[27:26]==2'h2)
|
if (ir[27:25]==3'h4)
|
fnTargetsSegreg = `TRUE;
|
fnTargetsSegreg = `TRUE;
|
else
|
else
|
fnTargetsSegreg = `FALSE;
|
fnTargetsSegreg = `FALSE;
|
`LDIS:
|
`LDIS:
|
if (ir[21:20]==2'h2)
|
if (ir[21:19]==3'h4)
|
fnTargetsSegreg = `TRUE;
|
fnTargetsSegreg = `TRUE;
|
else
|
else
|
fnTargetsSegreg = `FALSE;
|
fnTargetsSegreg = `FALSE;
|
`MTSPR,`MOVS:
|
`MTSPR,`MOVS:
|
if (ir[27:26]==2'h2)
|
if (ir[27:25]==3'h4)
|
fnTargetsSegreg = `TRUE;
|
fnTargetsSegreg = `TRUE;
|
else
|
else
|
fnTargetsSegreg = `FALSE;
|
fnTargetsSegreg = `FALSE;
|
default: fnTargetsSegreg = `FALSE;
|
default: fnTargetsSegreg = `FALSE;
|
endcase
|
endcase
|
Line 1789... |
Line 1973... |
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,`MODI,`MODUI,
|
`ADDI,`SUBI,`ADDUI,`SUBUI,`MULI,`MULUI,`DIVI,`DIVUI,`MODI,`MODUI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,`CHKI,
|
`_2ADDUI,`_4ADDUI,`_8ADDUI,`_16ADDUI,`CHKI,`CHKXI,
|
// 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,
|
Line 1805... |
Line 1989... |
`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,`LLA,
|
`RTI,`RTD,`RTE,`RTF,`JSF,`LLA,
|
`JSR,`JSRS,`SYS,`INT,`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
|
Line 1819... |
Line 2003... |
function fnIsFlowCtrl;
|
function fnIsFlowCtrl;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
begin
|
begin
|
case(opcode)
|
case(opcode)
|
`JMPI,`JMPIX,
|
`JMPI,`JMPIX,
|
`JSR,`JSRS,`JSRZ,`SYS,`INT,`LOOP,`RTS,`RTS2,`RTI,`RTD,`RTE:
|
`JSR,`JSRS,`JSRZ,`JSF,`SYS,`INT,`LOOP,`RTS,`RTF,`RTS2,`RTI,`RTD,`RTE:
|
fnIsFlowCtrl = 1'b1;
|
fnIsFlowCtrl = 1'b1;
|
default:
|
default:
|
if (opcode[7:4]==`BR)
|
if (opcode[7:4]==`BR)
|
fnIsFlowCtrl = 1'b1;
|
fnIsFlowCtrl = 1'b1;
|
else
|
else
|
Line 1857... |
Line 2041... |
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;
|
`ADDI,`SUBI,`DIVI,`MODI,`MULI,`CHKI:
|
`ADDI,`SUBI,`DIVI,`MODI,`MULI,`CHKXI:
|
fnCanException = `TRUE;
|
fnCanException = `TRUE;
|
`RR:
|
`RR:
|
if (func==`ADD || func==`SUB || func==`MUL || func==`DIV || func==`MOD || func==`CHK)
|
if (func==`ADD || func==`SUB || func==`MUL || func==`DIV || func==`MOD || func==`CHKX)
|
fnCanException = `TRUE;
|
fnCanException = `TRUE;
|
else
|
else
|
fnCanException = `FALSE;
|
fnCanException = `FALSE;
|
`TLB,`RTI,`RTD,`RTE,`CLI,`SEI:
|
`TLB,`RTI,`RTD,`RTE,`CLI,`SEI:
|
fnCanException = `TRUE;
|
fnCanException = `TRUE;
|
Line 1889... |
Line 2073... |
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;
|
default:
|
default:
|
case(isn[15:8])
|
case(isn[15:8])
|
`NOP,`SEI,`CLI,`RTI,`RTD,`RTE,`RTS2,`MEMSB,`MEMDB,`SYNC:
|
`NOP,`SEI,`CLI,`RTI,`RTD,`RTE,`RTS2,`RTF,`JSF,`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,`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,`CHKI:
|
fnInsnLength = 4'd6;
|
fnInsnLength = 4'd6;
|
|
`ifdef VECTOROPS
|
|
`LV,`SV: fnInsnLength = 4'd4;
|
|
`VMAC: fnInsnLength = 4'd6;
|
|
// Others are default 5
|
|
`endif
|
default:
|
default:
|
begin
|
begin
|
case(isn[15:12])
|
case(isn[15:12])
|
`TST: fnInsnLength = 4'd3;
|
`TST: fnInsnLength = 4'd3;
|
`BR: fnInsnLength = 4'd3;
|
`BR: fnInsnLength = 4'd3;
|
Line 1956... |
Line 2145... |
|
|
always @(fetchbuf or fetchbufA_instr or fetchbufA_v or fetchbufA_pc
|
always @(fetchbuf or fetchbufA_instr or fetchbufA_v or fetchbufA_pc
|
or fetchbufB_instr or fetchbufB_v or fetchbufB_pc
|
or fetchbufB_instr or fetchbufB_v or fetchbufB_pc
|
or fetchbufC_instr or fetchbufC_v or fetchbufC_pc
|
or fetchbufC_instr or fetchbufC_v or fetchbufC_pc
|
or fetchbufD_instr or fetchbufD_v or fetchbufD_pc
|
or fetchbufD_instr or fetchbufD_v or fetchbufD_pc
|
|
or int_pending or string_pc
|
)
|
)
|
begin
|
begin
|
fetchbuf0_instr <= (fetchbuf == 1'b0) ? fetchbufA_instr : fetchbufC_instr;
|
fetchbuf0_instr <= (fetchbuf == 1'b0) ? fetchbufA_instr : fetchbufC_instr;
|
fetchbuf0_v <= (fetchbuf == 1'b0) ? fetchbufA_v : fetchbufC_v ;
|
fetchbuf0_v <= (fetchbuf == 1'b0) ? fetchbufA_v : fetchbufC_v ;
|
|
|
Line 1986... |
Line 2176... |
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 ||
|
opcode==`SB || opcode==`SC || opcode==`SH || opcode==`SW ||
|
opcode==`SB || opcode==`SC || opcode==`SH || opcode==`SW ||
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX ||
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX ||
|
|
`ifdef VECTOROPS
|
|
opcode==`LV || opcode==`LVWS || opcode==`LVX ||
|
|
opcode==`SV || opcode==`SVWS || opcode==`SVX ||
|
|
`endif
|
opcode==`STS || opcode==`LCL ||
|
opcode==`STS || opcode==`LCL ||
|
opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
|
opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`SWCR ||
|
opcode==`TLB || opcode==`CAS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
|
opcode==`TLB || opcode==`CAS || opcode==`STMV || opcode==`STCMP || opcode==`STFND ||
|
opcode==`LWS || opcode==`SWS || opcode==`STI ||
|
opcode==`LWS || opcode==`SWS || opcode==`STI ||
|
opcode==`INC ||
|
opcode==`INC ||
|
opcode==`JMPI || opcode==`JMPIX ||
|
opcode==`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 fnIsVec;
|
|
input [7:0] opcode;
|
|
`ifdef VECTOROPS
|
|
fnIsVec = opcode==`VMAC || opcode==`VR || opcode==`VRR;// || opcode==`VLD || opcode==`VLDX || opcode==`VST || opcode==`VSTX;
|
|
`else
|
|
fnIsVec = `FALSE;
|
|
`endif
|
|
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
|
Line 2014... |
Line 2217... |
opcode==`ADDI || opcode==`SUBI || opcode==`ADDUI || opcode==`SUBUI ||
|
opcode==`ADDI || opcode==`SUBI || opcode==`ADDUI || opcode==`SUBUI ||
|
opcode==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI || opcode==`MODI || opcode==`MODUI ||
|
opcode==`MULI || opcode==`MULUI || opcode==`DIVI || opcode==`DIVUI || opcode==`MODI || opcode==`MODUI ||
|
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==`SHIFT || opcode==`LOGIC ||
|
opcode==`SHIFT || opcode==`LOGIC ||
|
opcode==`R || opcode==`R2 || opcode==`RR || opcode==`P || opcode==`LOOP ||
|
opcode==`R || opcode==`R2 || (opcode==`RR && (ir[39:34]!=`CHKX)) || opcode==`LOOP ||
|
opcode==`BITI || opcode==`CMP || opcode==`CMPI || opcode==`TST ||
|
opcode==`CHKI || opcode==`CMP || opcode==`CMPI || opcode==`TST ||
|
opcode==`LDI || opcode==`LDIS || opcode==`ADDUIS || opcode==`MFSPR ||
|
opcode==`LDI || opcode==`LDIS || opcode==`ADDUIS || opcode==`MFSPR ||
|
|
`ifdef VECTOROPS
|
|
opcode==`LV || opcode==`LVWS || opcode==`LVX ||
|
|
opcode==`VLOG || opcode==`VADDSUB | opcode==`VCMPS || opcode==`VMULDIV ||
|
|
opcode==`VMAC || opcode==`VR ||
|
|
`endif
|
`ifdef FLOATING_POINT
|
`ifdef FLOATING_POINT
|
opcode==`DOUBLE_R || opcode==`FLOAT_RR || opcode==`SINGLE_R ||
|
opcode==`DOUBLE_R || opcode==`FLOAT_RR || opcode==`SINGLE_R ||
|
`endif
|
`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==`JSF || opcode==`SYS || opcode==`INT ||
|
// predicate registers
|
// predicate registers
|
(opcode[7:4] < 4'h3) ||
|
(opcode[7:4] < 4'h3) || opcode==`P || opcode==`BITI ||
|
(opcode==`TLB && ir[19:16]==`TLB_RDREG) ||
|
(opcode==`TLB && ir[19:16]==`TLB_RDREG) ||
|
opcode==`BCD
|
opcode==`BCD
|
;
|
;
|
end
|
end
|
endfunction
|
endfunction
|
Line 2037... |
Line 2245... |
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsStore = opcode==`SB || opcode==`SC || opcode==`SH || opcode==`SW ||
|
fnIsStore = opcode==`SB || opcode==`SC || opcode==`SH || opcode==`SW ||
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX ||
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX ||
|
opcode==`STS || opcode==`SWCR ||
|
opcode==`STS || opcode==`SWCR ||
|
opcode==`SWS || opcode==`STI ||
|
opcode==`SWS || opcode==`STI ||
|
|
opcode==`SV || opcode==`SVWS || opcode==`SVX ||
|
opcode==`PUSH || opcode==`PEA || opcode==`LINK;
|
opcode==`PUSH || opcode==`PEA || opcode==`LINK;
|
endfunction
|
endfunction
|
|
|
function fnIsLoad;
|
function fnIsLoad;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsLoad = opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
|
fnIsLoad = opcode==`LB || opcode==`LBU || opcode==`LC || opcode==`LCU || opcode==`LH || opcode==`LHU || opcode==`LW ||
|
opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`LCL ||
|
opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`LCL ||
|
opcode==`LWS || opcode==`UNLINK || opcode==`JMPI || opcode==`JMPIX ||
|
opcode==`LWS || opcode==`UNLINK || opcode==`JMPI || opcode==`JMPIX ||
|
|
opcode==`LV || opcode==`LVWS || opcode==`LVX ||
|
opcode==`POP;
|
opcode==`POP;
|
endfunction
|
endfunction
|
|
|
function fnIsLoadV;
|
function fnIsLoadV;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsLoadV = opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`LCL;
|
fnIsLoadV = opcode==`LVB || opcode==`LVC || opcode==`LVH || opcode==`LVW || opcode==`LVWAR || opcode==`LCL ||
|
|
opcode==`LV || opcode==`LVWS || opcode==`LVX;
|
endfunction
|
endfunction
|
|
|
function fnIsIndexed;
|
function fnIsIndexed;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
fnIsIndexed = opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
fnIsIndexed = opcode==`LBX || opcode==`LBUX || opcode==`LCX || opcode==`LCUX || opcode==`LHX || opcode==`LHUX || opcode==`LWX ||
|
|
opcode==`LVX || opcode==`SVX ||
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX || opcode==`JMPIX;
|
opcode==`SBX || opcode==`SCX || opcode==`SHX || opcode==`SWX || opcode==`JMPIX;
|
endfunction
|
endfunction
|
|
|
//
|
//
|
function fnIsPFW;
|
function fnIsPFW;
|
Line 2070... |
Line 2282... |
|
|
// Decoding for illegal opcodes
|
// Decoding for illegal opcodes
|
function fnIsIllegal;
|
function fnIsIllegal;
|
input [7:0] op;
|
input [7:0] op;
|
input [5:0] fn;
|
input [5:0] fn;
|
|
if (`TRUE)
|
|
fnIsIllegal = `FALSE;
|
|
else
|
casex(op)
|
casex(op)
|
8'h40:
|
8'h40:
|
if (fn > 6'h17)
|
if (fn > 6'h17)
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
else if (fn==6'hC || fn==6'hD || fn==6'hE || fn==6'hF || fn==6'h12 || fn==6'h15 || fn==6'h16)
|
else if (fn==6'hC || fn==6'hD || fn==6'hE || fn==6'hF || fn==6'h12 || 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 2116... |
Line 2331... |
8'hF5:
|
8'hF5:
|
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: fnIsIllegal = `TRUE;
|
8'h52,8'h56,8'h57,8'h59,8'h5A,8'h5C,8'h5E:
|
`ifndef VECTOROPS
|
|
8'h52,8'h56,8'h57,8'h5A,8'h5C,8'h5E,8'hCD,8'hCE,8'hCF,8'hBD,8'hBE,8'hBF:
|
|
fnIsIllegal = `TRUE;
|
|
`endif
|
|
8'h59:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'h60,8'h61,8'h62,8'h63,8'h64,8'h65,8'h66,8'h67,8'h68,8'h69:
|
8'h60,8'h61,8'h62,8'h63,8'h64,8'h65,8'h66,8'h67,8'h68,8'h69:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'h73,8'h74,8'h75,8'h76,8'h7A,8'h7B,8'h7C,8'h7D,8'h7E,8'h7F:
|
8'h73,8'h74,8'h75,8'h76,8'h7A,8'h7B,8'h7C,8'h7D,8'h7E,8'h7F:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'h87,8'h88,8'h89,8'h8A:
|
8'h87,8'h88,8'h8A:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'h94,8'h95,8'h9C:
|
8'h94,8'h95,8'h9C:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'hB9,8'hBA,8'hBB,8'hBC,8'hBD,8'hBE,8'hBF:
|
8'hBA,8'hBB,8'hBC:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'hC4,8'hC5,8'b11001xxx:
|
8'hC8,8'hC9,8'hCA,8'hCB,8'hCD:
|
fnIsIllegal = `TRUE;
|
fnIsIllegal = `TRUE;
|
8'hDx: fnIsIllegal = `TRUE;
|
8'hDx: fnIsIllegal = `TRUE;
|
8'hEx: fnIsIllegal = `TRUE;
|
8'hEx: fnIsIllegal = `TRUE;
|
8'hFD,8'hFE: fnIsIllegal = `TRUE;
|
8'hFD,8'hFE: fnIsIllegal = `TRUE;
|
default: fnIsIllegal = `FALSE;
|
default: fnIsIllegal = `FALSE;
|
Line 2189... |
Line 2408... |
1'd1: fnSelect = 8'hCC;
|
1'd1: fnSelect = 8'hCC;
|
endcase
|
endcase
|
`LH,`LHU,`SH,`LVH,`LHX,`LHUX,`SHX:
|
`LH,`LHU,`SH,`LVH,`LHX,`LHUX,`SHX:
|
fnSelect = 8'hFF;
|
fnSelect = 8'hFF;
|
`LW,`LWX,`SW,`SWCR,`LVW,`LVWAR,`SWX,`CAS,`LWS,`SWS,`STI,`LCL,
|
`LW,`LWX,`SW,`SWCR,`LVW,`LVWAR,`SWX,`CAS,`LWS,`SWS,`STI,`LCL,
|
|
`LV,`LVWS,`LVX,`SV,`SVWS,`SVX,
|
`PUSH,`PEA,`POP,`LINK,`UNLINK:
|
`PUSH,`PEA,`POP,`LINK,`UNLINK:
|
fnSelect = 8'hFF;
|
fnSelect = 8'hFF;
|
default: fnSelect = 8'h00;
|
default: fnSelect = 8'h00;
|
endcase
|
endcase
|
else
|
else
|
Line 2265... |
Line 2485... |
case(adr[2])
|
case(adr[2])
|
1'b0: fnSelect = 8'h0F;
|
1'b0: fnSelect = 8'h0F;
|
1'b1: fnSelect = 8'hF0;
|
1'b1: fnSelect = 8'hF0;
|
endcase
|
endcase
|
`LW,`LWX,`SW,`SWCR,`LVW,`LVWAR,`SWX,`CAS,`LWS,`SWS,`STI,`LCL,
|
`LW,`LWX,`SW,`SWCR,`LVW,`LVWAR,`SWX,`CAS,`LWS,`SWS,`STI,`LCL,
|
|
`LV,`LVWS,`LVX,`SV,`SVWS,`SVX,
|
`PUSH,`PEA,`POP,`LINK,`UNLINK:
|
`PUSH,`PEA,`POP,`LINK,`UNLINK:
|
fnSelect = 8'hFF;
|
fnSelect = 8'hFF;
|
default: fnSelect = 8'h00;
|
default: fnSelect = 8'h00;
|
endcase
|
endcase
|
end
|
end
|
Line 2338... |
Line 2559... |
case(sel[3:0])
|
case(sel[3:0])
|
4'h3: fnDatai = dat[15:0];
|
4'h3: fnDatai = dat[15:0];
|
4'hC: fnDatai = dat[31:16];
|
4'hC: fnDatai = dat[31:16];
|
default: fnDatai = {DBW{1'b1}};
|
default: fnDatai = {DBW{1'b1}};
|
endcase
|
endcase
|
`LH,`LHU,`LW,`LWX,`LVH,`LVW,`LVWAR,`LHX,`LHUX,`CAS,`LCL,`LWS,`POP,`UNLINK:
|
`LH,`LHU,`LW,`LWX,`LVH,`LVW,`LVWAR,`LHX,`LHUX,
|
|
`LV,`LVWS,`LVX,
|
|
`CAS,`LCL,`LWS,`POP,`UNLINK:
|
fnDatai = dat[31:0];
|
fnDatai = dat[31:0];
|
default: fnDatai = {DBW{1'b1}};
|
default: fnDatai = {DBW{1'b1}};
|
endcase
|
endcase
|
else
|
else
|
case(opcode)
|
case(opcode)
|
Line 2445... |
Line 2668... |
case(sel)
|
case(sel)
|
8'h0F: fnDatai = dat[DBW/2-1:0];
|
8'h0F: fnDatai = dat[DBW/2-1:0];
|
8'hF0: fnDatai = dat[DBW-1:DBW/2];
|
8'hF0: fnDatai = dat[DBW-1:DBW/2];
|
default: fnDatai = {DBW{1'b1}};
|
default: fnDatai = {DBW{1'b1}};
|
endcase
|
endcase
|
`LW,`LWX,`LVW,`LVWAR,`CAS,`LCL,`LWS,`POP,`UNLINK:
|
`LW,`LWX,`LVW,`LVWAR,
|
|
`LV,`LVWS,`LVX,
|
|
`CAS,`LCL,`LWS,`POP,`UNLINK:
|
case(sel)
|
case(sel)
|
8'hFF: fnDatai = dat;
|
8'hFF: fnDatai = dat;
|
default: fnDatai = {DBW{1'b1}};
|
default: fnDatai = {DBW{1'b1}};
|
endcase
|
endcase
|
default: fnDatai = {DBW{1'b1}};
|
default: fnDatai = {DBW{1'b1}};
|
Line 2467... |
Line 2692... |
case(func[2:0])
|
case(func[2:0])
|
3'd0,3'd4: fnDatao = {4{dat[7:0]}};
|
3'd0,3'd4: fnDatao = {4{dat[7:0]}};
|
3'd1,3'd5: fnDatao = {2{dat[15:8]}};
|
3'd1,3'd5: fnDatao = {2{dat[15:8]}};
|
default: fnDatao = dat;
|
default: fnDatao = dat;
|
endcase
|
endcase
|
`SW,`SWCR,`SWX,`CAS,`SWS,`STI,
|
`SW,`SWCR,`SWX,`CAS,`SWS,`STI,`SV,`SVWS,`SVX,
|
`PUSH,`PEA,`LINK: fnDatao = dat;
|
`PUSH,`PEA,`LINK: fnDatao = dat;
|
`SH,`SHX: fnDatao = dat;
|
`SH,`SHX: fnDatao = dat;
|
`SC,`SCX: fnDatao = {2{dat[15:0]}};
|
`SC,`SCX: fnDatao = {2{dat[15:0]}};
|
`SB,`SBX: fnDatao = {4{dat[7:0]}};
|
`SB,`SBX: fnDatao = {4{dat[7:0]}};
|
default: fnDatao = dat;
|
default: fnDatao = dat;
|
Line 2483... |
Line 2708... |
3'd0,3'd4: fnDatao = {8{dat[DBW/8-1:0]}};
|
3'd0,3'd4: fnDatao = {8{dat[DBW/8-1:0]}};
|
3'd1,3'd5: fnDatao = {4{dat[DBW/4-1:0]}};
|
3'd1,3'd5: fnDatao = {4{dat[DBW/4-1:0]}};
|
3'd2,3'd6: fnDatao = {2{dat[DBW/2-1:0]}};
|
3'd2,3'd6: fnDatao = {2{dat[DBW/2-1:0]}};
|
3'd3,3'd7: fnDatao = dat;
|
3'd3,3'd7: fnDatao = dat;
|
endcase
|
endcase
|
`SW,`SWCR,`SWX,`CAS,`SWS,`STI,
|
`SW,`SWCR,`SWX,`CAS,`SWS,`STI,`SV,`SVWS,`SVX,
|
`PUSH,`PEA,`LINK: fnDatao = dat;
|
`PUSH,`PEA,`LINK: fnDatao = dat;
|
`SH,`SHX: fnDatao = {2{dat[DBW/2-1:0]}};
|
`SH,`SHX: fnDatao = {2{dat[DBW/2-1:0]}};
|
`SC,`SCX: fnDatao = {4{dat[DBW/4-1:0]}};
|
`SC,`SCX: fnDatao = {4{dat[DBW/4-1:0]}};
|
`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 = fnIsMem(opcode0);
|
assign fetchbuf0_mem = fnIsMem(opcode0);
|
|
assign fetchbuf0_vec = fnIsVec(opcode0);
|
assign fetchbuf0_jmp = fnIsFlowCtrl(opcode0);
|
assign fetchbuf0_jmp = fnIsFlowCtrl(opcode0);
|
assign fetchbuf0_fp = fnIsFP(opcode0);
|
assign fetchbuf0_fp = fnIsFP(opcode0);
|
assign fetchbuf0_rfw = fnIsRFW(opcode0,fetchbuf0_instr);
|
assign fetchbuf0_rfw = fnIsRFW(opcode0,fetchbuf0_instr);
|
assign fetchbuf0_pfw = fnIsPFW(opcode0);
|
assign fetchbuf0_pfw = fnIsPFW(opcode0);
|
assign fetchbuf1_mem = fnIsMem(opcode1);
|
assign fetchbuf1_mem = fnIsMem(opcode1);
|
|
assign fetchbuf1_vec = fnIsVec(opcode1);
|
assign fetchbuf1_jmp = fnIsFlowCtrl(opcode1);
|
assign fetchbuf1_jmp = fnIsFlowCtrl(opcode1);
|
assign fetchbuf1_fp = fnIsFP(opcode1);
|
assign fetchbuf1_fp = fnIsFP(opcode1);
|
assign fetchbuf1_rfw = fnIsRFW(opcode1,fetchbuf1_instr);
|
assign fetchbuf1_rfw = fnIsRFW(opcode1,fetchbuf1_instr);
|
assign fetchbuf1_pfw = fnIsPFW(opcode1);
|
assign fetchbuf1_pfw = fnIsPFW(opcode1);
|
|
|
Line 2634... |
Line 2861... |
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]};
|
|
`RTF: fnImm = {9'h264,4'h0};
|
|
`JSF: fnImm = {9'h265,4'h0};
|
`RTS: fnImm = insn[19:16];
|
`RTS: fnImm = insn[19:16];
|
`RTD,`RTE,`RTI,`RTS2,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm = 64'h0;
|
`RTD,`RTE,`RTI,`RTS2,`JSRZ,`STMV,`STCMP,`STFND,`CACHE,`STS: fnImm = 64'h0;
|
`STI: fnImm = {{58{insn[33]}},insn[33:28]};
|
`STI: fnImm = {{58{insn[33]}},insn[33:28]};
|
`PUSH: fnImm = 64'hFFFFFFFFFFFFFFF8; //-8
|
`PUSH: fnImm = 64'hFFFFFFFFFFFFFFF8; //-8
|
//`LINK: fnImm = {insn[39:28],3'b000};
|
//`LINK: fnImm = {insn[39:28],3'b000};
|
Line 2666... |
Line 2895... |
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];
|
|
`RTF,`JSF: fnImm8 = 8'h80;
|
`RTS: fnImm8 = insn[19:16];
|
`RTS: fnImm8 = insn[19:16];
|
`RTD,`RTE,`RTI,`RTS2,`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
|
Line 2703... |
Line 2933... |
8'h2C,8'h2D,8'h2E,8'h2F,
|
8'h2C,8'h2D,8'h2E,8'h2F,
|
`LDI,`LDIS,`ADDUIS:
|
`LDI,`LDIS,`ADDUIS:
|
fnImmMSB = insn[31];
|
fnImmMSB = insn[31];
|
`SYS,`INT,`CACHE,`LINK:
|
`SYS,`INT,`CACHE,`LINK:
|
fnImmMSB = 1'b0; // SYS,INT are unsigned
|
fnImmMSB = 1'b0; // SYS,INT are unsigned
|
`RTS,`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`RTS2,`STS:
|
`JSF,`RTS,`RTF,`RTD,`RTE,`RTI,`JSRZ,`STMV,`STCMP,`STFND,`RTS2,`STS:
|
fnImmMSB = 1'b0; // RTS is unsigned
|
fnImmMSB = 1'b0; // RTS is unsigned
|
`PUSH: fnImmMSB = 1'b1;
|
`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];
|
Line 2733... |
Line 2963... |
4'd8: fnImmImm = {insn[63:8],8'h00};
|
4'd8: fnImmImm = {insn[63:8],8'h00};
|
default: fnImmImm = 64'd0;
|
default: fnImmImm = 64'd0;
|
endcase
|
endcase
|
endfunction
|
endfunction
|
|
|
|
// In the works: multiplexing for the immediate operand
|
|
function fnOp0;
|
|
input [7:0] opcode;
|
|
input [5:0] vel;
|
|
input [63:0] ins;
|
|
input [2:0] tail;
|
|
fnOp0 =
|
|
`ifdef VECTOROPS
|
|
(opcode==`LVX || opcode==`SVX) ? vel :
|
|
`endif
|
|
(opcode==`INT || opcode==`SYS || opcode==`RTF || opcode==`JSF) ? fnImm(ins) :
|
|
fnIsBranch(opcode) ? {{DBW-12{ins[11]}},ins[11:8],ins[23:16]} :
|
|
(iqentry_op[(tail-3'd1)&7]==`IMM && iqentry_v[tail-3'd1]) ? {iqentry_a0[(tail-3'd1)&7][DBW-1:8],fnImm8(ins)}:
|
|
opcode==`IMM ? fnImmImm(ins) : fnImm(ins);
|
|
endfunction
|
|
|
// Used during enque
|
// Used during enque
|
// Operand A is a little more work than B or C as it may read from special
|
// Operand A is a little more work than B or C as it may read from special
|
// purpose registers.
|
// purpose registers.
|
function [63:0] fnOpa;
|
function [63:0] fnOpa;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
input [6:0] Ra;
|
input [7:0] Ra;
|
input [63:0] ins;
|
input [63:0] ins;
|
input [63:0] rfo;
|
input [63:0] rfo;
|
input [63:0] epc;
|
input [63:0] epc;
|
begin
|
begin
|
`ifdef BITFIELDOPS
|
`ifdef BITFIELDOPS
|
if (opcode==`BITFIELD && ins[43:40]==`BFINSI)
|
if (opcode==`BITFIELD && ins[43:40]==`BFINSI)
|
fnOpa = ins[21:16];
|
fnOpa = ins[21:16];
|
else
|
else
|
`endif
|
`endif
|
if (Ra[6])
|
if (Ra[7:6]==2'h1)
|
fnOpa = fnSpr(Ra[5:0],epc);
|
fnOpa = fnSpr(Ra[5:0],epc);
|
else
|
else
|
fnOpa = rfo;
|
fnOpa = rfo;
|
end
|
end
|
endfunction
|
endfunction
|
|
|
function [DBW-1:0] fnOpb;
|
function [DBW-1:0] fnOpb;
|
input [7:0] opcode;
|
input [7:0] opcode;
|
input [6:0] Rb;
|
input [9:0] Rb;
|
input [63:0] ins;
|
input [63:0] ins;
|
input [63:0] rfo;
|
input [63:0] rfo;
|
|
input [63:0] vrfo;
|
input [63:0] epc;
|
input [63:0] epc;
|
begin
|
begin
|
fnOpb = fnIsShiftiop(ins) ? {{DBW-6{1'b0}},ins[`INSTRUCTION_RB]} :
|
fnOpb = fnIsShiftiop(ins) ? {{DBW-6{1'b0}},ins[`INSTRUCTION_RB]} :
|
fnIsFPCtrl(ins) ? {{DBW-6{1'b0}},ins[`INSTRUCTION_RB]} :
|
fnIsFPCtrl(ins) ? {{DBW-6{1'b0}},ins[`INSTRUCTION_RB]} :
|
opcode==`INC ? {{56{ins[47]}},ins[47:40]} :
|
opcode==`INC ? {{56{ins[47]}},ins[47:40]} :
|
opcode==`STI ? ins[27:22] :
|
opcode==`STI ? ins[27:22] :
|
Rb[6] ? fnSpr(Rb[5:0],epc) :
|
Rb[7:6]==2'h1 ? fnSpr(Rb[5:0],epc) :
|
|
`ifdef VECTOROPS
|
|
Rb[7] ? vrfo :
|
|
`endif
|
rfo;
|
rfo;
|
end
|
end
|
endfunction
|
endfunction
|
|
|
// Used during enque
|
// Used during enque
|
function [63:0] fnOpt;
|
function [63:0] fnOpt;
|
input [6:0] tgt;
|
input [7:0] tgt;
|
input [63:0] rfo;
|
input [63:0] rfo;
|
|
input [63:0] vrfo;
|
input [63:0] epc;
|
input [63:0] epc;
|
begin
|
begin
|
if (tgt[6])
|
if (tgt[7:6]==2'b01)
|
fnOpt = fnSpr(tgt[5:0],epc);
|
fnOpt = fnSpr(tgt[5:0],epc);
|
|
`ifdef VECTOROPS
|
|
else if (tgt[7])
|
|
fnOpt = vrfo;
|
|
`endif
|
else
|
else
|
fnOpt = rfo;
|
fnOpt = rfo;
|
end
|
end
|
endfunction
|
endfunction
|
|
|
Line 2798... |
Line 3052... |
fnIsKMOnly = `FALSE;
|
fnIsKMOnly = `FALSE;
|
`endif
|
`endif
|
endfunction
|
endfunction
|
|
|
function fnIsKMOnlyReg;
|
function fnIsKMOnlyReg;
|
input [6:0] regx;
|
input [7:0] regx;
|
`ifdef PRIVCHKS
|
`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
|
;
|
;
|
`else
|
`else
|
Line 2810... |
Line 3064... |
`endif
|
`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 [7:0] regno; // r0, c0, c15, tick
|
fnRegIsAutoValid = regno==7'h00 || regno==7'h50 || regno==7'h5F || regno==7'h72;
|
fnRegIsAutoValid = regno==7'h00 || regno==7'h50 || regno==7'h5F || regno==7'h72;
|
endfunction
|
endfunction
|
|
|
function [15:0] fnRegstrGrp;
|
function [15:0] fnRegstrGrp;
|
input [6:0] Rn;
|
input [6:0] Rn;
|
Line 2834... |
Line 3088... |
endcase
|
endcase
|
|
|
endfunction
|
endfunction
|
|
|
function [7:0] fnRegstr;
|
function [7:0] fnRegstr;
|
input [6:0] Rn;
|
input [7:0] Rn;
|
begin
|
begin
|
if (!Rn[6]) begin
|
if (Rn[7:6]==2'b00) begin
|
fnRegstr = Rn[5:0];
|
fnRegstr = Rn[5:0];
|
end
|
end
|
else
|
else
|
fnRegstr = Rn[3:0];
|
fnRegstr = Rn[3:0];
|
end
|
end
|
endfunction
|
endfunction
|
|
|
|
assign operandA0 = fnOpa(opcode0,Ra0,fetchbuf0_instr,rfoa0,fetchbuf0_pc);
|
|
assign operandA1 = fnOpa(opcode1,Ra1,fetchbuf1_instr,rfoa1,fetchbuf1_pc);
|
|
|
initial begin
|
initial begin
|
//
|
//
|
// set up panic messages
|
// set up panic messages
|
message[ `PANIC_NONE ] = "NONE ";
|
message[ `PANIC_NONE ] = "NONE ";
|
message[ `PANIC_FETCHBUFBEQ ] = "FETCHBUFBEQ ";
|
message[ `PANIC_FETCHBUFBEQ ] = "FETCHBUFBEQ ";
|
Line 2910... |
Line 3167... |
|| (iqentry_a2_s[g] == alu0_sourceid && alu0_v)
|
|| (iqentry_a2_s[g] == alu0_sourceid && alu0_v)
|
|| (iqentry_a2_s[g] == alu1_sourceid && alu1_v))
|
|| (iqentry_a2_s[g] == alu1_sourceid && alu1_v))
|
&& (iqentry_a3_v[g]
|
&& (iqentry_a3_v[g]
|
|| (iqentry_a3_s[g] == alu0_sourceid && alu0_v)
|
|| (iqentry_a3_s[g] == alu0_sourceid && alu0_v)
|
|| (iqentry_a3_s[g] == alu1_sourceid && alu1_v))
|
|| (iqentry_a3_s[g] == alu1_sourceid && alu1_v))
|
|
`ifdef VECTOROPS
|
|
&& (iqentry_a4_v[g]
|
|
|| (iqentry_a4_s[g] == alu0_sourceid && alu0_v)
|
|
|| (iqentry_a4_s[g] == alu1_sourceid && alu1_v))
|
|
`endif
|
&& (iqentry_T_v[g]
|
&& (iqentry_T_v[g]
|
|| (iqentry_T_s[g] == alu0_sourceid && alu0_v)
|
|| (iqentry_T_s[g] == alu0_sourceid && alu0_v)
|
|| (iqentry_T_s[g] == alu1_sourceid && alu1_v))
|
|| (iqentry_T_s[g] == alu1_sourceid && alu1_v))
|
;
|
;
|
|
|
assign could_issue[g] = iqentry_v[g] && !iqentry_done[g] && !iqentry_out[g] && args_valid[g] &&
|
assign could_issue[g] = iqentry_v[g] && !iqentry_done[g] &&
|
|
!iqentry_out[g] && args_valid[g] &&
|
(iqentry_mem[g] ? !iqentry_agen[g] : 1'b1);
|
(iqentry_mem[g] ? !iqentry_agen[g] : 1'b1);
|
|
|
end
|
end
|
end
|
end
|
endgenerate
|
endgenerate
|
Line 2938... |
Line 3201... |
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] & alu0_idle) begin
|
// See if we can issue to the first alu.
|
|
if (alu0_idle) begin
|
|
if (could_issue[head0] && !iqentry_fp[head0]) 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] & alu0_idle
|
else if (could_issue[head1] && !iqentry_fp[head1]
|
&& !(iqentry_v[head0] && iqentry_sync[head0]))
|
&& !(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] & alu0_idle
|
else if (could_issue[head2] && !iqentry_fp[head2]
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(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] & alu0_idle
|
else if (could_issue[head3] && !iqentry_fp[head3]
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(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] & alu0_idle
|
else if (could_issue[head4] && !iqentry_fp[head4]
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(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] & alu0_idle
|
else if (could_issue[head5] && !iqentry_fp[head5]
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(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] & alu0_idle
|
else if (could_issue[head6] && !iqentry_fp[head6]
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head5] && iqentry_sync[head5])
|
&& !(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] & alu0_idle
|
else if (could_issue[head7] && !iqentry_fp[head7]
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
Line 3006... |
Line 3271... |
&& !(iqentry_v[head6] && iqentry_sync[head6])
|
&& !(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
|
|
end
|
|
|
// Don't bother checking head0, it should have issued to the first
|
if (alu1_idle) begin
|
// instruction.
|
if (could_issue[head0] && !iqentry_fp[head0]
|
if (could_issue[head1] && !iqentry_fp[head1] && !iqentry_issue[head1] & alu1_idle
|
&& !fnIsAlu0Op(iqentry_op[head0],iqentry_fn[head0])
|
|
&& !iqentry_issue[head0]) begin
|
|
iqentry_issue[head0] = `TRUE;
|
|
iqentry_islot[head0] = 2'b01;
|
|
end
|
|
else if (could_issue[head1] && !iqentry_fp[head1] && !iqentry_issue[head1]
|
&& !fnIsAlu0Op(iqentry_op[head1],iqentry_fn[head1])
|
&& !fnIsAlu0Op(iqentry_op[head1],iqentry_fn[head1])
|
&& !(iqentry_v[head0] && iqentry_sync[head0]))
|
&& !(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] & alu1_idle
|
else if (could_issue[head2] && !iqentry_fp[head2] && !iqentry_issue[head2]
|
&& !fnIsAlu0Op(iqentry_op[head2],iqentry_fn[head2])
|
&& !fnIsAlu0Op(iqentry_op[head2],iqentry_fn[head2])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(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] & alu1_idle
|
else if (could_issue[head3] && !iqentry_fp[head3] && !iqentry_issue[head3]
|
&& !fnIsAlu0Op(iqentry_op[head3],iqentry_fn[head3])
|
&& !fnIsAlu0Op(iqentry_op[head3],iqentry_fn[head3])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(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] & alu1_idle
|
else if (could_issue[head4] && !iqentry_fp[head4] && !iqentry_issue[head4]
|
&& !fnIsAlu0Op(iqentry_op[head4],iqentry_fn[head4])
|
&& !fnIsAlu0Op(iqentry_op[head4],iqentry_fn[head4])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(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] & alu1_idle
|
else if (could_issue[head5] && !iqentry_fp[head5] && !iqentry_issue[head5]
|
&& !fnIsAlu0Op(iqentry_op[head5],iqentry_fn[head5])
|
&& !fnIsAlu0Op(iqentry_op[head5],iqentry_fn[head5])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head4] && iqentry_sync[head4])
|
&& !(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] & alu1_idle
|
else if (could_issue[head6] & !iqentry_fp[head6] && !iqentry_issue[head6]
|
&& !fnIsAlu0Op(iqentry_op[head6],iqentry_fn[head6])
|
&& !fnIsAlu0Op(iqentry_op[head6],iqentry_fn[head6])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
Line 3067... |
Line 3338... |
&& !(iqentry_v[head5] && iqentry_sync[head5])
|
&& !(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] & alu1_idle
|
else if (could_issue[head7] && !iqentry_fp[head7] && !iqentry_issue[head7]
|
&& !fnIsAlu0Op(iqentry_op[head7],iqentry_fn[head7])
|
&& !fnIsAlu0Op(iqentry_op[head7],iqentry_fn[head7])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head0] && iqentry_sync[head0])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head1] && iqentry_sync[head1])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head2] && iqentry_sync[head2])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
&& !(iqentry_v[head3] && iqentry_sync[head3])
|
Line 3081... |
Line 3352... |
) begin
|
) begin
|
iqentry_issue[head7] = `TRUE;
|
iqentry_issue[head7] = `TRUE;
|
iqentry_islot[head7] = 2'b01;
|
iqentry_islot[head7] = 2'b01;
|
end
|
end
|
end
|
end
|
|
end
|
|
|
`ifdef FLOATING_POINT
|
`ifdef FLOATING_POINT
|
reg [3:0] fpispot;
|
reg [3:0] fpispot;
|
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_fpissue = 8'h00;
|
iqentry_fpissue = 8'h00;
|
iqentry_fpislot[0] = 2'b00;
|
iqentry_fpislot[0] = 2'b00;
|
iqentry_fpislot[1] = 2'b00;
|
iqentry_fpislot[1] = 2'b00;
|
iqentry_fpislot[2] = 2'b00;
|
iqentry_fpislot[2] = 2'b00;
|
Line 3757... |
Line 4028... |
dbg_adr1 <= 0;
|
dbg_adr1 <= 0;
|
dbg_adr2 <= 0;
|
dbg_adr2 <= 0;
|
dbg_adr3 <= 0;
|
dbg_adr3 <= 0;
|
`endif
|
`endif
|
end
|
end
|
|
`ifdef SEGMENTATION
|
if (ABW==32)
|
if (ABW==32)
|
sregs_lmt[7] = 20'hFFFFF;
|
sregs_lmt[7] = 20'hFFFFF;
|
else
|
else
|
sregs_lmt[7] = 52'hFFFFFFFFFFFFF;
|
sregs_lmt[7] = 52'hFFFFFFFFFFFFF;
|
|
// The pc wraps around to address zero while fetching the reset vector.
|
|
// This causes the processor to use the code segement register so the
|
|
// CS has to be defined for reset.
|
|
sregs_base[7] <= RSTCSEG;
|
|
`endif
|
rf_source[0] <= 4'd0;
|
rf_source[0] <= 4'd0;
|
// rf_v[0] = `VAL;
|
// rf_v[0] = `VAL;
|
// rf_v[7'h50] = `VAL;
|
// rf_v[7'h50] = `VAL;
|
// rf_v[7'h5F] = `VAL;
|
// rf_v[7'h5F] = `VAL;
|
alu0_available <= `TRUE;
|
alu0_available <= `TRUE;
|
Line 3782... |
Line 4059... |
dram1 <= 3'b00;
|
dram1 <= 3'b00;
|
dram2 <= 3'b00;
|
dram2 <= 3'b00;
|
tlb_state <= 3'd0;
|
tlb_state <= 3'd0;
|
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.
|
|
// This causes the processor to use the code segement register so the
|
|
// CS has to be defined for reset.
|
|
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;
|
alu1_sourceid <= 0;
|
alu1_sourceid <= 0;
|
|
smode <= 2'b00;
|
|
regset <= 3'd0;
|
end
|
end
|
|
|
// The following registers are always valid
|
// The following registers are always valid
|
rf_v[7'h00] = `VAL;
|
rf_v[7'h00] = `VAL;
|
rf_v[7'h50] = `VAL; // C0
|
rf_v[7'h50] = `VAL; // C0
|
Line 3846... |
Line 4121... |
//
|
//
|
if (commit0_v) begin
|
if (commit0_v) begin
|
if (!rf_v[ commit0_tgt ]) begin
|
if (!rf_v[ commit0_tgt ]) begin
|
rf_v[ commit0_tgt ] = (rf_source[ commit0_tgt ] == commit0_id) || ((branchmiss) && iqentry_source[ commit0_id[2:0] ]);
|
rf_v[ commit0_tgt ] = (rf_source[ commit0_tgt ] == commit0_id) || ((branchmiss) && iqentry_source[ commit0_id[2:0] ]);
|
end
|
end
|
if (commit0_tgt != 7'd0) $display("r%d <- %h", commit0_tgt, commit0_bus);
|
if (commit0_tgt != 8'd0) $display("r%d <- %h", commit0_tgt, commit0_bus);
|
end
|
end
|
if (commit1_v) begin
|
if (commit1_v) begin
|
if (!rf_v[ commit1_tgt ]) begin
|
if (!rf_v[ commit1_tgt ]) begin
|
rf_v[ commit1_tgt ] = (rf_source[ commit1_tgt ] == commit1_id)|| ((branchmiss) && iqentry_source[ commit1_id[2:0] ]);
|
rf_v[ commit1_tgt ] = (rf_source[ commit1_tgt ] == commit1_id)|| ((branchmiss) && iqentry_source[ commit1_id[2:0] ]);
|
end
|
end
|
if (commit1_tgt != 7'd0) $display("r%d <- %h", commit1_tgt, commit1_bus);
|
if (commit1_tgt != 8'd0) $display("r%d <- %h", commit1_tgt, commit1_bus);
|
end
|
end
|
|
|
// This chunk of code has to be before the enqueue stage so that the agen bit
|
// This chunk of code has to be before the enqueue stage so that the agen bit
|
// can be reset to zero by enqueue.
|
// can be reset to zero by enqueue.
|
// put results into the appropriate instruction entries
|
// put results into the appropriate instruction entries
|
Line 3872... |
Line 4147... |
alu0_dataready <= `TRUE;
|
alu0_dataready <= `TRUE;
|
end
|
end
|
end
|
end
|
|
|
if (alu0_v) begin
|
if (alu0_v) begin
|
if (|alu0_exc)
|
if (|alu0_exc) begin
|
set_exception(alu0_id,
|
set_exception(alu0_id, alu0_exc);
|
alu0_exc==`EXC_PRIV ? 8'd245 :
|
iqentry_a1[alu0_id[2:0]] <= alu0_bus;
|
alu0_exc==`EXC_DBZ ? 8'd241 :
|
end
|
alu0_exc==`EXC_CHK ? 8'd239 : 8'h00);
|
|
else begin
|
else begin
|
if (iqentry_op[alu0_id[2:0]]!=`IMM)
|
if (iqentry_op[alu0_id[2:0]]!=`IMM)
|
iqentry_done[ alu0_id[2:0] ] <= (!iqentry_mem[ alu0_id[2:0] ] || !alu0_cmt);
|
iqentry_done[ alu0_id[2:0] ] <= (!iqentry_mem[ alu0_id[2:0] ] || !alu0_cmt);
|
if (iqentry_jmpi[alu0_id[2:0]] && alu0_cmt)
|
if (iqentry_jmpi[alu0_id[2:0]] && alu0_cmt)
|
iqentry_res [alu0_id[2:0]] <= alu0_pc + alu0_insnsz;
|
iqentry_res [alu0_id[2:0]] <= alu0_pc + alu0_insnsz;
|
Line 3891... |
Line 4165... |
iqentry_agen[ alu0_id[2:0] ] <= `TRUE;
|
iqentry_agen[ alu0_id[2:0] ] <= `TRUE;
|
end
|
end
|
end
|
end
|
|
|
|
|
if (((alu1_op==`RR && (alu1_fn==`MUL || alu1_fn==`MULU)) || alu1_op==`MULI || alu1_op==`MULUI) && ALU1BIG) begin
|
if (((alu1_op==`RR && (alu1_fn==`MUL || alu1_fn==`MULU)) || alu1_op==`MULI || alu1_op==`MULUI)) begin
|
if (alu1_done) begin
|
if (alu1_done) begin
|
alu1_dataready <= `TRUE;
|
alu1_dataready <= `TRUE;
|
end
|
end
|
end
|
end
|
else if (((alu1_op==`RR && (alu1_fn==`DIV || alu1_fn==`DIVU || alu1_fn==`MOD || alu1_fn==`MODU)) ||
|
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
|
alu1_op==`DIVI || alu1_op==`DIVUI || alu1_op==`MODI || alu1_op==`MODUI)) begin
|
if (alu1_done) begin
|
if (alu1_done) begin
|
alu1_dataready <= `TRUE;
|
alu1_dataready <= `TRUE;
|
end
|
end
|
end
|
end
|
|
|
if (alu1_v) begin
|
if (alu1_v) begin
|
if (|alu1_exc)
|
if (|alu1_exc) begin
|
set_exception(alu1_id,
|
set_exception(alu1_id, alu1_exc);
|
alu1_exc==`EXC_PRIV ? 8'd245 :
|
iqentry_a1[alu1_id[2:0]] <= alu1_bus;
|
alu1_exc==`EXC_DBZ ? 8'd241 :
|
end
|
alu1_exc==`EXC_CHK ? 8'd239 : 8'h00);
|
|
else begin
|
else begin
|
if (iqentry_op[alu1_id[2:0]]!=`IMM)
|
if (iqentry_op[alu1_id[2:0]]!=`IMM)
|
iqentry_done[ alu1_id[2:0] ] <= (!iqentry_mem[ alu1_id[2:0] ] || !alu1_cmt);
|
iqentry_done[ alu1_id[2:0] ] <= (!iqentry_mem[ alu1_id[2:0] ] || !alu1_cmt);
|
if (iqentry_jmpi[alu1_id[2:0]] && alu1_cmt)
|
if (iqentry_jmpi[alu1_id[2:0]] && alu1_cmt)
|
iqentry_res [alu1_id[2:0]] <= alu1_pc + alu1_insnsz;
|
iqentry_res [alu1_id[2:0]] <= alu1_pc + alu1_insnsz;
|
Line 3957... |
Line 4230... |
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
//
|
//
|
exception_set = `FALSE;
|
exception_set = `FALSE;
|
queued1 = `FALSE;
|
queued1 = `FALSE;
|
queued2 = `FALSE;
|
queued2 = `FALSE;
|
|
queued1v = `FALSE;
|
|
queued2v = `FALSE;
|
allowq = `TRUE;
|
allowq = `TRUE;
|
qstomp = `FALSE;
|
qstomp = `FALSE;
|
if (branchmiss) // don't bother doing anything if there's been a branch miss
|
if (branchmiss) // don't bother doing anything if there's been a branch miss
|
reset_tail_pointers(0);
|
reset_tail_pointers(0);
|
else begin
|
else begin
|
case ({fetchbuf0_v, fetchbuf1_v && fnNumReadPorts(fetchbuf1_instr) <= ports_avail})
|
case ({fetchbuf0_v, fetchbuf1_v && fnNumReadPorts(fetchbuf1_instr) <= ports_avail})
|
2'b00: ; // do nothing
|
2'b00: ; // do nothing
|
2'b01: enque1(tail0,1,0,1);
|
2'b01: enque1(tail0,1,0,1,vele);
|
2'b10: enque0(tail0,1,0,1);
|
2'b10: enque0(tail0,1,0,1,vele);
|
2'b11: begin
|
2'b11: begin
|
enque0(tail0,1,1,1);
|
enque0(tail0,1,1,1,vele);
|
if (allowq)
|
if (allowq)
|
enque1(tail1,2,0,0);
|
enque1(tail1,2,0,0,vele+1);
|
validate_args();
|
validate_args();
|
end
|
end
|
endcase
|
endcase
|
|
`ifdef VECTOROPS
|
|
// Once instruction is completely queued reset vector element count to zero.
|
|
// Otherwise increment it according to the number of elements queued.
|
|
if (queued1|queued2)
|
|
vele <= 8'd0;
|
|
else if (queued2v)
|
|
vele <= vele + 2;
|
|
else if (queued1v)
|
|
vele <= vele + 1;
|
|
`endif
|
end
|
end
|
|
|
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
// FETCH
|
// FETCH
|
//
|
//
|
Line 4268... |
Line 4553... |
iqentry_res [ dram_id[2:0] ] <= dram_bus;
|
iqentry_res [ dram_id[2:0] ] <= dram_bus;
|
// If an exception occurred, stuff an interrupt instruction into the queue
|
// If an exception occurred, stuff an interrupt instruction into the queue
|
// slot. The instruction will re-issue as an ALU operation. We can change
|
// slot. The instruction will re-issue as an ALU operation. We can change
|
// the queued instruction because it isn't finished yet.
|
// the queued instruction because it isn't finished yet.
|
if (|dram_exc) begin
|
if (|dram_exc) begin
|
set_exception(dram_id,
|
set_exception(dram_id, dram_exc);
|
dram_exc==`EXC_DBE ? 8'hFB :
|
|
dram_exc==`EXC_DBG ? 8'd243 :
|
|
dram_exc==`EXC_SEGV ? 8'd244 :
|
|
8'hF8); // F8 = TLBMiss exception 243 = debug
|
|
$stop;
|
$stop;
|
end
|
end
|
else begin
|
else begin
|
// Note that the predicate was already evaluated to TRUE before the
|
// Note that the predicate was already evaluated to TRUE before the
|
// dram operation started.
|
// dram operation started.
|
Line 4321... |
Line 4602... |
// - fp0_bus
|
// - fp0_bus
|
// - mem_bus
|
// - mem_bus
|
// - commit0_bus
|
// - commit0_bus
|
// - commit1_bus
|
// - commit1_bus
|
//
|
//
|
|
setargs (alu0_id, alu0_v, alu0_bus);
|
|
setargs (alu1_id, alu1_v, alu1_bus);
|
|
`ifdef FLOATING_POINT
|
|
setargs (fp0_id, fp0_v, fp0_bus);
|
|
`endif
|
|
setargs (dram_id, dram_v, dram_bus);
|
|
setargs (commit0_id, commit0_v, commit0_bus);
|
|
setargs (commit1_id, commit1_v, commit1_bus);
|
|
|
for (n = 0; n < QENTRIES; n = n + 1)
|
for (n = 0; n < QENTRIES; n = n + 1)
|
begin
|
begin
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
|
iqentry_pred[n] <= alu0nyb[iqentry_preg[n]];
|
iqentry_pred[n] <= alu0nyb[iqentry_preg[n]];
|
iqentry_p_v[n] <= `VAL;
|
iqentry_p_v[n] <= `VAL;
|
end
|
end
|
if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
|
|
iqentry_a1[n] <= alu0_bus;
|
|
iqentry_a1_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
|
|
iqentry_a2[n] <= alu0_bus;
|
|
iqentry_a2_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
|
|
iqentry_a3[n] <= alu0_bus;
|
|
iqentry_a3_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == alu0_id && iqentry_v[n] == `VAL && alu0_v == `VAL) begin
|
|
iqentry_T[n] <= alu0_bus;
|
|
iqentry_T_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
|
iqentry_pred[n] <= alu1nyb[iqentry_preg[n]];
|
iqentry_pred[n] <= alu1nyb[iqentry_preg[n]];
|
iqentry_p_v[n] <= `VAL;
|
iqentry_p_v[n] <= `VAL;
|
end
|
end
|
if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
|
|
iqentry_a1[n] <= alu1_bus;
|
|
iqentry_a1_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
|
|
iqentry_a2[n] <= alu1_bus;
|
|
iqentry_a2_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
|
|
iqentry_a3[n] <= alu1_bus;
|
|
iqentry_a3_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == alu1_id && iqentry_v[n] == `VAL && alu1_v == `VAL) begin
|
|
iqentry_T[n] <= alu1_bus;
|
|
iqentry_T_v[n] <= `VAL;
|
|
end
|
|
`ifdef FLOATING_POINT
|
|
/*
|
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
|
|
iqentry_pred[n] <= fp0_bus[3:0];
|
|
iqentry_p_v[n] <= `VAL;
|
|
end
|
|
*/
|
|
if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
|
|
iqentry_a1[n] <= fp0_bus;
|
|
iqentry_a1_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
|
|
iqentry_a2[n] <= fp0_bus;
|
|
iqentry_a2_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
|
|
iqentry_a3[n] <= fp0_bus;
|
|
iqentry_a3_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == fp0_id && iqentry_v[n] == `VAL && fp0_v == `VAL) begin
|
|
iqentry_T[n] <= fp0_bus;
|
|
iqentry_T_v[n] <= `VAL;
|
|
end
|
|
`endif
|
|
// For SWCR
|
// For SWCR
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
|
iqentry_pred[n] <= dram_bus[3:0];
|
iqentry_pred[n] <= dram_bus[3:0];
|
iqentry_p_v[n] <= `VAL;
|
iqentry_p_v[n] <= `VAL;
|
end
|
end
|
if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
|
|
iqentry_a1[n] <= dram_bus;
|
|
iqentry_a1_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
|
|
iqentry_a2[n] <= dram_bus;
|
|
iqentry_a2_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
|
|
iqentry_a3[n] <= dram_bus;
|
|
iqentry_a3_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == dram_id && iqentry_v[n] == `VAL && dram_v == `VAL) begin
|
|
iqentry_T[n] <= dram_bus;
|
|
iqentry_T_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n]==commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
|
iqentry_pred[n] <= cmt0nyb[iqentry_preg[n]];
|
iqentry_pred[n] <= cmt0nyb[iqentry_preg[n]];
|
iqentry_p_v[n] <= `VAL;
|
iqentry_p_v[n] <= `VAL;
|
end
|
end
|
if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
|
|
iqentry_a1[n] <= commit0_bus;
|
|
iqentry_a1_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
|
|
iqentry_a2[n] <= commit0_bus;
|
|
iqentry_a2_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
|
|
iqentry_a3[n] <= commit0_bus;
|
|
iqentry_a3_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == commit0_id && iqentry_v[n] == `VAL && commit0_v == `VAL) begin
|
|
iqentry_T[n] <= commit0_bus;
|
|
iqentry_T_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
|
if (iqentry_p_v[n] == `INV && iqentry_p_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
|
iqentry_pred[n] <= cmt1nyb[iqentry_preg[n]];
|
iqentry_pred[n] <= cmt1nyb[iqentry_preg[n]];
|
iqentry_p_v[n] <= `VAL;
|
iqentry_p_v[n] <= `VAL;
|
end
|
end
|
if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
|
|
iqentry_a1[n] <= commit1_bus;
|
|
iqentry_a1_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
|
|
iqentry_a2[n] <= commit1_bus;
|
|
iqentry_a2_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
|
|
iqentry_a3[n] <= commit1_bus;
|
|
iqentry_a3_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == commit1_id && iqentry_v[n] == `VAL && commit1_v == `VAL) begin
|
|
iqentry_T[n] <= commit1_bus;
|
|
iqentry_T_v[n] <= `VAL;
|
|
end
|
|
end
|
end
|
|
|
//`include "Thor_issue.v"
|
//`include "Thor_issue.v"
|
// ISSUE
|
// ISSUE
|
//
|
//
|
Line 4502... |
Line 4687... |
if (dram1_id[2:0] == n[2:0]) dram1 <= `DRAMSLOT_AVAIL;
|
if (dram1_id[2:0] == n[2:0]) dram1 <= `DRAMSLOT_AVAIL;
|
if (dram2_id[2:0] == n[2:0]) dram2 <= `DRAMSLOT_AVAIL;
|
if (dram2_id[2:0] == n[2:0]) dram2 <= `DRAMSLOT_AVAIL;
|
end
|
end
|
else if (iqentry_issue[n]) begin
|
else if (iqentry_issue[n]) begin
|
case (iqentry_islot[n])
|
case (iqentry_islot[n])
|
2'd0: if (alu0_available) begin
|
2'd0: if (alu0_available && alu0_done) begin
|
alu0_ld <= 1'b1;
|
alu0_ld <= 1'b1;
|
alu0_sourceid <= n[3:0];
|
alu0_sourceid <= n[3:0];
|
alu0_insnsz <= iqentry_insnsz[n];
|
alu0_insnsz <= iqentry_insnsz[n];
|
alu0_op <= iqentry_op[n];
|
alu0_op <= iqentry_op[n];
|
alu0_fn <= iqentry_fn[n];
|
alu0_fn <= iqentry_fn[n];
|
Line 4524... |
Line 4709... |
: (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]) || iqentry_lla[n]) ? {sregs[iqentry_fn[n][5:3]],12'h000} :
|
((iqentry_mem[n] && !iqentry_cmpmv[n]) || iqentry_lla[n]) ? {sregs_base[iqentry_fn[n][5:3]],12'h000} :
|
|
`else
|
|
((iqentry_mem[n] && !iqentry_cmpmv[n]) || iqentry_lla[n]) ? 64'd0 :
|
`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 4538... |
Line 4725... |
: 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;
|
iqentry_out[n] <= `TRUE;
|
end
|
end
|
2'd1: if (alu1_available) begin
|
2'd1: if (alu1_available && alu1_done) 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];
|
alu1_op <= iqentry_op[n];
|
alu1_op <= iqentry_op[n];
|
alu1_fn <= iqentry_fn[n];
|
alu1_fn <= iqentry_fn[n];
|
Line 4560... |
Line 4747... |
: (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]) || iqentry_lla[n]) ? {sregs[iqentry_fn[n][5:3]],12'h000} :
|
((iqentry_mem[n] && !iqentry_cmpmv[n]) || iqentry_lla[n]) ? {sregs_base[iqentry_fn[n][5:3]],12'h000} :
|
|
`else
|
|
((iqentry_mem[n] && !iqentry_cmpmv[n]) || iqentry_lla[n]) ? 64'd0 :
|
`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 4618... |
Line 4807... |
: 64'hDEADDEADDEADDEAD;
|
: 64'hDEADDEADDEADDEAD;
|
fp0_argT <= iqentry_T_v[n] ? iqentry_T[n]
|
fp0_argT <= iqentry_T_v[n] ? iqentry_T[n]
|
: (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;
|
|
|
fp0_argI <= iqentry_a0[n];
|
fp0_argI <= iqentry_a0[n];
|
end
|
end
|
default: panic <= `PANIC_INVALIDISLOT;
|
default: panic <= `PANIC_INVALIDISLOT;
|
endcase
|
endcase
|
iqentry_out[n] <= `TRUE;
|
iqentry_out[n] <= `TRUE;
|
Line 4650... |
Line 4840... |
tlb_state <= tlb_state + 3'd1;
|
tlb_state <= tlb_state + 3'd1;
|
if (tlb_state==3'd3) begin
|
if (tlb_state==3'd3) begin
|
dram_v <= `TRUE;
|
dram_v <= `TRUE;
|
dram_id <= tlb_id;
|
dram_id <= tlb_id;
|
dram_tgt <= tlb_tgt;
|
dram_tgt <= tlb_tgt;
|
dram_exc <= `EXC_NONE;
|
dram_exc <= `EX_NONE;
|
dram_bus <= tlb_dato;
|
dram_bus <= tlb_dato;
|
tlb_op <= 4'h0;
|
tlb_op <= 4'h0;
|
tlb_state <= 3'd0;
|
tlb_state <= 3'd0;
|
end
|
end
|
|
|
Line 4666... |
Line 4856... |
$display("0MEM %c:%h %h cycle started",fnIsStore(dram0_op)?"S" : "L", dram0_addr, dram0_data);
|
$display("0MEM %c:%h %h cycle started",fnIsStore(dram0_op)?"S" : "L", dram0_addr, dram0_data);
|
if (dbg_lmatch|dbg_smatch) begin
|
if (dbg_lmatch|dbg_smatch) begin
|
dram_v <= `TRUE;
|
dram_v <= `TRUE;
|
dram_id <= dram0_id;
|
dram_id <= dram0_id;
|
dram_tgt <= dram0_tgt;
|
dram_tgt <= dram0_tgt;
|
dram_exc <= `EXC_DBG;
|
dram_exc <= `EX_DBG;
|
dram_bus <= 64'h0;
|
dram_bus <= 64'h0;
|
dram0 <= 3'd0;
|
dram0 <= 3'd0;
|
end
|
end
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
`ifdef SEGLIMITS
|
`ifdef SEGLIMITS
|
else if (dram0_addr[ABW-1:12] >= dram0_lmt) begin
|
else if (dram0_addr[ABW-1:12] >= dram0_lmt) begin
|
dram_v <= `TRUE; // we are finished the memory cycle
|
dram_v <= `TRUE; // we are finished the memory cycle
|
dram_id <= dram0_id;
|
dram_id <= dram0_id;
|
dram_tgt <= dram0_tgt;
|
dram_tgt <= dram0_tgt;
|
dram_exc <= `EXC_SEGV; //dram0_exc;
|
dram_exc <= `EX_SEGV; //dram0_exc;
|
dram_bus <= 64'h0;
|
dram_bus <= 64'h0;
|
dram0 <= 3'd0;
|
dram0 <= 3'd0;
|
end
|
end
|
`endif
|
`endif
|
`endif
|
`endif
|
Line 4693... |
Line 4883... |
3'd2:
|
3'd2:
|
if (DTLBMiss) begin
|
if (DTLBMiss) begin
|
dram_v <= `TRUE; // we are finished the memory cycle
|
dram_v <= `TRUE; // we are finished the memory cycle
|
dram_id <= dram0_id;
|
dram_id <= dram0_id;
|
dram_tgt <= dram0_tgt;
|
dram_tgt <= dram0_tgt;
|
dram_exc <= `EXC_TLBMISS; //dram0_exc;
|
dram_exc <= `EX_TLBMISS; //dram0_exc;
|
dram_bus <= 64'h0;
|
dram_bus <= 64'h0;
|
dram0 <= 3'd0;
|
dram0 <= 3'd0;
|
end
|
end
|
else if (dram0_exc!=`EXC_NONE) begin
|
else if (dram0_exc!=`EXC_NONE) begin
|
dram_v <= `TRUE; // we are finished the memory cycle
|
dram_v <= `TRUE; // we are finished the memory cycle
|
Line 4747... |
Line 4937... |
if (ack_i|err_i) begin
|
if (ack_i|err_i) begin
|
$display("MEM ack");
|
$display("MEM ack");
|
dram_v <= dram0_op != `CAS && dram0_op != `INC && dram0_op != `STS && dram0_op != `STMV && dram0_op != `STCMP && dram0_op != `STFND;
|
dram_v <= dram0_op != `CAS && dram0_op != `INC && dram0_op != `STS && dram0_op != `STMV && dram0_op != `STCMP && dram0_op != `STFND;
|
dram_id <= dram0_id;
|
dram_id <= dram0_id;
|
dram_tgt <= dram0_tgt;
|
dram_tgt <= dram0_tgt;
|
dram_exc <= (err_i & dram0_tgt!=7'd0) ? `EXC_DBE : `EXC_NONE;//dram0_exc;
|
dram_exc <= (err_i & (dram0_tgt!=7'd0 || !fnIsLoad(dram0_op))) ? `EX_DBE : `EX_NONE;//dram0_exc;
|
if (dram0_op==`SWCR)
|
if (dram0_op==`SWCR)
|
dram_bus <= {63'd0,resv_i};
|
dram_bus <= {63'd0,resv_i};
|
else
|
else
|
dram_bus <= fnDatai(dram0_op,dram0_fn,dat_i[DBW-1:0],rsel);
|
dram_bus <= fnDatai(dram0_op,dram0_fn,dat_i[DBW-1:0],rsel);
|
dram0_owns_bus <= `FALSE;
|
dram0_owns_bus <= `FALSE;
|
Line 4870... |
Line 5060... |
dram_id <= dram0_id;
|
dram_id <= dram0_id;
|
dram_tgt <= dram0_tgt;
|
dram_tgt <= dram0_tgt;
|
if (ack_i|err_i) begin
|
if (ack_i|err_i) begin
|
$display("MEM ack2");
|
$display("MEM ack2");
|
dram_v <= `VAL;
|
dram_v <= `VAL;
|
dram_exc <= (err_i & dram0_tgt!=7'd0) ? `EXC_DBE : `EXC_NONE;
|
dram_exc <= (err_i & dram0_tgt!=7'd0) ? `EX_DBE : `EX_NONE;
|
dram0_owns_bus <= `FALSE;
|
dram0_owns_bus <= `FALSE;
|
wb_nack();
|
wb_nack();
|
lock_o <= 1'b0;
|
lock_o <= 1'b0;
|
dram0 <= 3'd7;
|
dram0 <= 3'd7;
|
end
|
end
|
Line 4964... |
Line 5154... |
default: begin
|
default: begin
|
$display("Read hit [%h]",dram0_addr);
|
$display("Read hit [%h]",dram0_addr);
|
dram_v <= `TRUE;
|
dram_v <= `TRUE;
|
dram_id <= dram0_id;
|
dram_id <= dram0_id;
|
dram_tgt <= dram0_tgt;
|
dram_tgt <= dram0_tgt;
|
dram_exc <= `EXC_NONE;
|
dram_exc <= `EX_NONE;
|
dram_bus <= fnDatai(dram0_op,dram0_fn,cdat,rsel);
|
dram_bus <= fnDatai(dram0_op,dram0_fn,cdat,rsel);
|
dram0 <= 3'd0;
|
dram0 <= 3'd0;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
Line 5064... |
Line 5254... |
`endif
|
`endif
|
iqentry_a2[n];
|
iqentry_a2[n];
|
dram0_datacmp <= iqentry_a2[n];
|
dram0_datacmp <= iqentry_a2[n];
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
if (iqentry_cmpmv[n])
|
if (iqentry_cmpmv[n])
|
dram0_addr <= iqentry_a1[n] + {sregs[iqentry_fn[n][5:3]],12'h000};
|
dram0_addr <= iqentry_a1[n] + {sregs_base[iqentry_fn[n][5:3]],12'h000};
|
else
|
else
|
dram0_addr <= iqentry_a1[n];
|
dram0_addr <= iqentry_a1[n];
|
dram0_seg <= {sregs[iqentry_fn[n][5:3]],12'h000};
|
dram0_seg <= {sregs_base[iqentry_fn[n][5:3]],12'h000};
|
dram0_lmt <= sregs[iqentry_fn[n][5:3]] + sregs_lmt[iqentry_fn[n][5:3]];
|
dram0_lmt <= sregs_base[iqentry_fn[n][5:3]] + sregs_lmt[iqentry_fn[n][5:3]];
|
// dram0_exc <= (iqentry_a1[n][ABW-1:12] >= sregs_lmt[iqentry_fn[n][5:3]]) ? `EXC_SEGV : `EXC_NONE;
|
// dram0_exc <= (iqentry_a1[n][ABW-1:12] >= sregs_lmt[iqentry_fn[n][5:3]]) ? `EXC_SEGV : `EXC_NONE;
|
`ifdef STRINGOPS
|
`ifdef STRINGOPS
|
src_addr <= iqentry_a1[n] + {sregs[iqentry_fn[n][5:3]],12'h000};
|
src_addr <= iqentry_a1[n] + {sregs_base[iqentry_fn[n][5:3]],12'h000};
|
dst_addr <= iqentry_a2[n] + {sregs[iqentry_fn[n][5:3]],12'h000};
|
dst_addr <= iqentry_a2[n] + {sregs_base[iqentry_fn[n][5:3]],12'h000};
|
`endif
|
`endif
|
`else
|
`else
|
dram0_addr <= iqentry_a1[n];
|
dram0_addr <= iqentry_a1[n];
|
`ifdef STRINGOPS
|
`ifdef STRINGOPS
|
src_addr <= iqentry_a1[n];
|
src_addr <= iqentry_a1[n];
|
Line 5501... |
Line 5691... |
end
|
end
|
endtask
|
endtask
|
|
|
task commit_spr;
|
task commit_spr;
|
input commit_v;
|
input commit_v;
|
input [6:0] commit_tgt;
|
input [7:0] commit_tgt;
|
input [DBW-1:0] commit_bus;
|
input [DBW-1:0] commit_bus;
|
input which;
|
input which;
|
begin
|
begin
|
if (commit_v && commit_tgt[6]) begin
|
if (commit_v && commit_tgt[7:6]==2'h1) begin
|
casex(commit_tgt[5:0])
|
casex(commit_tgt[5:0])
|
6'b00xxxx: begin
|
6'b00xxxx: begin
|
pregs[commit_tgt[3:0]] <= which ? cmt1nyb[commit_tgt[3:0]] : cmt0nyb[commit_tgt[3:0]];//commit_bus[3:0];
|
pregs[commit_tgt[3:0]] <= which ? cmt1nyb[commit_tgt[3:0]] : cmt0nyb[commit_tgt[3:0]];//commit_bus[3:0];
|
$display("pregs[%d]<=%h", commit_tgt[3:0], commit_bus[3:0]);
|
$display("pregs[%d]<=%h", commit_tgt[3:0], commit_bus[3:0]);
|
// $stop;
|
// $stop;
|
Line 5518... |
Line 5708... |
cregs[commit_tgt[3:0]] <= commit_bus;
|
cregs[commit_tgt[3:0]] <= commit_bus;
|
$display("cregs[%d]<=%h", commit_tgt[3:0], commit_bus);
|
$display("cregs[%d]<=%h", commit_tgt[3:0], commit_bus);
|
end
|
end
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
6'b100xxx: begin
|
6'b100xxx: begin
|
sregs[commit_tgt[2:0]] <= commit_bus[DBW-1:12];
|
sregs[{1'b0,commit_tgt[2:0]}] <= commit_bus[31:0];
|
$display("sregs[%d]<=%h", commit_tgt[2:0], commit_bus);
|
$display("sregs[%d]<=%h", commit_tgt[2:0], commit_bus);
|
end
|
end
|
6'b101xxx: sregs_lmt[commit_tgt[2:0]] <= commit_bus[DBW-1:12];
|
6'b101000: sregs[{1'b1,commit_tgt[2:0]}] <= commit_bus[31:0];
|
|
6'b101001: GDT <= commit_bus;
|
|
6'b101011: segsw <= commit_bus[4:0];
|
|
6'b101100: sregs_base[segsw] <= commit_bus[DBW-1:12];
|
|
6'b101101: sregs_lmt[segsw] <= commit_bus[DBW-1:12];
|
|
6'b101111: sregs_acr[segsw] <= commit_bus[15:0];
|
`endif
|
`endif
|
6'b110000:
|
6'b110000:
|
begin
|
begin
|
pregs[0] <= commit_bus[3:0];
|
pregs[0] <= commit_bus[3:0];
|
pregs[1] <= commit_bus[7:4];
|
pregs[1] <= commit_bus[7:4];
|
Line 5546... |
Line 5741... |
pregs[15] <= commit_bus[63:60];
|
pregs[15] <= commit_bus[63:60];
|
end
|
end
|
end
|
end
|
`LCTR: begin lc <= commit_bus; $display("LC <= %h", commit_bus); end
|
`LCTR: begin lc <= commit_bus; $display("LC <= %h", commit_bus); end
|
`ASID: asid <= commit_bus;
|
`ASID: asid <= commit_bus;
|
|
`ifdef VECTOROPS
|
|
`VL: VL <= commit_bus;
|
|
`endif
|
`SR: begin
|
`SR: begin
|
GM <= commit_bus[7:0];
|
GM <= commit_bus[7:0];
|
|
regset <= commit_bus[10:8];
|
GMB <= commit_bus[23:16];
|
GMB <= commit_bus[23:16];
|
imb <= commit_bus[31];
|
imb <= commit_bus[31];
|
im <= commit_bus[15];
|
im <= commit_bus[15];
|
fxe <= commit_bus[12];
|
fxe <= commit_bus[12];
|
end
|
end
|
Line 5618... |
Line 5817... |
// value on the commit bus.
|
// value on the commit bus.
|
casex(regno)
|
casex(regno)
|
6'b00xxxx: fnSpr = {DBW/4{pregs[regno[3:0]]}};
|
6'b00xxxx: fnSpr = {DBW/4{pregs[regno[3:0]]}};
|
6'b01xxxx: fnSpr = cregs[regno[3:0]];
|
6'b01xxxx: fnSpr = cregs[regno[3:0]];
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
6'b100xxx: fnSpr = {sregs[regno[2:0]],12'h000};
|
6'b100xxx: fnSpr = sregs[{1'b0,regno[2:0]}];
|
6'b101xxx: fnSpr = {sregs_lmt[regno[2:0]],12'h000};
|
6'b101000: fnSpr = sregs[{1'b1,regno[2:0]}];
|
|
6'b101001: fnSpr = GDT;
|
|
6'b101100: fnSpr = {sregs_base[segsw],12'h000};
|
|
6'b101101: fnSpr = {sregs_lmt[segsw],12'h000};
|
|
6'b101111: fnSpr = sregs_acr[segsw];
|
`endif
|
`endif
|
6'b110000: if (DBW==64)
|
6'b110000: if (DBW==64)
|
fnSpr = {pregs[15],pregs[14],pregs[13],pregs[12],
|
fnSpr = {pregs[15],pregs[14],pregs[13],pregs[12],
|
pregs[11],pregs[10],pregs[9],pregs[8],
|
pregs[11],pregs[10],pregs[9],pregs[8],
|
pregs[7],pregs[6],pregs[5],pregs[4],
|
pregs[7],pregs[6],pregs[5],pregs[4],
|
Line 5632... |
Line 5835... |
fnSpr = {pregs[7],pregs[6],pregs[5],pregs[4],
|
fnSpr = {pregs[7],pregs[6],pregs[5],pregs[4],
|
pregs[3],pregs[2],pregs[1],pregs[0]};
|
pregs[3],pregs[2],pregs[1],pregs[0]};
|
`TICK: fnSpr = tick;
|
`TICK: fnSpr = tick;
|
`LCTR: fnSpr = lc;
|
`LCTR: fnSpr = lc;
|
`ASID: fnSpr = asid;
|
`ASID: fnSpr = asid;
|
|
`ifdef VECTOROPS
|
|
`VL: fnSpr = VL;
|
|
`endif
|
`SR: begin
|
`SR: begin
|
fnSpr[7:0] = GM;
|
fnSpr[7:0] = GM;
|
|
fnSpr[10:8] = regset;
|
fnSpr[23:16] = GMB;
|
fnSpr[23:16] = GMB;
|
fnSpr[31] = imb;
|
fnSpr[31] = imb;
|
fnSpr[15] = im;
|
fnSpr[15] = im;
|
fnSpr[12] = fxe;
|
fnSpr[12] = fxe;
|
end
|
end
|
|
`ARG1: fnSpr = intarg1;
|
6'd60: fnSpr = spr_bir;
|
6'd60: fnSpr = spr_bir;
|
6'd61:
|
6'd61:
|
casex(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;
|
Line 5700... |
Line 5908... |
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])
|
|
`INT: intarg1 <= iqentry_a1[head];
|
`CLI: begin imcd <= IMCD; 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;
|
Line 5727... |
Line 5936... |
begin
|
begin
|
case(iqentry_fn[head])
|
case(iqentry_fn[head])
|
6'd0: ic_invalidate <= `TRUE;
|
6'd0: ic_invalidate <= `TRUE;
|
6'd1: begin
|
6'd1: begin
|
ic_invalidate_line <= `TRUE;
|
ic_invalidate_line <= `TRUE;
|
ic_lineno <= iqentry_a1[head] + {sregs[3'd7],12'h000};
|
`ifdef SEGMENTATION
|
|
ic_lineno <= iqentry_a1[head] + {sregs_base[3'd7],12'h000};
|
|
`else
|
|
ic_lineno <= iqentry_a1[head];
|
|
`endif
|
end
|
end
|
6'd32: dc_invalidate <= `TRUE;
|
6'd32: dc_invalidate <= `TRUE;
|
6'd33: begin
|
6'd33: begin
|
dc_invalidate_line <= `TRUE;
|
dc_invalidate_line <= `TRUE;
|
dc_lineno <= iqentry_a1[head] + {sregs[iqentry_fn[head][5:3]],12'h000};
|
`ifdef SEGMENTATION
|
|
dc_lineno <= iqentry_a1[head] + {sregs_base[iqentry_fn[head][5:3]],12'h000};
|
|
`else
|
|
dc_lineno <= iqentry_a1[head];
|
|
`endif
|
end
|
end
|
default: ; // do nothing
|
default: ; // do nothing
|
endcase
|
endcase
|
end
|
end
|
default: ;
|
default: ;
|
Line 5750... |
Line 5967... |
// tree to a single if.
|
// tree to a single if.
|
task enque0a;
|
task enque0a;
|
input [2:0] tail;
|
input [2:0] tail;
|
input [2:0] inc;
|
input [2:0] inc;
|
input unlink;
|
input unlink;
|
|
input [2:0] vel;
|
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;
|
Line 5761... |
Line 5979... |
$stop;
|
$stop;
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
`ifdef SEGLIMITS
|
`ifdef SEGLIMITS
|
// If segment limit exceeded and not in the non-segmented area.
|
// If segment limit exceeded and not in the non-segmented area.
|
if (fetchbuf0_pc >= {sregs_lmt[3'd7],12'h000} && fetchbuf0_pc[ABW-1:ABW-4]!=4'hF)
|
if (fetchbuf0_pc >= {sregs_lmt[3'd7],12'h000} && fetchbuf0_pc[ABW-1:ABW-4]!=4'hF)
|
set_exception(tail,8'd244);
|
set_exception(tail,`EX_SEGV);
|
`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.
|
if (fnIsKMOnlyReg(Rt0) && !km && !(opcode0==`SYS || opcode0==`INT))
|
if (fnIsKMOnlyReg(Rt0) && !km && !(opcode0==`SYS || opcode0==`INT))
|
set_exception(tail,8'd245);
|
set_exception(tail,`EX_PRIV);
|
// If attempting to use an undefined instruction
|
// If attempting to use an undefined instruction
|
`ifdef TRAP_ILLEGALOPS
|
`ifdef TRAP_ILLEGALOPS
|
if (fnIsIllegal(opcode0,opcode0==`MLO ? rfoc0[5:0] : fnFunc(fetchbuf0_instr)))
|
if (fnIsIllegal(opcode0,opcode0==`MLO ? rfoc0[5:0] : fnFunc(fetchbuf0_instr)))
|
set_exception(tail,8'd250);
|
set_exception(tail,9'd250);
|
`endif
|
`endif
|
`ifdef DEBUG_LOGIC
|
`ifdef DEBUG_LOGIC
|
if (dbg_ctrl[0] && dbg_ctrl[17:16]==2'b00 && fetchbuf0_pc==dbg_adr0)
|
if (dbg_ctrl[0] && dbg_ctrl[17:16]==2'b00 && fetchbuf0_pc==dbg_adr0)
|
dbg_imatchA0 = `TRUE;
|
dbg_imatchA0 = `TRUE;
|
if (dbg_ctrl[1] && dbg_ctrl[21:20]==2'b00 && fetchbuf0_pc==dbg_adr1)
|
if (dbg_ctrl[1] && dbg_ctrl[21:20]==2'b00 && fetchbuf0_pc==dbg_adr1)
|
Line 5785... |
Line 6003... |
if (dbg_ctrl[3] && dbg_ctrl[29:28]==2'b00 && fetchbuf0_pc==dbg_adr3)
|
if (dbg_ctrl[3] && dbg_ctrl[29:28]==2'b00 && fetchbuf0_pc==dbg_adr3)
|
dbg_imatchA3 = `TRUE;
|
dbg_imatchA3 = `TRUE;
|
if (dbg_imatchA0|dbg_imatchA1|dbg_imatchA2|dbg_imatchA3)
|
if (dbg_imatchA0|dbg_imatchA1|dbg_imatchA2|dbg_imatchA3)
|
dbg_imatchA = `TRUE;
|
dbg_imatchA = `TRUE;
|
if (dbg_imatchA)
|
if (dbg_imatchA)
|
set_exception(tail,8'd243); // Debug exception
|
set_exception(tail,9'd243); // Debug exception
|
`endif
|
`endif
|
if (!exception_set) begin
|
if (!exception_set) begin
|
interrupt_pc =
|
interrupt_pc =
|
// If the previous instruction was an interrupt, then inherit the address
|
// If the previous instruction was an interrupt, then inherit the address
|
(iqentry_op[(tail-3'd1)&7]==`INT && iqentry_v[(tail-3'd1)&7]==`VAL && iqentry_tgt[(tail-3'd1)&7][3:0]==4'hE) ?
|
(iqentry_op[(tail-3'd1)&7]==`INT && iqentry_v[(tail-3'd1)&7]==`VAL && iqentry_tgt[(tail-3'd1)&7][3:0]==4'hE) ?
|
Line 5811... |
Line 6029... |
iqentry_bt [tail] <= fnIsFlowCtrl(opcode0) && predict_taken0;
|
iqentry_bt [tail] <= fnIsFlowCtrl(opcode0) && predict_taken0;
|
iqentry_br [tail] <= opcode0[7:4]==`BR;
|
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_vec [tail] <= fetchbuf0_vec;
|
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;
|
Line 5830... |
Line 6049... |
iqentry_tgt [tail] <= Rt0;
|
iqentry_tgt [tail] <= Rt0;
|
iqentry_preg [tail] <= Pn0;
|
iqentry_preg [tail] <= Pn0;
|
// Need the bypassing on the preg file for write-through register effect.
|
// Need the bypassing on the preg file for write-through register effect.
|
iqentry_pred [tail] <= fnSpr({2'h0,Pn0},fetchbuf0_pc);//pregs[Pn0];
|
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 || opcode0==`SYS) ? fnImm(fetchbuf0_instr) :
|
iqentry_a0[tail] <=
|
|
`ifdef VECTOROPS
|
|
(opcode0==`LVX || opcode0==`SVX) ? {vel,3'b0} :
|
|
`endif
|
|
(opcode0==`INT || opcode0==`SYS || opcode0==`RTF || opcode0==`JSF) ? 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
|
iqentry_r1 [tail] <= Ra0;
|
iqentry_r1 [tail] <= Ra0;
|
iqentry_r2 [tail] <= Rb0;
|
iqentry_r2 [tail] <= Rb0;
|
iqentry_r3 [tail] <= Rc0;
|
iqentry_r3 [tail] <= Rc0;
|
iqentry_rt [tail] <= Rt0;
|
iqentry_rt [tail] <= Rt0;
|
`endif
|
`endif
|
iqentry_a1 [tail] <= fnOpa(opcode0,Ra0,fetchbuf0_instr,rfoa0,fetchbuf0_pc);
|
iqentry_a1 [tail] <= fnOpa(opcode0,Ra0,fetchbuf0_instr,rfoa0,fetchbuf0_pc);
|
iqentry_a2 [tail] <= fnOpb(opcode0,Rb0,fetchbuf0_instr,rfob0,fetchbuf0_pc);
|
iqentry_a2 [tail] <= fnOpb(opcode0,Rb0,fetchbuf0_instr,rfob0,pvrfoa0,fetchbuf0_pc);
|
iqentry_a3 [tail] <= rfoc0;
|
iqentry_a3 [tail] <= fetchbuf0_vec ? pvrfob0 : rfoc0;
|
iqentry_T [tail] <= fnOpt(Rt0,rfot0,fetchbuf0_pc);
|
iqentry_T [tail] <= fnOpt(Rt0,rfot0,vrfot0,fetchbuf0_pc);
|
// The source is set even though the arg might be automatically valid (less logic).
|
// The source is set even though the arg might be automatically valid (less logic).
|
// This is harmless to do. Note there is no source for the 'I' argument.
|
// This is harmless to do. Note there is no source for the 'I' argument.
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn0}];
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn0}];
|
iqentry_a1_s [tail] <= //unlink ? {1'b0, (tail-1)&7} :
|
iqentry_a1_s [tail] <= //unlink ? {1'b0, (tail-1)&7} :
|
rf_source[Ra0];
|
rf_source[Ra0];
|
iqentry_a2_s [tail] <= rf_source[Rb0];
|
iqentry_a2_s [tail] <= rf_source[Rb0];
|
iqentry_a3_s [tail] <= rf_source[Rc0];
|
iqentry_a3_s [tail] <= rf_source[Rc0];
|
|
`ifdef VECTOROPS
|
|
iqentry_a4 [tail] <= pvrfoc0;
|
|
iqentry_a4_s [tail] <= rf_source[Rd0];
|
|
`endif
|
iqentry_T_s [tail] <= rf_source[Rt0];
|
iqentry_T_s [tail] <= rf_source[Rt0];
|
|
|
// Always do this because it's the first queue slot.
|
// Always do this because it's the first queue slot.
|
validate_args10(tail);
|
validate_args10(tail);
|
end
|
end
|
tail0 <= tail0 + inc;
|
tail0 <= tail0 + inc;
|
tail1 <= tail1 + inc;
|
tail1 <= tail1 + inc;
|
tail2 <= tail2 + inc;
|
tail2 <= tail2 + inc;
|
|
// If it's a vector instruction it isn't finished queuing until all the elements
|
|
// have queued. We still need to know however when each element queues so that
|
|
// the element counter can be incremented.
|
|
// Note that the element can't be queued until the vector length is known which
|
|
// is always found in a1.
|
|
`ifdef VECTOROPS
|
|
if (fetchbuf0_vec) begin
|
|
if (fnVecL(fetchbuf0_instr) begin
|
|
queued1v = `VAL;
|
|
queued1 = vel >= VL[6:0];
|
|
// We set allowq to FALSE to disallow a second instruction queue if a vector instruction
|
|
// is being queued.
|
|
allowq = `FALSE;
|
|
end
|
|
// For a specific element we need to wait until after the ele is set and
|
|
// the register file has a chance to be read.
|
|
else begin
|
|
ele <= iqentry_a1[tail];
|
|
queued1 = iqentry_a1_v[tail];
|
|
end
|
|
end
|
|
else
|
|
`endif
|
|
begin
|
queued1 = `TRUE;
|
queued1 = `TRUE;
|
|
end
|
rrmapno <= rrmapno + 3'd1;
|
rrmapno <= rrmapno + 3'd1;
|
end
|
end
|
endtask
|
endtask
|
|
|
task enquePushpopAdd;
|
task enquePushpopAdd;
|
Line 5918... |
Line 6172... |
// This is harmless to do. Note there is no source for the 'I' argument.
|
// This is harmless to do. Note there is no source for the 'I' argument.
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,which ? Pn1 : Pn0}];
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,which ? Pn1 : Pn0}];
|
iqentry_a1_s [tail] <= rf_source[Ra0];
|
iqentry_a1_s [tail] <= rf_source[Ra0];
|
iqentry_a2_s [tail] <= rf_source[Rb0];
|
iqentry_a2_s [tail] <= rf_source[Rb0];
|
iqentry_a3_s [tail] <= rf_source[Rc0];
|
iqentry_a3_s [tail] <= rf_source[Rc0];
|
|
`ifdef VECTOROPS
|
|
iqentry_a4_s [tail] <= rf_source[Rd0];
|
|
`endif
|
iqentry_T_s [tail] <= rf_source[Ra0];
|
iqentry_T_s [tail] <= rf_source[Ra0];
|
// Always do this because it's the first queue slot.
|
// Always do this because it's the first queue slot.
|
iqentry_p_v [tail] <= rf_v [{1'b1,2'h0,which ? Pn1:Pn0}] || ((which ? cond1 : cond0) < 4'h2);
|
iqentry_p_v [tail] <= rf_v [{1'b1,2'h0,which ? Pn1:Pn0}] || ((which ? cond1 : cond0) < 4'h2);
|
iqentry_a1_v [tail] <= rf_v[ which ? Ra1 : Ra0 ];
|
iqentry_a1_v [tail] <= rf_v[ which ? Ra1 : Ra0 ];
|
iqentry_a2_v [tail] <= 1'b1;
|
iqentry_a2_v [tail] <= 1'b1;
|
Line 5937... |
Line 6194... |
task enque0;
|
task enque0;
|
input [2:0] tail;
|
input [2:0] tail;
|
input [2:0] inc;
|
input [2:0] inc;
|
input test_stomp;
|
input test_stomp;
|
input validate_args;
|
input validate_args;
|
|
input [2:0] vel;
|
begin
|
begin
|
|
/*
|
|
`ifdef VECTOROPS
|
|
if (fetchbuf0_vec && VM[vel]==1'b0) begin
|
|
queued1v = iqentry_a1_v[tail];
|
|
if (vel >= iqentry_a1[tail] && iqentry_a1_v[tail])
|
|
queued1 = `TRUE;
|
|
end
|
|
else
|
|
`endif
|
|
*/
|
if (opcode0==`NOP)
|
if (opcode0==`NOP)
|
queued1 = `TRUE; // to update fetch buffers
|
queued1 = `TRUE; // to update fetch buffers
|
`ifdef DEBUG_LOGIC
|
`ifdef DEBUG_LOGIC
|
else
|
else
|
if (dbg_ctrl[7] && !StatusDBG) begin
|
if (dbg_ctrl[7] && !StatusDBG) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
enque0a(tail,3'd2,1'b0);
|
enque0a(tail,3'd2,1'b0,vel);
|
set_exception((tail+1)&7,8'd243);
|
set_exception((tail+1)&7,9'd243);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
// A pop instruction takes 2 queue entries.
|
// A pop instruction takes 2 queue entries.
|
else if (fnIsPop(fetchbuf0_instr)|fnIsPush(fetchbuf0_instr)|opcode0==`LINK) begin
|
else if (fnIsPop(fetchbuf0_instr)|fnIsPush(fetchbuf0_instr)|opcode0==`LINK) begin
|
$display("0 found push/pop");
|
$display("0 found push/pop");
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
$display("enqueing2");
|
$display("enqueing2");
|
enque0a(tail,3'd2,1'b0);
|
enque0a(tail,3'd2,1'b0,vel);
|
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf0_instr),opcode0==`LINK,0,0);
|
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf0_instr),opcode0==`LINK,0,0);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
`ifdef UNLINKOP
|
`ifdef UNLINKOP
|
else if (opcode0==`UNLINK) begin
|
else if (opcode0==`UNLINK) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
enquePushpopAdd(tail,1'b0,1'b0,1'b1,0);
|
enquePushpopAdd(tail,1'b0,1'b0,1'b1,0);
|
enque0a((tail+1)&7,3'd2,1'b1);
|
enque0a((tail+1)&7,3'd2,1'b1,vel);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
`endif
|
`endif
|
|
/*
|
|
`ifdef SEGMENTATION
|
|
else if (fnTargetsSegreg(fetchbuf0_instr)) begin
|
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
|
enque0a(tail,2'd2,0,vel);
|
|
set_exception((tail+1)&7,{6'b100000,Rt0[2:0]}); // Seg load
|
|
allowq = `FALSE;
|
|
end
|
|
end
|
|
`endif
|
|
*/
|
else if (iqentry_v[tail] == `INV) begin
|
else if (iqentry_v[tail] == `INV) begin
|
if ((({fnIsBranch(opcode0), predict_taken0} == {`TRUE, `TRUE})||(opcode0==`LOOP)) && test_stomp)
|
if ((({fnIsBranch(opcode0), predict_taken0} == {`TRUE, `TRUE})||(opcode0==`LOOP)) && test_stomp)
|
qstomp = `TRUE;
|
qstomp = `TRUE;
|
enque0a(tail,inc,0);
|
enque0a(tail,inc,0,vel);
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
task enque1a;
|
task enque1a;
|
input [2:0] tail;
|
input [2:0] tail;
|
input [2:0] inc;
|
input [2:0] inc;
|
input validate_args;
|
input validate_args;
|
input unlink;
|
input unlink;
|
|
input [2:0] vel;
|
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'hFFFC275A)
|
if (fetchbuf1_pc==32'hFFFC275A)
|
$stop;
|
$stop;
|
`ifdef SEGMENTATION
|
`ifdef SEGMENTATION
|
`ifdef SEGLIMITS
|
`ifdef SEGLIMITS
|
if (fetchbuf1_pc >= {sregs_lmt[3'd7],12'h000} && fetchbuf1_pc[ABW-1:ABW-4]!=4'hF)
|
if (fetchbuf1_pc >= {sregs_lmt[3'd7],12'h000} && fetchbuf1_pc[ABW-1:ABW-4]!=4'hF)
|
set_exception(tail,8'd244);
|
set_exception(tail,9'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,9'd245);
|
`ifdef TRAP_ILLEGALOPS
|
`ifdef TRAP_ILLEGALOPS
|
if (fnIsIllegal(opcode1,opcode1==`MLO ? rfoc1[5:0] : fnFunc(fetchbuf1_instr)))
|
if (fnIsIllegal(opcode1,opcode1==`MLO ? rfoc1[5:0] : fnFunc(fetchbuf1_instr)))
|
set_exception(tail,8'd250);
|
set_exception(tail,9'd250);
|
`endif
|
`endif
|
`ifdef DEBUG_LOGIC
|
`ifdef DEBUG_LOGIC
|
if (dbg_ctrl[0] && dbg_ctrl[17:16]==2'b00 && fetchbuf1_pc==dbg_adr0)
|
if (dbg_ctrl[0] && dbg_ctrl[17:16]==2'b00 && fetchbuf1_pc==dbg_adr0)
|
dbg_imatchB0 = `TRUE;
|
dbg_imatchB0 = `TRUE;
|
if (dbg_ctrl[1] && dbg_ctrl[21:20]==2'b00 && fetchbuf1_pc==dbg_adr1)
|
if (dbg_ctrl[1] && dbg_ctrl[21:20]==2'b00 && fetchbuf1_pc==dbg_adr1)
|
Line 6015... |
Line 6295... |
if (dbg_ctrl[3] && dbg_ctrl[29:28]==2'b00 && fetchbuf1_pc==dbg_adr3)
|
if (dbg_ctrl[3] && dbg_ctrl[29:28]==2'b00 && fetchbuf1_pc==dbg_adr3)
|
dbg_imatchB3 = `TRUE;
|
dbg_imatchB3 = `TRUE;
|
if (dbg_imatchB0|dbg_imatchB1|dbg_imatchB2|dbg_imatchB3)
|
if (dbg_imatchB0|dbg_imatchB1|dbg_imatchB2|dbg_imatchB3)
|
dbg_imatchB = `TRUE;
|
dbg_imatchB = `TRUE;
|
if (dbg_imatchB)
|
if (dbg_imatchB)
|
set_exception(tail,8'd243); // debug excpetion
|
set_exception(tail,9'd243); // debug excpetion
|
`endif
|
`endif
|
if (!exception_set) begin
|
if (!exception_set) begin
|
// If an instruction wasn't enqueued or it wasn't an interrupt instruction then
|
// If an instruction wasn't enqueued or it wasn't an interrupt instruction then
|
// the interrupt pc will need to be set. Othersise this enqueue will inherit
|
// the interrupt pc will need to be set. Othersise this enqueue will inherit
|
// from the previous one.
|
// from the previous one.
|
if (!queued1 || !(opcode0==`INT && Rt0[3:0]==4'hE))
|
if (!queued1 || !(opcode0==`INT && Rt0[3:0]==4'hE))
|
interrupt_pc = (iqentry_op[(tail-3'd1)&7]==`INT && iqentry_v[(tail-3'd1)&7]==`VAL && iqentry_tgt[(tail-3'd1)&7][3:0]==4'hE) ?
|
interrupt_pc = (iqentry_op[(tail-3'd1)&7]==`INT && iqentry_v[(tail-3'd1)&7]==`VAL && iqentry_tgt[(tail-3'd1)&7][3:0]==4'hE) ?
|
(string_pc != 0 ? string_pc : iqentry_pc[(tail-3'd1)&7]) :
|
(string_pc != 0 ? string_pc : iqentry_pc[(tail-3'd1)&7]) :
|
(iqentry_op[(tail-3'd1)&7]==`IMM && iqentry_v[(tail-3'd1)&7]==`VAL) ? (string_pc != 0 ? string_pc :
|
(iqentry_op[(tail-3'd1)&7]==`IMM && iqentry_v[(tail-3'd1)&7]==`VAL) ? (string_pc != 0 ? string_pc :
|
iqentry_pc[(tail-3'd1)&7]) : (string_pc != 0 ? string_pc : fetchbuf1_pc);
|
iqentry_pc[(tail-3'd1)&7]) : (string_pc != 0 ? string_pc : fetchbuf1_pc);
|
iqentry_v [tail] <= `VAL;
|
iqentry_v [tail] <= fetchbuf1_vec ? vel < iqentry_a1[tail][2:0] : `VAL;
|
iqentry_done [tail] <= `INV;
|
iqentry_done [tail] <= `INV;
|
iqentry_cmt [tail] <= `TRUE;
|
iqentry_cmt [tail] <= `TRUE;
|
iqentry_out [tail] <= `INV;
|
iqentry_out [tail] <= `INV;
|
iqentry_res [tail] <= `ZERO;
|
iqentry_res [tail] <= `ZERO;
|
iqentry_insnsz[tail] <= fnInsnLength(fetchbuf1_instr);
|
iqentry_insnsz[tail] <= fnInsnLength(fetchbuf1_instr);
|
Line 6065... |
Line 6345... |
iqentry_tgt [tail] <= Rt1;
|
iqentry_tgt [tail] <= Rt1;
|
iqentry_preg [tail] <= Pn1;
|
iqentry_preg [tail] <= Pn1;
|
iqentry_pred [tail] <= fnSpr({2'h0,Pn1},fetchbuf1_pc);//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 || opcode1==`SYS) ? fnImm(fetchbuf1_instr) :
|
iqentry_a0[tail] <=
|
|
`ifdef VECTOROPS
|
|
(opcode1==`LVX || opcode1==`SVX) ? {vel,3'b0} :
|
|
`endif
|
|
(opcode1==`INT || opcode1==`SYS || opcode1==`RTF || opcode1==`JSF) ? 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);
|
iqentry_a1 [tail] <= fnOpa(opcode1,Ra1,fetchbuf1_instr,rfoa1,fetchbuf1_pc);
|
iqentry_a1 [tail] <= fnOpa(opcode1,Ra1,fetchbuf1_instr,rfoa1,fetchbuf1_pc);
|
iqentry_a2 [tail] <= fnOpb(opcode1,Rb1,fetchbuf1_instr,rfob1,fetchbuf1_pc);
|
iqentry_a2 [tail] <= fnOpb(opcode1,Rb1,fetchbuf1_instr,rfob1,pvrfoa1,fetchbuf1_pc);
|
iqentry_a3 [tail] <= rfoc1;
|
iqentry_a3 [tail] <= fetchbuf1_vec ? pvrfob1 : rfoc1;
|
iqentry_T [tail] <= fnOpt(Rt1,rfot1,fetchbuf1_pc);
|
iqentry_T [tail] <= fnOpt(Rt1,rfot1,vrfot1,fetchbuf1_pc);
|
`ifdef SIMULATION
|
`ifdef SIMULATION
|
iqentry_r1 [tail] <= Ra1;
|
iqentry_r1 [tail] <= Ra1;
|
iqentry_r2 [tail] <= Rb1;
|
iqentry_r2 [tail] <= Rb1;
|
iqentry_r3 [tail] <= Rc1;
|
iqentry_r3 [tail] <= Rc1;
|
iqentry_rt [tail] <= Rt1;
|
iqentry_rt [tail] <= Rt1;
|
Line 6088... |
Line 6372... |
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn1}];
|
iqentry_p_s [tail] <= rf_source[{1'b1,2'h0,Pn1}];
|
iqentry_a1_s [tail] <= //unlink ? {1'b0, (tail-3'd1)&7} :
|
iqentry_a1_s [tail] <= //unlink ? {1'b0, (tail-3'd1)&7} :
|
rf_source[Ra1];
|
rf_source[Ra1];
|
iqentry_a2_s [tail] <= rf_source[Rb1];
|
iqentry_a2_s [tail] <= rf_source[Rb1];
|
iqentry_a3_s [tail] <= rf_source[Rc1];
|
iqentry_a3_s [tail] <= rf_source[Rc1];
|
|
`ifdef VECTOROPS
|
|
iqentry_a4 [tail] <= pvrfoc1;
|
|
iqentry_a4_s [tail] <= rf_source[Rd1];
|
|
`endif
|
iqentry_T_s [tail] <= rf_source[Rt1];
|
iqentry_T_s [tail] <= rf_source[Rt1];
|
if (validate_args)
|
if (validate_args)
|
validate_args11(tail);
|
validate_args11(tail);
|
end
|
end
|
tail0 <= tail0 + inc;
|
tail0 <= tail0 + inc;
|
Line 6104... |
Line 6392... |
task enque1;
|
task enque1;
|
input [2:0] tail;
|
input [2:0] tail;
|
input [2:0] inc;
|
input [2:0] inc;
|
input test_stomp;
|
input test_stomp;
|
input validate_args;
|
input validate_args;
|
|
input [2:0] vel;
|
begin
|
begin
|
|
/*
|
|
This bit of code being superceded by vector predicate bits
|
|
`ifdef VECTOROPS
|
|
if (fetchbuf1_vec && VM[vel]==1'b0) begin
|
|
queued1v = iqentry_vl_v[tail];
|
|
if (vel >= iqentry_vl[tail] && iqentry_vl_v[tail])
|
|
queued1 = `TRUE;
|
|
end
|
|
else
|
|
`endif
|
|
*/
|
if (opcode1==`NOP) begin
|
if (opcode1==`NOP) begin
|
if (queued1==`TRUE) queued2 = `TRUE;
|
if (queued1==`TRUE) queued2 = `TRUE;
|
queued1 = `TRUE;
|
queued1 = `TRUE;
|
end
|
end
|
`ifdef DEBUG_LOGIC
|
`ifdef DEBUG_LOGIC
|
else
|
else
|
if (dbg_ctrl[7] && !StatusDBG) begin
|
if (dbg_ctrl[7] && !StatusDBG) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
enque1a(tail,3'd2,1,0);
|
enque1a(tail,3'd2,1,0,vel);
|
set_exception((tail+1)&7,8'd243);
|
set_exception((tail+1)&7,9'd243);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
`ifdef STACKOPS
|
`ifdef STACKOPS
|
Line 6128... |
Line 6428... |
$display("iqv[%d+1]:%d", tail, iqentry_v[tail+1]);
|
$display("iqv[%d+1]:%d", tail, iqentry_v[tail+1]);
|
$display("valargs:%d", validate_args);
|
$display("valargs:%d", validate_args);
|
$display("qd1:%d", queued1);
|
$display("qd1:%d", queued1);
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV && validate_args && !queued1) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV && validate_args && !queued1) begin
|
$display("1 enq 2 ");
|
$display("1 enq 2 ");
|
enque1a(tail,3'd2,1,0);
|
enque1a(tail,3'd2,1,0,vel);
|
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf1_instr),opcode1==`LINK,0,1);
|
enquePushpopAdd((tail+1)&7,fnIsPop(fetchbuf1_instr),opcode1==`LINK,0,1);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
`ifdef UNLINKOP
|
`ifdef UNLINKOP
|
else if (opcode1==`UNLINK) begin
|
else if (opcode1==`UNLINK) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
enquePushpopAdd(tail,1'b0,1'b0,1'b1,1);
|
enquePushpopAdd(tail,1'b0,1'b0,1'b1,1);
|
enque1a((tail+1)&7,3'd2,1,1);
|
enque1a((tail+1)&7,3'd2,1,1,vel);
|
allowq = `FALSE;
|
allowq = `FALSE;
|
end
|
end
|
end
|
end
|
`endif
|
`endif
|
`endif
|
`endif
|
|
/*
|
|
`ifdef SEGMENTATION
|
|
else if (fnTargetsSegreg(fetchbuf1_instr)) begin
|
|
if (iqentry_v[tail]==`INV && iqentry_v[(tail+1)&7]==`INV) begin
|
|
enque1a(tail,2'd2,1,0,vel);
|
|
set_exception((tail+1)&7,{6'b100000,Rt1[2:0]}); // Seg load
|
|
allowq = `FALSE;
|
|
end
|
|
end
|
|
`endif
|
|
*/
|
else if (iqentry_v[tail] == `INV && !qstomp) begin
|
else if (iqentry_v[tail] == `INV && !qstomp) begin
|
if ((({fnIsBranch(opcode1), predict_taken1} == {`TRUE, `TRUE})||(opcode1==`LOOP)) && test_stomp)
|
if ((({fnIsBranch(opcode1), predict_taken1} == {`TRUE, `TRUE})||(opcode1==`LOOP)) && test_stomp)
|
qstomp = `TRUE;
|
qstomp = `TRUE;
|
enque1a(tail,inc,validate_args,0);
|
enque1a(tail,inc,validate_args,0,vel);
|
|
// Note that if there are two instructions ready to queue and the first instruction is a
|
|
// vector instruction then we shouldn't get here because allowq would be false.
|
|
`ifdef VECTOROPS
|
|
if (queued1v==`TRUE) queued2v = fetchbuf1_vec;
|
|
else queued1v = fetchbuf1_vec;
|
|
if (queued1==`TRUE) queued2 = fetchbuf1_vec ? vele >= VL[6:0] : `TRUE;
|
|
else queued1 = fetchbuf1_vec ? vele >= VL[6:0] : `TRUE;
|
|
`else
|
if (queued1==`TRUE) queued2 = `TRUE;
|
if (queued1==`TRUE) queued2 = `TRUE;
|
else queued1 = `TRUE;
|
else queued1 = `TRUE;
|
|
`endif
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
task validate_args10;
|
task validate_args10;
|
input [2:0] tail;
|
input [2:0] tail;
|
begin
|
begin
|
iqentry_p_v [tail] <= rf_v [{1'b1,2'h0,Pn0}] || cond0 < 4'h2;
|
iqentry_p_v [tail] <= rf_v [{1'b1,2'h0,Pn0}] || cond0 < 4'h2;
|
iqentry_a1_v [tail] <= fnSource1_v( opcode0 ) | rf_v[ Ra0 ];
|
iqentry_a1_v [tail] <= fnSource1_v( opcode0 ) | rf_v[ Ra0 ];
|
iqentry_a2_v [tail] <= fnSource2_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[Rb0];
|
iqentry_a2_v [tail] <= (fnSource2_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[Rb0]);// & fnVelv(fetchbuf0_instr);
|
iqentry_a3_v [tail] <= fnSource3_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[ Rc0 ];
|
iqentry_a3_v [tail] <= fnSource3_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[ Rc0 ];
|
|
`ifdef VECTOROPS
|
|
iqentry_a4_v [tail] <= fnSource4_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[ Rd0 ];
|
|
`endif
|
iqentry_T_v [tail] <= fnSourceT_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[ Rt0 ];
|
iqentry_T_v [tail] <= fnSourceT_v( opcode0, fnFunc(fetchbuf0_instr)) | rf_v[ Rt0 ];
|
|
iqentry_velv [tail] <= fnVelv(fetchbuf0_instr);
|
if (fetchbuf0_rfw|fetchbuf0_pfw) begin
|
if (fetchbuf0_rfw|fetchbuf0_pfw) begin
|
$display("regv[%d] = %d", Rt0,rf_v[ Rt0 ]);
|
$display("regv[%d] = %d", Rt0,rf_v[ Rt0 ]);
|
rf_v[ Rt0 ] = fnRegIsAutoValid(Rt0);
|
rf_v[ Rt0 ] = fnRegIsAutoValid(Rt0);
|
$display("reg[%d] <= INV",Rt0);
|
$display("reg[%d] <= INV",Rt0);
|
rf_source[ Rt0 ] <= { fetchbuf0_mem, tail }; // top bit indicates ALU/MEM bus
|
rf_source[ Rt0 ] <= { fetchbuf0_mem, tail }; // top bit indicates ALU/MEM bus
|
Line 6178... |
Line 6502... |
input [2:0] tail;
|
input [2:0] tail;
|
begin
|
begin
|
// The predicate is automatically valid for condiitions 0 and 1 (always false or always true).
|
// The predicate is automatically valid for condiitions 0 and 1 (always false or always true).
|
iqentry_p_v [tail] <= rf_v [{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
|
iqentry_p_v [tail] <= rf_v [{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
|
iqentry_a1_v [tail] <= fnSource1_v( opcode1 ) | rf_v[ Ra1 ];
|
iqentry_a1_v [tail] <= fnSource1_v( opcode1 ) | rf_v[ Ra1 ];
|
iqentry_a2_v [tail] <= fnSource2_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rb1 ];
|
iqentry_a2_v [tail] <= (fnSource2_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rb1 ]);// & fnVelv(fetchbuf1_instr);
|
iqentry_a3_v [tail] <= fnSource3_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rc1 ];
|
iqentry_a3_v [tail] <= fnSource3_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rc1 ];
|
|
`ifdef VECTOROPS
|
|
iqentry_a4_v [tail] <= fnSource3_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rd1 ];
|
|
`endif
|
iqentry_T_v [tail] <= fnSourceT_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rt1 ];
|
iqentry_T_v [tail] <= fnSourceT_v( opcode1, fnFunc(fetchbuf1_instr)) | rf_v[ Rt1 ];
|
|
iqentry_velv [tail] <= fnVelv(fetchbuf1_instr);
|
if (fetchbuf1_rfw|fetchbuf1_pfw) begin
|
if (fetchbuf1_rfw|fetchbuf1_pfw) begin
|
$display("1:regv[%d] = %d", Rt1,rf_v[ Rt1 ]);
|
$display("1:regv[%d] = %d", Rt1,rf_v[ Rt1 ]);
|
rf_v[ Rt1 ] = fnRegIsAutoValid(Rt1);
|
rf_v[ Rt1 ] = fnRegIsAutoValid(Rt1);
|
$display("reg[%d] <= INV",Rt1);
|
$display("reg[%d] <= INV",Rt1);
|
rf_source[ Rt1 ] <= { fetchbuf1_mem, tail }; // top bit indicates ALU/MEM bus
|
rf_source[ Rt1 ] <= { fetchbuf1_mem, tail }; // top bit indicates ALU/MEM bus
|
Line 6196... |
Line 6524... |
|
|
// If two entries were queued then validate the arguments for the second entry.
|
// If two entries were queued then validate the arguments for the second entry.
|
//
|
//
|
task validate_args;
|
task validate_args;
|
begin
|
begin
|
if (queued2) begin
|
if (queued2|queued2v) begin
|
// SOURCE 1 ... this is relatively straightforward, because all instructions
|
// SOURCE 1 ... this is relatively straightforward, because all instructions
|
// that have a source (i.e. every instruction but LUI) read from RB
|
// that have a source (i.e. every instruction but LUI) read from RB
|
//
|
//
|
// if the argument is an immediate or not needed, we're done
|
// if the argument is an immediate or not needed, we're done
|
if (fnSource1_v( opcode1 ) == `VAL) begin
|
if (fnSource1_v( opcode1 ) == `VAL) begin
|
Line 6213... |
Line 6541... |
else if (!fetchbuf0_rfw) begin
|
else if (!fetchbuf0_rfw) begin
|
iqentry_a1_v [tail1] <= rf_v [Ra1];
|
iqentry_a1_v [tail1] <= rf_v [Ra1];
|
iqentry_a1_s [tail1] <= rf_source [Ra1];
|
iqentry_a1_s [tail1] <= rf_source [Ra1];
|
end
|
end
|
// otherwise, previous instruction does write to RF ... see if overlap
|
// otherwise, previous instruction does write to RF ... see if overlap
|
else if (Rt0 != 7'd0 && Ra1 == Rt0) begin
|
else if (Rt0 != 10'd0 && Ra1 == Rt0) begin
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
$display("invalidating iqentry_a1_v[%d]", tail1);
|
$display("invalidating iqentry_a1_v[%d]", tail1);
|
iqentry_a1_v [tail1] <= `INV;
|
iqentry_a1_v [tail1] <= `INV;
|
iqentry_a1_s [tail1] <= {fetchbuf0_mem, tail0};
|
iqentry_a1_s [tail1] <= {fetchbuf0_mem, tail0};
|
end
|
end
|
Line 6226... |
Line 6554... |
iqentry_a1_v [tail1] <= rf_v [Ra1];
|
iqentry_a1_v [tail1] <= rf_v [Ra1];
|
iqentry_a1_s [tail1] <= rf_source [Ra1];
|
iqentry_a1_s [tail1] <= rf_source [Ra1];
|
$display("2:iqentry_a1_s[%d] <= %d", tail1, rf_source [Ra1]);
|
$display("2:iqentry_a1_s[%d] <= %d", tail1, rf_source [Ra1]);
|
end
|
end
|
|
|
if (!fetchbuf0_pfw) begin
|
if (!fetchbuf0_rfw) begin
|
iqentry_p_v [tail1] <= rf_v [{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
|
iqentry_p_v [tail1] <= rf_v [{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
|
iqentry_p_s [tail1] <= rf_source [{1'b1,2'h0,Pn1}];
|
iqentry_p_s [tail1] <= rf_source [{1'b1,2'h0,Pn1}];
|
end
|
end
|
else if ((Rt0 != 7'd0 && (Pn1==Rt0[3:0] || Rt0==7'h70)) && ((Rt0 & 7'h70)==7'h40)||Rt0==7'h70) begin
|
else if ((Rt0 != 8'd0 && (Pn1==Rt0[3:0] || Rt0==8'h70)) && ((Rt0 & 8'h70)==8'h40)||Rt0==8'h70) begin
|
iqentry_p_v [tail1] <= cond1 < 4'h2;
|
iqentry_p_v [tail1] <= cond1 < 4'h2;
|
iqentry_p_s [tail1] <= {fetchbuf0_mem, tail0};
|
iqentry_p_s [tail1] <= {fetchbuf0_mem, tail0};
|
end
|
end
|
else begin
|
else begin
|
iqentry_p_v [tail1] <= rf_v[{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
|
iqentry_p_v [tail1] <= rf_v[{1'b1,2'h0,Pn1}] || cond1 < 4'h2;
|
Line 6254... |
Line 6582... |
else if (!fetchbuf0_rfw) begin
|
else if (!fetchbuf0_rfw) begin
|
iqentry_a2_v [tail1] <= rf_v[ Rb1 ];
|
iqentry_a2_v [tail1] <= rf_v[ Rb1 ];
|
iqentry_a2_s [tail1] <= rf_source[Rb1];
|
iqentry_a2_s [tail1] <= rf_source[Rb1];
|
end
|
end
|
// otherwise, previous instruction does write to RF ... see if overlap
|
// otherwise, previous instruction does write to RF ... see if overlap
|
else if (Rt0 != 7'd0 && Rb1 == Rt0) begin
|
else if (Rt0 != 8'd0 && Rb1 == Rt0) begin
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
iqentry_a2_v [tail1] <= `INV;
|
iqentry_a2_v [tail1] <= `INV;
|
iqentry_a2_s [tail1] <= {fetchbuf0_mem,tail0};
|
iqentry_a2_s [tail1] <= {fetchbuf0_mem,tail0};
|
end
|
end
|
// if no overlap, get info from rf_v and rf_source
|
// if no overlap, get info from rf_v and rf_source
|
Line 6281... |
Line 6609... |
else if (!fetchbuf0_rfw) begin
|
else if (!fetchbuf0_rfw) begin
|
iqentry_a3_v [tail1] <= rf_v [Rc1];
|
iqentry_a3_v [tail1] <= rf_v [Rc1];
|
iqentry_a3_s [tail1] <= rf_source [Rc1];
|
iqentry_a3_s [tail1] <= rf_source [Rc1];
|
end
|
end
|
// otherwise, previous instruction does write to RF ... see if overlap
|
// otherwise, previous instruction does write to RF ... see if overlap
|
else if (Rt0 != 7'd0 && Rc1 == Rt0) begin
|
else if (Rt0 != 8'd0 && Rc1 == Rt0) begin
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
iqentry_a3_v [tail1] <= `INV;
|
iqentry_a3_v [tail1] <= `INV;
|
iqentry_a3_s [tail1] <= {fetchbuf0_mem,tail0};
|
iqentry_a3_s [tail1] <= {fetchbuf0_mem,tail0};
|
end
|
end
|
// if no overlap, get info from rf_v and rf_source
|
// if no overlap, get info from rf_v and rf_source
|
else begin
|
else begin
|
iqentry_a3_v [tail1] <= rf_v [Rc1];
|
iqentry_a3_v [tail1] <= rf_v [Rc1];
|
iqentry_a3_s [tail1] <= rf_source [Rc1];
|
iqentry_a3_s [tail1] <= rf_source [Rc1];
|
end
|
end
|
|
`ifdef VECTOROPS
|
|
if (fnSource4_v( opcode1,fnFunc(fetchbuf1_instr) ) == `VAL) begin
|
|
iqentry_a4_v [tail1] <= `VAL;
|
|
end
|
|
// if previous instruction writes nothing to RF, then get info from rf_v and rf_source
|
|
else if (!fetchbuf0_rfw) begin
|
|
iqentry_a4_v [tail1] <= rf_v [Rd1];
|
|
iqentry_a4_s [tail1] <= rf_source [Rd1];
|
|
end
|
|
// otherwise, previous instruction does write to RF ... see if overlap
|
|
else if (Rt0 != 10'd0 && Rd1 == Rt0) begin
|
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
|
iqentry_a4_v [tail1] <= `INV;
|
|
iqentry_a4_s [tail1] <= {fetchbuf0_mem,tail0};
|
|
end
|
|
// if no overlap, get info from rf_v and rf_source
|
|
else begin
|
|
iqentry_a4_v [tail1] <= rf_v [Rd1];
|
|
iqentry_a4_s [tail1] <= rf_source [Rd1];
|
|
end
|
|
`endif
|
//
|
//
|
// Target 3 ... this is relatively straightforward, because all instructions
|
// Target 3 ... this is relatively straightforward, because all instructions
|
// that have a source (i.e. every instruction but LUI) read from RC
|
// that have a source (i.e. every instruction but LUI) read from RC
|
//
|
//
|
// if the argument is an immediate or not needed, we're done
|
// if the argument is an immediate or not needed, we're done
|
Line 6308... |
Line 6655... |
else if (!fetchbuf0_rfw) begin
|
else if (!fetchbuf0_rfw) begin
|
iqentry_T_v [tail1] <= rf_v [Rt1];
|
iqentry_T_v [tail1] <= rf_v [Rt1];
|
iqentry_T_s [tail1] <= rf_source [Rt1];
|
iqentry_T_s [tail1] <= rf_source [Rt1];
|
end
|
end
|
// otherwise, previous instruction does write to RF ... see if overlap
|
// otherwise, previous instruction does write to RF ... see if overlap
|
else if (Rt0 != 7'd0 && Rt1 == Rt0) begin
|
else if (Rt0 != 8'd0 && Rt1 == Rt0) begin
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
// if the previous instruction is a LW, then grab result from memq, not the iq
|
iqentry_T_v [tail1] <= `INV;
|
iqentry_T_v [tail1] <= `INV;
|
iqentry_T_s [tail1] <= {fetchbuf0_mem,tail0};
|
iqentry_T_s [tail1] <= {fetchbuf0_mem,tail0};
|
end
|
end
|
// if no overlap, get info from rf_v and rf_source
|
// if no overlap, get info from rf_v and rf_source
|
Line 6440... |
Line 6787... |
// set_exception:
|
// set_exception:
|
// Used to requeue the instruction as an exception if an exception occurs.
|
// Used to requeue the instruction as an exception if an exception occurs.
|
|
|
task set_exception;
|
task set_exception;
|
input [2:0] id; // instruction queue id
|
input [2:0] id; // instruction queue id
|
input [7:0] exc; // exception number
|
input [8:0] exc; // exception number
|
begin
|
begin
|
iqentry_op [id[2:0] ] <= `INT;
|
iqentry_op [id[2:0] ] <= `INT;
|
iqentry_cond [id[2:0]] <= 4'd1; // always execute
|
iqentry_cond [id[2:0]] <= 4'd1; // always execute
|
iqentry_mem[id[2:0]] <= `FALSE;
|
iqentry_mem[id[2:0]] <= `FALSE;
|
iqentry_rfw[id[2:0]] <= `TRUE; // writes to IPC
|
iqentry_rfw[id[2:0]] <= `TRUE; // writes to IPC
|
Line 6452... |
Line 6799... |
iqentry_p_v [id[2:0]] <= `TRUE;
|
iqentry_p_v [id[2:0]] <= `TRUE;
|
iqentry_a1 [id[2:0]] <= cregs[4'hC]; // *** assumes BR12 is static
|
iqentry_a1 [id[2:0]] <= cregs[4'hC]; // *** assumes BR12 is static
|
iqentry_a1_v [id[2:0]] <= `TRUE; // Flag arguments as valid
|
iqentry_a1_v [id[2:0]] <= `TRUE; // Flag arguments as valid
|
iqentry_a2_v [id[2:0]] <= `TRUE;
|
iqentry_a2_v [id[2:0]] <= `TRUE;
|
iqentry_a3_v [id[2:0]] <= `TRUE;
|
iqentry_a3_v [id[2:0]] <= `TRUE;
|
|
`ifdef VECTOROPS
|
|
iqentry_a4_v [id[2:0]] <= `TRUE;
|
|
`endif
|
iqentry_T_v [id[2:0]] <= `TRUE;
|
iqentry_T_v [id[2:0]] <= `TRUE;
|
iqentry_out [id[2:0]] <= `FALSE;
|
iqentry_out [id[2:0]] <= `FALSE;
|
iqentry_agen [id[2:0]] <= `FALSE;
|
iqentry_agen [id[2:0]] <= `FALSE;
|
iqentry_tgt[id[2:0]] <= {1'b1,2'h1,(exc==8'd243)?4'hB:4'hD}; // Target EPC
|
iqentry_tgt[id[2:0]] <= {1'b1,2'h1,(exc==9'd243 || exc[8])?4'hB:4'hD}; // Target EPC
|
exception_set = `TRUE;
|
exception_set = `TRUE;
|
end
|
end
|
endtask
|
endtask
|
|
|
// The core should really invalidate all the predicate registers when the
|
// The core should really invalidate all the predicate registers when the
|
Line 6471... |
Line 6821... |
// instruction should be followed with a SYNC instruction to ensure that
|
// instruction should be followed with a SYNC instruction to ensure that
|
// the results are picked up.
|
// the results are picked up.
|
// To be fixed one day.
|
// To be fixed one day.
|
task invalidate_pregs;
|
task invalidate_pregs;
|
input [2:0] tail;
|
input [2:0] tail;
|
input [6:0] Rt;
|
input [7:0] Rt;
|
input mem;
|
input mem;
|
begin
|
begin
|
if (Rt==7'h70) begin
|
if (Rt==8'h70) begin
|
rf_v[7'h40] = `INV;
|
rf_v[8'h40] = `INV;
|
rf_v[7'h41] = `INV;
|
rf_v[8'h41] = `INV;
|
rf_v[7'h42] = `INV;
|
rf_v[8'h42] = `INV;
|
rf_v[7'h43] = `INV;
|
rf_v[8'h43] = `INV;
|
rf_v[7'h44] = `INV;
|
rf_v[8'h44] = `INV;
|
rf_v[7'h45] = `INV;
|
rf_v[8'h45] = `INV;
|
rf_v[7'h46] = `INV;
|
rf_v[8'h46] = `INV;
|
rf_v[7'h47] = `INV;
|
rf_v[8'h47] = `INV;
|
rf_v[7'h48] = `INV;
|
rf_v[8'h48] = `INV;
|
rf_v[7'h49] = `INV;
|
rf_v[8'h49] = `INV;
|
rf_v[7'h4A] = `INV;
|
rf_v[8'h4A] = `INV;
|
rf_v[7'h4B] = `INV;
|
rf_v[8'h4B] = `INV;
|
rf_v[7'h4C] = `INV;
|
rf_v[8'h4C] = `INV;
|
rf_v[7'h4D] = `INV;
|
rf_v[8'h4D] = `INV;
|
rf_v[7'h4E] = `INV;
|
rf_v[8'h4E] = `INV;
|
rf_v[7'h4F] = `INV;
|
rf_v[8'h4F] = `INV;
|
rf_source[7'h40] <= { mem, tail };
|
rf_source[8'h40] <= { mem, tail };
|
rf_source[7'h41] <= { mem, tail };
|
rf_source[8'h41] <= { mem, tail };
|
rf_source[7'h42] <= { mem, tail };
|
rf_source[8'h42] <= { mem, tail };
|
rf_source[7'h43] <= { mem, tail };
|
rf_source[8'h43] <= { mem, tail };
|
rf_source[7'h44] <= { mem, tail };
|
rf_source[8'h44] <= { mem, tail };
|
rf_source[7'h45] <= { mem, tail };
|
rf_source[8'h45] <= { mem, tail };
|
rf_source[7'h46] <= { mem, tail };
|
rf_source[8'h46] <= { mem, tail };
|
rf_source[7'h47] <= { mem, tail };
|
rf_source[8'h47] <= { mem, tail };
|
rf_source[7'h48] <= { mem, tail };
|
rf_source[8'h48] <= { mem, tail };
|
rf_source[7'h49] <= { mem, tail };
|
rf_source[8'h49] <= { mem, tail };
|
rf_source[7'h4A] <= { mem, tail };
|
rf_source[8'h4A] <= { mem, tail };
|
rf_source[7'h4B] <= { mem, tail };
|
rf_source[8'h4B] <= { mem, tail };
|
rf_source[7'h4C] <= { mem, tail };
|
rf_source[8'h4C] <= { mem, tail };
|
rf_source[7'h4D] <= { mem, tail };
|
rf_source[8'h4D] <= { mem, tail };
|
rf_source[7'h4E] <= { mem, tail };
|
rf_source[8'h4E] <= { mem, tail };
|
rf_source[7'h4F] <= { mem, tail };
|
rf_source[8'h4F] <= { mem, tail };
|
|
end
|
|
end
|
|
endtask
|
|
|
|
// The following task looks at a functional unit output bus and assigns results
|
|
// to waiting arguments.
|
|
|
|
task setargs;
|
|
input [3:0] id;
|
|
input v;
|
|
input [DBW-1:0] bus;
|
|
begin
|
|
for (n = 0; n < QENTRIES; n = n + 1)
|
|
begin
|
|
if (iqentry_a1_v[n] == `INV && iqentry_a1_s[n] == id && iqentry_v[n] == `VAL && v == `VAL) begin
|
|
iqentry_a1[n] <= bus;
|
|
iqentry_a1_v[n] <= `VAL;
|
|
end
|
|
if (iqentry_a2_v[n] == `INV && iqentry_a2_s[n] == id && iqentry_v[n] == `VAL && v == `VAL) begin
|
|
iqentry_a2[n] <= bus;
|
|
iqentry_a2_v[n] <= `VAL;
|
|
end
|
|
/*
|
|
if (iqentry_a2_v[n] == `INV && iqentry_a2_sv[n]==`TRUE && iqentry_v[n] && rf_v [{ele,iqentry_rb[n]}]) begin
|
|
iqentry_a2[n] <= vrfob0;
|
|
iqentry_a2_v[n] <= iqentry_velv[n];
|
|
end
|
|
*/
|
|
if (iqentry_a3_v[n] == `INV && iqentry_a3_s[n] == id && iqentry_v[n] == `VAL && v == `VAL) begin
|
|
iqentry_a3[n] <= bus;
|
|
iqentry_a3_v[n] <= `VAL;
|
|
end
|
|
`ifdef VECTOROPS
|
|
if (iqentry_a4_v[n] == `INV && iqentry_a4_s[n] == id && iqentry_v[n] == `VAL && v == `VAL) begin
|
|
iqentry_a4[n] <= bus;
|
|
iqentry_a4_v[n] <= `VAL;
|
|
end
|
|
`endif
|
|
if (iqentry_T_v[n] == `INV && iqentry_T_s[n] == id && iqentry_v[n] == `VAL && v == `VAL) begin
|
|
iqentry_T[n] <= bus;
|
|
iqentry_T_v[n] <= `VAL;
|
|
end
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
endmodule
|
endmodule
|