Line 60... |
Line 60... |
(
|
(
|
input CLK, // clock
|
input CLK, // clock
|
input RES, // reset
|
input RES, // reset
|
input HLT, // halt
|
input HLT, // halt
|
|
|
`ifdef __THREADING__
|
//`ifdef __THREADING__
|
input IREQ, // irq req
|
// input IREQ, // irq req
|
`endif
|
//`endif
|
|
|
input [31:0] IDATA, // instruction data bus
|
input [31:0] IDATA, // instruction data bus
|
output [31:0] IADDR, // instruction addr bus
|
output [31:0] IADDR, // instruction addr bus
|
|
|
input [31:0] DATAI, // data bus (input)
|
input [31:0] DATAI, // data bus (input)
|
Line 80... |
Line 80... |
output [ 3:0] BE, // byte enable
|
output [ 3:0] BE, // byte enable
|
output WR, // write enable
|
output WR, // write enable
|
output RD, // read enable
|
output RD, // read enable
|
`endif
|
`endif
|
|
|
|
`ifdef SIMULATION
|
|
input FINISH_REQ,
|
|
`endif
|
output [3:0] DEBUG // old-school osciloscope based debug! :)
|
output [3:0] DEBUG // old-school osciloscope based debug! :)
|
);
|
);
|
|
|
// dummy 32-bit words w/ all-0s and all-1s:
|
// dummy 32-bit words w/ all-0s and all-1s:
|
|
|
wire [31:0] ALL0 = 0;
|
wire [31:0] ALL0 = 0;
|
wire [31:0] ALL1 = -1;
|
wire [31:0] ALL1 = -1;
|
|
|
`ifdef __THREADING__
|
`ifdef __THREADING__
|
reg XMODE = 0; // 0 = user, 1 = exception
|
reg XMODE = 0; // thread ptr
|
`endif
|
`endif
|
|
|
// pre-decode: IDATA is break apart as described in the RV32I specification
|
// pre-decode: IDATA is break apart as described in the RV32I specification
|
|
|
reg [31:0] XIDATA;
|
reg [31:0] XIDATA;
|
Line 338... |
Line 341... |
//0);
|
//0);
|
|
|
wire JREQ = (JAL||JALR||BMUX);
|
wire JREQ = (JAL||JALR||BMUX);
|
wire [31:0] JVAL = JALR ? DADDR : PC+SIMM; // SIMM + (JALR ? U1REG : PC);
|
wire [31:0] JVAL = JALR ? DADDR : PC+SIMM; // SIMM + (JALR ? U1REG : PC);
|
|
|
|
`ifdef SIMULATION
|
`ifdef __PERFMETER__
|
`ifdef __PERFMETER__
|
integer clocks=0, user=0, super=0, halt=0, flush=0;
|
integer clocks=0, thread0=0, thread1=0, load=0, store=0, flush=0, halt=0;
|
|
|
always@(posedge CLK)
|
always@(posedge CLK)
|
begin
|
begin
|
if(!XRES)
|
if(!XRES)
|
begin
|
begin
|
clocks = clocks+1;
|
clocks = clocks+1;
|
|
|
|
if(HLT)
|
|
begin
|
|
if(SCC) store = store+1;
|
|
else if(LCC) load = load +1;
|
|
else halt = halt +1;
|
|
end
|
|
else
|
|
begin
|
|
if(FLUSH)
|
|
begin
|
|
flush=flush+1;
|
|
end
|
|
else
|
|
begin
|
`ifdef __THREADING__
|
`ifdef __THREADING__
|
|
|
if(XMODE==0 && !HLT && !FLUSH) user = user +1;
|
if(XMODE==0) thread0 = thread0+1;
|
if(XMODE==1 && !HLT && !FLUSH) super = super+1;
|
if(XMODE==1) thread1 = thread1+1;
|
`else
|
`else
|
if(!HLT && !FLUSH) user = user +1;
|
thread0 = thread0 +1;
|
`endif
|
`endif
|
|
end
|
|
end
|
|
|
if(HLT) halt=halt+1;
|
if(FINISH_REQ)
|
if(FLUSH) flush=flush+1;
|
|
|
|
if(clocks && clocks%`__PERFMETER__==0)
|
|
begin
|
begin
|
$display("%d clocks: %0d%% user, %0d%% super, %0d%% ws, %0d%% flush",
|
$display("****************************************************************************");
|
clocks,
|
$display("DarkRISCV Pipeline Report:");
|
100*user/clocks,
|
$display("core0 clocks: %0d",clocks);
|
100*super/clocks,
|
|
100*halt/clocks,
|
$display("core0 running: %0d%% (%0d%% thread0, %0d%% thread1)",
|
100*flush/clocks);
|
100.0*(thread0+thread1)/clocks,
|
|
100.0*thread0/clocks,
|
|
100.0*thread1/clocks);
|
|
|
|
$display("core0 halted: %0d%% (%0d%% load, %0d%% store, %0d%% busy)",
|
|
100.0*(load+store)/clocks,
|
|
100.0*load/clocks,
|
|
100.0*store/clocks,
|
|
100.0*halt/clocks);
|
|
|
|
$display("core0 stalled: %0d%%",100.0*flush/clocks);
|
|
$display("****************************************************************************");
|
|
$finish();
|
end
|
end
|
end
|
end
|
end
|
end
|
|
`else
|
|
$finish();
|
|
`endif
|
`endif
|
`endif
|
|
|
always@(posedge CLK)
|
always@(posedge CLK)
|
begin
|
begin
|
RESMODE <= RES ? -1 : RESMODE ? RESMODE-1 : 0;
|
RESMODE <= RES ? -1 : RESMODE ? RESMODE-1 : 0;
|
Line 434... |
Line 466... |
NXPC2[RES ? RESMODE[0] : XMODE] <= XRES ? `__RESETPC__ : HLT ? NXPC2[XMODE] : // reset and halt
|
NXPC2[RES ? RESMODE[0] : XMODE] <= XRES ? `__RESETPC__ : HLT ? NXPC2[XMODE] : // reset and halt
|
JREQ ? JVAL : // jmp/bra
|
JREQ ? JVAL : // jmp/bra
|
NXPC2[XMODE]+4; // normal flow
|
NXPC2[XMODE]+4; // normal flow
|
|
|
XMODE <= XRES ? 0 : HLT ? XMODE : // reset and halt
|
XMODE <= XRES ? 0 : HLT ? XMODE : // reset and halt
|
XMODE==0&& IREQ&&(JAL||JALR||BMUX) ? 1 : // wait pipeflush to switch to irq
|
XMODE==0/*&& IREQ*/&&(JAL||JALR||BMUX) ? 1 : // wait pipeflush to switch to irq
|
XMODE==1&&!IREQ&&(JAL||JALR||BMUX) ? 0 : XMODE; // wait pipeflush to return from irq
|
XMODE==1/*&&!IREQ*/&&(JAL||JALR||BMUX) ? 0 : XMODE; // wait pipeflush to return from irq
|
|
|
`else
|
`else
|
NXPC <= /*XRES ? `__RESETPC__ :*/ HLT ? NXPC : NXPC2;
|
NXPC <= /*XRES ? `__RESETPC__ :*/ HLT ? NXPC : NXPC2;
|
|
|
NXPC2 <= XRES ? `__RESETPC__ : HLT ? NXPC2 : // reset and halt
|
NXPC2 <= XRES ? `__RESETPC__ : HLT ? NXPC2 : // reset and halt
|