Line 50... |
Line 50... |
`define EX_RST 9'd511 // Reset
|
`define EX_RST 9'd511 // Reset
|
|
|
`include "Raptor64_opcodes.v"
|
`include "Raptor64_opcodes.v"
|
|
|
module Raptor64sc(rst_i, clk_i, nmi_i, irq_i, irq_no, bte_o, cti_o, bl_o, iocyc_o,
|
module Raptor64sc(rst_i, clk_i, nmi_i, irq_i, irq_no, bte_o, cti_o, bl_o, iocyc_o,
|
cyc_o, stb_o, ack_i, err_i, we_o, sel_o, rsv_o, adr_o, dat_i, dat_o, sys_adv, sys_adr
|
cyc_o, stb_o, ack_i, err_i, we_o, sel_o, rsv_o, adr_o, dat_i, dat_o, sys_adv, sys_adr,
|
|
advanceI, advanceR, advanceX, advanceM1, advanceM2, advanceW, advanceT
|
);
|
);
|
parameter IDLE = 5'd1;
|
parameter IDLE = 5'd1;
|
parameter ICACT = 5'd2;
|
parameter ICACT = 5'd2;
|
parameter ICACT1 = 5'd4;
|
parameter ICACT1 = 5'd4;
|
parameter ICACT2 = 5'd5;
|
parameter ICACT2 = 5'd5;
|
Line 65... |
Line 66... |
parameter RUN = 4'd1;
|
parameter RUN = 4'd1;
|
input rst_i;
|
input rst_i;
|
input clk_i;
|
input clk_i;
|
input nmi_i;
|
input nmi_i;
|
input irq_i;
|
input irq_i;
|
input [4:0] irq_no;
|
input [8:0] irq_no;
|
|
|
output [1:0] bte_o; // burst type
|
output [1:0] bte_o; // burst type
|
reg [1:0] bte_o;
|
reg [1:0] bte_o;
|
output [2:0] cti_o; // cycle type
|
output [2:0] cti_o; // cycle type
|
reg [2:0] cti_o;
|
reg [2:0] cti_o;
|
Line 96... |
Line 97... |
reg [63:0] dat_o;
|
reg [63:0] dat_o;
|
|
|
input sys_adv;
|
input sys_adv;
|
input [63:5] sys_adr;
|
input [63:5] sys_adr;
|
|
|
|
output advanceI;
|
|
output advanceR;
|
|
output advanceX;
|
|
output advanceM1;
|
|
output advanceM2;
|
|
output advanceW;
|
|
output advanceT;
|
|
|
|
wire clk;
|
reg [3:0] state;
|
reg [3:0] state;
|
reg [5:0] fltctr;
|
reg [5:0] fltctr;
|
wire fltdone = fltctr==6'd0;
|
wire fltdone = fltctr==6'd0;
|
reg bu_im; // interrupt mask
|
reg bu_im; // interrupt mask
|
reg im1; // temporary interrupt mask for LM/SM
|
reg im1; // temporary interrupt mask for LM/SM
|
Line 420... |
Line 430... |
reg [63:0] next_m_z;
|
reg [63:0] next_m_z;
|
reg [63:0] next_m_w;
|
reg [63:0] next_m_w;
|
|
|
always @(m_z or m_w)
|
always @(m_z or m_w)
|
begin
|
begin
|
next_m_z <= (36'h3696936969 * m_z[31:0]) + m_z[63:32];
|
next_m_z <= (36'd3696936969 * m_z[31:0]) + m_z[63:32];
|
next_m_w <= (36'h1800018000 * m_w[31:0]) + m_w[63:32];
|
next_m_w <= (36'd1800018000 * m_w[31:0]) + m_w[63:32];
|
end
|
end
|
|
|
wire [63:0] rand = {m_z[31:0],32'd0} + m_w;
|
wire [63:0] rand = {m_z[31:0],32'd0} + m_w;
|
|
|
wire [10:0] bias = 11'h3FF; // bias amount (eg 127)
|
wire [10:0] bias = 11'h3FF; // bias amount (eg 127)
|
Line 1511... |
Line 1521... |
wire m2needBus = m2IsLoad || m2IsStore;
|
wire m2needBus = m2IsLoad || m2IsStore;
|
|
|
wire xRtz = xRt[4:0]==5'd0;
|
wire xRtz = xRt[4:0]==5'd0;
|
wire m1Rtz = m1Rt[4:0]==5'd0;
|
wire m1Rtz = m1Rt[4:0]==5'd0;
|
wire m2Rtz = m2Rt[4:0]==5'd0;
|
wire m2Rtz = m2Rt[4:0]==5'd0;
|
|
wire wRtz = wRt[4:0]==5'd0;
|
|
wire tRtz = tRt[4:0]==5'd0;
|
|
|
//wire StallI = dIsLSPair & ~dIR[15];
|
//wire StallI = dIsLSPair & ~dIR[15];
|
wire intPending = nmi_edge || (irq_i & ~im); // || ITLBMiss
|
wire intPending = (nmi_edge & ~StatusHWI) || (irq_i & ~im & ~StatusHWI); // || ITLBMiss
|
|
|
// Check if there are results being forwarded, to allow the pipeline to empty if result
|
// Check if there are results being forwarded, to allow the pipeline to empty if result
|
// forwarding isn't needed.
|
// forwarding isn't needed.
|
wire tForwardingActive = tRt==dRa || tRt==dRb || tRt==dRc;
|
wire tForwardingActive = (tRt==dRa || tRt==dRb || tRt==dRc) & !tRtz;
|
wire wForwardingActive = wRt==dRa || wRt==dRb || wRt==dRc;
|
wire wForwardingActive = (wRt==dRa || wRt==dRb || wRt==dRc) & !wRtz;
|
wire m2ForwardingActive = m2Rt==dRa || m2Rt==dRb || m2Rt==dRc;
|
wire m2ForwardingActive = (m2Rt==dRa || m2Rt==dRb || m2Rt==dRc) & !m2Rtz;
|
wire m1ForwardingActive = m1Rt==dRa || m1Rt==dRb || m1Rt==dRc;
|
wire m1ForwardingActive = (m1Rt==dRa || m1Rt==dRb || m1Rt==dRc) & !m1Rtz;
|
wire xForwardingActive = xRt==dRa || xRt==dRb || xRt==dRc;
|
wire xForwardingActive = (xRt==dRa || xRt==dRb || xRt==dRc) & !xRtz;
|
wire memCycleActive = ((iocyc_o & !(ack_i|err_i)) || (cyc_o & !(ack_i|err_i)));
|
wire memCycleActive = ((iocyc_o & !(ack_i|err_i)) || (cyc_o & !(ack_i|err_i)));
|
wire StallI = 1'b0;
|
wire StallI = 1'b0;
|
|
|
// Stall on SWC allows rsf flag to be loaded for the next instruction
|
// Stall on SWC allows rsf flag to be loaded for the next instruction
|
// Could check for dRa,dRb,dRc==0, for non-stalling
|
// Could check for dRa,dRb,dRc==0, for non-stalling
|
wire StallR = ((( xIsLoad||xIsIn||xIsCnt) && (xForwardingActive) && !xRtz) || xIsSWC) ||
|
wire StallR = ((( xIsLoad||xIsIn||xIsCnt) && xForwardingActive) || xIsSWC) ||
|
(((m1IsLoad||m1IsIn||m1IsCnt) && (m1ForwardingActive) && !m1Rtz)) ||
|
(((m1IsLoad||m1IsIn||m1IsCnt) && m1ForwardingActive)) ||
|
(((m2IsLoad||m2IsCnt) && (m2ForwardingActive) && !m2Rtz))
|
(((m2IsLoad||m2IsCnt) && m2ForwardingActive))
|
;
|
;
|
wire StallX = ((xneedBus||xIsLoad||xIsStore) & (m1needBus|m2needBus|icaccess));
|
wire StallX = ((xneedBus||xIsLoad||xIsStore) & (m1needBus|m2needBus|icaccess));
|
wire StallM1 = (m1needBus & (m2needBus|icaccess)) ||
|
wire StallM1 = (m1needBus & (m2needBus|icaccess)) ||
|
( m1IsLoad & m1IsCacheElement & (m2IsStore|wIsStore)) || // wait for a preceding store to complete
|
( m1IsLoad & m1IsCacheElement & (m2IsStore|wIsStore)) || // wait for a preceding store to complete
|
memCycleActive
|
memCycleActive
|
Line 1568... |
Line 1580... |
assign advanceR = advanceX & !StallR;
|
assign advanceR = advanceX & !StallR;
|
assign advanceI = advanceR & (ICacheAct ? ihit : ibufrdy) & !StallI;
|
assign advanceI = advanceR & (ICacheAct ? ihit : ibufrdy) & !StallI;
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Cache loading control
|
// Cache loading control
|
|
//
|
|
// There are two triggers for instruction loading depending on whether or not
|
|
// the icache is active.
|
|
// For the instruction cache load we wait until there are no more memory or
|
|
// I/O operations active. An instruction cache load is taking place and that
|
|
// cost is probably at least a dozen cycles (8*memory clocks+3latency).
|
|
// In the data cache case we know that there is a memory operation about to
|
|
// execute in the M1 stage because it's the data cache miss instruction. So
|
|
// there are no other memory operations active. We wait for the prior operation
|
|
// to clear from the M2 stage.
|
|
// The point is to avoid a memory operation colliding with cache access. We
|
|
// could maybe just test for the stb_o line but it gets complex.
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
wire pipelineEmpty =
|
wire pipelineEmpty = (dOpcode==`NOPI) && // and the pipeline is flushed
|
(dOpcode==`NOPI) && // and the pipeline is flushed
|
|
(xOpcode==`NOPI) &&
|
(xOpcode==`NOPI) &&
|
(m1Opcode==`NOPI) &&
|
(m1Opcode==`NOPI) &&
|
(m2Opcode==`NOPI)
|
(m2Opcode==`NOPI)
|
;
|
;
|
wire triggerDCacheLoad = (m1IsLoad & m1IsCacheElement & !dhit) && // there is a miss
|
wire triggerDCacheLoad = (m1IsLoad & m1IsCacheElement & !dhit) && // there is a miss
|
!(icaccess | dcaccess) && // caches are not active
|
!(icaccess | dcaccess) && // caches are not active
|
(m2Opcode==`NOPI); // and the pipeline is free of memory-ops
|
(m2Opcode==`NOPI); // and the pipeline is free of memory-ops
|
;
|
|
wire triggerICacheLoad1 = ICacheAct && !ihit && !triggerDCacheLoad && // There is a miss
|
wire triggerICacheLoad1 = ICacheAct && !ihit && !triggerDCacheLoad && // There is a miss
|
!(icaccess | dcaccess) && // caches are not active
|
!(icaccess | dcaccess) && // caches are not active
|
pipelineEmpty;
|
pipelineEmpty;
|
wire triggerICacheLoad2 = (!ICacheAct && !ibufrdy) && !triggerDCacheLoad && // There is a miss
|
wire triggerICacheLoad2 = (!ICacheAct && !ibufrdy) && !triggerDCacheLoad && // There is a miss
|
!(icaccess | dcaccess) && // caches are not active
|
!(icaccess | dcaccess) && // caches are not active
|
Line 1735... |
Line 1758... |
|
|
wire isxIRQ = ((xIR[15:7]>=`EX_IRQ && xIR[15:7] < `EX_IRQ+32) || xIR[15:7]==`EX_NMI) && xIR[16];
|
wire isxIRQ = ((xIR[15:7]>=`EX_IRQ && xIR[15:7] < `EX_IRQ+32) || xIR[15:7]==`EX_NMI) && xIR[16];
|
wire isPipeIRQ = dextype==`EX_NMI || (dextype>=`EX_IRQ && dextype < `EX_IRQ+32);
|
wire isPipeIRQ = dextype==`EX_NMI || (dextype>=`EX_IRQ && dextype < `EX_IRQ+32);
|
wire isxNonHWI = (xIR[15:7]!=`EX_NMI &&
|
wire isxNonHWI = (xIR[15:7]!=`EX_NMI &&
|
!(xIR[15:7]>=`EX_IRQ && xIR[15:7] < `EX_IRQ+32) &&
|
!(xIR[15:7]>=`EX_IRQ && xIR[15:7] < `EX_IRQ+32) &&
|
xIR[15:7]!=`EX_TLBI || xIR[15:7]!=`EX_TLBD);
|
xIR[15:7]!=`EX_TLBI && xIR[15:7]!=`EX_TLBD);
|
|
wire IRQinPipe = intPending || isPipeIRQ;
|
|
|
always @(posedge clk)
|
always @(posedge clk)
|
if (rst_i) begin
|
if (rst_i) begin
|
bte_o <= 2'b00;
|
bte_o <= 2'b00;
|
cti_o <= 3'b000;
|
cti_o <= 3'b000;
|
Line 1889... |
Line 1913... |
// a system call.
|
// a system call.
|
if (nmi_edge & !StatusHWI) begin
|
if (nmi_edge & !StatusHWI) begin
|
$display("*****************");
|
$display("*****************");
|
$display("NMI edge detected");
|
$display("NMI edge detected");
|
$display("*****************");
|
$display("*****************");
|
ie_fuse <= 8'h00;
|
|
StatusHWI <= 1'b1;
|
|
dextype <= `EX_NMI;
|
dextype <= `EX_NMI;
|
dNmi <= 1'b1;
|
dNmi <= 1'b1;
|
dIR <= {`MISC,9'd0,`EX_NMI,`SYSCALL};
|
dIR <= {`MISC,9'd0,`EX_NMI,`SYSCALL};
|
end
|
end
|
else if (irq_i & !im & !StatusHWI) begin
|
else if (irq_i & !im & !StatusHWI) begin
|
$display("*****************");
|
$display("*****************");
|
$display("IRQ detected");
|
$display("IRQ %d detected", irq_no);
|
$display("*****************");
|
$display("*****************");
|
ie_fuse <= 8'h00;
|
dIR <= {`MISC,9'd0,irq_no,`SYSCALL};
|
StatusHWI <= 1'b1;
|
$display("setting dIR=%h", {`MISC,9'd0,irq_no,`SYSCALL});
|
dIR <= {`MISC,9'd0,`EX_IRQ|irq_no,`SYSCALL};
|
dextype <= irq_no;
|
dextype <= `EX_IRQ|irq_no;
|
|
end
|
end
|
`ifdef TLB
|
`ifdef TLB
|
// A TLB miss is treated like a hardware interrupt.
|
// A TLB miss is treated like a hardware interrupt.
|
else if (ITLBMiss) begin
|
else if (ITLBMiss) begin
|
$display("TLB miss on instruction fetch.");
|
$display("TLB miss on instruction fetch.");
|
Line 2145... |
Line 2166... |
`FIP: begin
|
`FIP: begin
|
// In case we stomped on am interrupt, we have to re-enable
|
// In case we stomped on am interrupt, we have to re-enable
|
// interrupts which were disable in the I-Stage. We go backwards
|
// interrupts which were disable in the I-Stage. We go backwards
|
// in time and set the interrupt status to what it used to be
|
// in time and set the interrupt status to what it used to be
|
// when this instruction is executed.
|
// when this instruction is executed.
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2158... |
Line 2177... |
xFip <= 1'b1;
|
xFip <= 1'b1;
|
m1Fip <= 1'b1;
|
m1Fip <= 1'b1;
|
end
|
end
|
`IEPP: begin
|
`IEPP: begin
|
eptr <= eptr + 8'd1;
|
eptr <= eptr + 8'd1;
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2194... |
Line 2211... |
end
|
end
|
`ERET:
|
`ERET:
|
if (StatusEXL[xAXC]) begin
|
if (StatusEXL[xAXC]) begin
|
StatusEXL[xAXC] <= 1'b0;
|
StatusEXL[xAXC] <= 1'b0;
|
pc <= EPC[xAXC];
|
pc <= EPC[xAXC];
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2215... |
Line 2230... |
// the IRQ SYSCALL. If nested interrupts were happening, the IRET at the
|
// the IRQ SYSCALL. If nested interrupts were happening, the IRET at the
|
// end of the real IRQ routine would re-enable interrupts too soon.
|
// end of the real IRQ routine would re-enable interrupts too soon.
|
`SYSCALL:
|
`SYSCALL:
|
begin
|
begin
|
if (isxIRQ && // Is this a software IRQ SYSCALL ?
|
if (isxIRQ && // Is this a software IRQ SYSCALL ?
|
(isPipeIRQ || intPending)) begin // Is there an interrupt in the pipeline ? OR about to happen
|
IRQinPipe) begin // Is there an interrupt in the pipeline ? OR about to happen
|
m1IR <= `NOP_INSN; // Then turn this into a NOP
|
m1IR <= `NOP_INSN; // Then turn this into a NOP
|
m1Rt <= 9'd0;
|
m1Rt <= 9'd0;
|
end
|
end
|
else begin
|
else begin
|
if (isxNonHWI) begin
|
if (isxNonHWI)
|
StatusEXL[xAXC] <= 1'b1;
|
StatusEXL[xAXC] <= 1'b1;
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
end
|
|
else begin
|
else begin
|
StatusHWI <= 1'b1;
|
StatusHWI <= 1'b1;
|
ie_fuse <= 8'h00;
|
ie_fuse <= 8'h00;
|
if (xNmi)
|
if (xNmi)
|
nmi_edge <= 1'b0;
|
nmi_edge <= 1'b0;
|
Line 2252... |
Line 2264... |
case(xFunc6)
|
case(xFunc6)
|
`EXEC:
|
`EXEC:
|
begin
|
begin
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
dIR <= b;
|
dIR <= b;
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2303... |
Line 2313... |
`JAL:
|
`JAL:
|
`ifdef BTB
|
`ifdef BTB
|
if (dpc[63:2] != a[63:2] + imm[63:2]) begin
|
if (dpc[63:2] != a[63:2] + imm[63:2]) begin
|
pc[63:2] <= a[63:2] + imm[63:2];
|
pc[63:2] <= a[63:2] + imm[63:2];
|
btb[xpc[7:2]] <= {a[63:2] + imm[63:2],2'b00};
|
btb[xpc[7:2]] <= {a[63:2] + imm[63:2],2'b00};
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
`else
|
`else
|
begin
|
begin
|
pc[63:2] <= a[63:2] + imm[63:2];
|
pc[63:2] <= a[63:2] + imm[63:2];
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2330... |
Line 2336... |
// we predicted the RET return correctly, so there's nothing to do. Otherwise
|
// we predicted the RET return correctly, so there's nothing to do. Otherwise
|
// we need to branch to the RET location.
|
// we need to branch to the RET location.
|
`RET:
|
`RET:
|
if (dpc[63:2]!=b[63:2]) begin
|
if (dpc[63:2]!=b[63:2]) begin
|
pc[63:2] <= b[63:2];
|
pc[63:2] <= b[63:2];
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2345... |
Line 2349... |
// BEQ r1,r2,label
|
// BEQ r1,r2,label
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR,`LOOP,`BRA,`BRN:
|
`BEQ,`BNE,`BLT,`BLE,`BGT,`BGE,`BLTU,`BLEU,`BGTU,`BGEU,`BAND,`BOR,`BNR,`LOOP,`BRA,`BRN:
|
if (!takb & xbranch_taken) begin
|
if (!takb & xbranch_taken) begin
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
else if (takb & !xbranch_taken) begin
|
else if (takb & !xbranch_taken) begin
|
$display("Taking branch %h",{xpc[63:2] + {{52{xIR[14]}},xIR[14:5]},2'b00});
|
$display("Taking branch %h",{xpc[63:2] + {{52{xIR[14]}},xIR[14:5]},2'b00});
|
pc[63:2] <= xpc[63:2] + {{52{xIR[14]}},xIR[14:5]};
|
pc[63:2] <= xpc[63:2] + {{52{xIR[14]}},xIR[14:5]};
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2372... |
Line 2372... |
pc[63:2] <= c[63:2];
|
pc[63:2] <= c[63:2];
|
pc[1:0] <= 2'b00;
|
pc[1:0] <= 2'b00;
|
`ifdef BTB
|
`ifdef BTB
|
btb[xpc[7:2]] <= c;
|
btb[xpc[7:2]] <= c;
|
`endif
|
`endif
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2391... |
Line 2389... |
if ((xbranch_taken && b[63:2]!=dpc[63:2]) || // took branch, but not to right target
|
if ((xbranch_taken && b[63:2]!=dpc[63:2]) || // took branch, but not to right target
|
!xbranch_taken) begin // didn't take branch, and were supposed to
|
!xbranch_taken) begin // didn't take branch, and were supposed to
|
pc[63:2] <= b[63:2];
|
pc[63:2] <= b[63:2];
|
pc[1:0] <= 2'b00;
|
pc[1:0] <= 2'b00;
|
btb[xpc[7:2]] <= b;
|
btb[xpc[7:2]] <= b;
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
else if (xbranch_taken) begin // took the branch, and weren't supposed to
|
else if (xbranch_taken) begin // took the branch, and weren't supposed to
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
`else
|
`else
|
if (takb) begin
|
if (takb) begin
|
pc[63:2] <= b[63:2];
|
pc[63:2] <= b[63:2];
|
pc[1:0] <= 2'b00;
|
pc[1:0] <= 2'b00;
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2428... |
Line 2420... |
// BEQI r1,#3,label
|
// BEQI r1,#3,label
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
|
if (takb) begin
|
if (takb) begin
|
if (!xbranch_taken) begin
|
if (!xbranch_taken) begin
|
pc[63:2] <= xpc[63:2] + {{50{xIR[19]}},xIR[19:8]};
|
pc[63:2] <= xpc[63:2] + {{50{xIR[19]}},xIR[19:8]};
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2441... |
Line 2431... |
end
|
end
|
else begin
|
else begin
|
if (xbranch_taken) begin
|
if (xbranch_taken) begin
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
$display("Taking mispredicted branch %h",fnIncPC(xpc));
|
pc <= fnIncPC(xpc);
|
pc <= fnIncPC(xpc);
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2454... |
Line 2442... |
end
|
end
|
`TRAPcc,`TRAPcci:
|
`TRAPcc,`TRAPcci:
|
if (takb) begin
|
if (takb) begin
|
StatusEXL[xAXC] <= 1'b1;
|
StatusEXL[xAXC] <= 1'b1;
|
xextype <= `EX_TRAP;
|
xextype <= `EX_TRAP;
|
StatusHWI <= xStatusHWI;
|
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= 9'd0;
|
xRt <= 9'd0;
|
Line 2721... |
Line 2707... |
if (dbz_error) begin
|
if (dbz_error) begin
|
$display("Divide by zero error");
|
$display("Divide by zero error");
|
LoadNOPs <= #1 1'b1;
|
LoadNOPs <= #1 1'b1;
|
// Squash a pending IRQ, but not an NMI
|
// Squash a pending IRQ, but not an NMI
|
m1extype <= #1 `EX_DBZ;
|
m1extype <= #1 `EX_DBZ;
|
StatusHWI <= xStatusHWI;
|
m1IR <= #1 `NOP_INSN;
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= #1 9'd0;
|
xRt <= #1 9'd0;
|
end
|
end
|
else if (ovr_error) begin
|
else if (ovr_error) begin
|
$display("Overflow error");
|
$display("Overflow error");
|
LoadNOPs <= 1'b1;
|
LoadNOPs <= 1'b1;
|
m1extype <= `EX_OFL;
|
m1extype <= `EX_OFL;
|
StatusHWI <= xStatusHWI;
|
m1IR <= #1 `NOP_INSN;
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= #1 9'd0;
|
xRt <= #1 9'd0;
|
end
|
end
|
// else if (priv_violation) begin
|
// else if (priv_violation) begin
|
// $display("Priviledge violation");
|
// $display("Priviledge violation");
|
|
// m1IR <= #1 `NOP_INSN;
|
// LoadNOPs <= 1'b1;
|
// LoadNOPs <= 1'b1;
|
// if (!xNmi&!dNmi) begin
|
// if (!xNmi&!dNmi) begin
|
// m1extype <= `EX_PRIV;
|
// m1extype <= `EX_PRIV;
|
// StatusHWI <= xStatusHWI;
|
|
// ie_fuse[0] <= ~xIm;
|
|
// end
|
// end
|
// dIR <= #1 `NOP_INSN;
|
// dIR <= #1 `NOP_INSN;
|
// xIR <= #1 `NOP_INSN;
|
// xIR <= #1 `NOP_INSN;
|
// xRt <= #1 9'd0;
|
// xRt <= #1 9'd0;
|
// end
|
// end
|
else if (illegal_insn) begin
|
else if (illegal_insn) begin
|
$display("Unimplemented Instruction");
|
$display("Unimplemented Instruction");
|
LoadNOPs <= 1'b1;
|
LoadNOPs <= 1'b1;
|
m1extype <= `EX_UNIMP_INSN;
|
m1extype <= `EX_UNIMP_INSN;
|
StatusHWI <= xStatusHWI;
|
m1IR <= #1 `NOP_INSN;
|
ie_fuse[0] <= ~xIm;
|
|
if (!xNmi&!dNmi) begin
|
if (!xNmi&!dNmi) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
xIR <= `NOP_INSN;
|
end
|
end
|
xRt <= #1 9'd0;
|
xRt <= #1 9'd0;
|
Line 2819... |
Line 2801... |
m2IsStore <= m2IsStore;
|
m2IsStore <= m2IsStore;
|
|
|
if (m1IsIO & err_i) begin
|
if (m1IsIO & err_i) begin
|
m2extype <= `EX_DBERR;
|
m2extype <= `EX_DBERR;
|
errorAddress <= adr_o;
|
errorAddress <= adr_o;
|
|
m2IR <= #1 `NOP_INSN;
|
end
|
end
|
|
|
if (m1extype == `EX_NON) begin
|
|
case(m1Opcode)
|
case(m1Opcode)
|
`MISC:
|
`MISC:
|
case(m1Func)
|
case(m1Func)
|
`SYSCALL:
|
`SYSCALL:
|
if (!m1IsCacheElement) begin
|
if (!m1IsCacheElement) begin
|
Line 2871... |
Line 2853... |
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
m2Data <= {{48{data16[15]}},data16};
|
m2Data <= {{48{data16[15]}},data16};
|
end
|
end
|
`INCU:
|
`INCU:
|
begin
|
begin
|
iocyc_o <= 1'b0;
|
iocyc_o <= #1 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= #1 1'b0;
|
sel_o <= 8'h00;
|
sel_o <= #1 8'h00;
|
m2Data <= data16;
|
m2Data <= #1 data16;
|
end
|
end
|
`INB:
|
`INB:
|
begin
|
begin
|
iocyc_o <= 1'b0;
|
iocyc_o <= #1 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= #1 1'b0;
|
sel_o <= 8'h00;
|
sel_o <= #1 8'h00;
|
m2Data <= {{56{data8[7]}},data8};
|
m2Data <= #1 {{56{data8[7]}},data8};
|
end
|
end
|
`INBU:
|
`INBU:
|
begin
|
begin
|
iocyc_o <= 1'b0;
|
iocyc_o <= #1 1'b0;
|
stb_o <= 1'b0;
|
stb_o <= #1 1'b0;
|
sel_o <= 8'h00;
|
sel_o <= #1 8'h00;
|
m2Data <= data8;
|
m2Data <= #1 data8;
|
end
|
end
|
`OUTW,`OUTH,`OUTC,`OUTB,`OUTBC:
|
`OUTW,`OUTH,`OUTC,`OUTB,`OUTBC:
|
begin
|
begin
|
iocyc_o <= #1 1'b0;
|
iocyc_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
stb_o <= #1 1'b0;
|
Line 3102... |
Line 3084... |
else
|
else
|
m2IR <= `NOP_INSN;
|
m2IR <= `NOP_INSN;
|
end
|
end
|
`endif
|
`endif
|
endcase
|
endcase
|
end
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Check for a TLB miss.
|
// Check for a TLB miss.
|
// On a prefetch load, just switch the opcode to a NOP
|
// On a prefetch load, just switch the opcode to a NOP
|
// instruction and ignore the error. Otherwise set the
|
// instruction and ignore the error. Otherwise set the
|
// exception type.
|
// exception type.
|
Line 3178... |
Line 3160... |
if (((m2IsLoad&&m2Rt[4:0]!=5'd0)|m2IsStore) & err_i) begin
|
if (((m2IsLoad&&m2Rt[4:0]!=5'd0)|m2IsStore) & err_i) begin
|
wextype <= #1 `EX_DBERR;
|
wextype <= #1 `EX_DBERR;
|
errorAddress <= #1 adr_o;
|
errorAddress <= #1 adr_o;
|
end
|
end
|
|
|
if (m2extype==`EX_NON) begin
|
|
case(m2Opcode)
|
case(m2Opcode)
|
`MISC:
|
`MISC:
|
if (m2Func==`SYSCALL)
|
if (m2Func==`SYSCALL)
|
begin
|
begin
|
cyc_o <= #1 1'b0;
|
cyc_o <= #1 1'b0;
|
Line 3252... |
Line 3233... |
endcase
|
endcase
|
// Force stack pointer to word alignment
|
// Force stack pointer to word alignment
|
if (m2Rt[4:0]==5'b11110)
|
if (m2Rt[4:0]==5'b11110)
|
wData[2:0] <= 3'b000;
|
wData[2:0] <= 3'b000;
|
end
|
end
|
end
|
|
// Stage tail
|
// Stage tail
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
// Pipeline annul for when a bubble in the pipeline occurs.
|
else if (advanceW) begin
|
else if (advanceW) begin
|
wIR <= #1 `NOP_INSN;
|
wIR <= #1 `NOP_INSN;
|
wextype <= `EX_NON;
|
wextype <= `EX_NON;
|