Line 92... |
Line 92... |
|
|
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; // thread ptr
|
reg [$clog2(`NTHREADS)-1:0] 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 151... |
Line 151... |
`else
|
`else
|
reg FLUSH = -1; // flush instruction pipeline
|
reg FLUSH = -1; // flush instruction pipeline
|
`endif
|
`endif
|
|
|
`ifdef __THREADING__
|
`ifdef __THREADING__
|
|
|
`ifdef __RV32E__
|
`ifdef __RV32E__
|
|
|
reg [4:0] RESMODE = -1;
|
reg [$clog2(`NTHREADS)+3:0] RESMODE = -1;
|
|
|
wire [4:0] DPTR = XRES ? RESMODE : { XMODE, XIDATA[10: 7] }; // set SP_RESET when RES==1
|
|
wire [4:0] S1PTR = { XMODE, XIDATA[18:15] };
|
|
wire [4:0] S2PTR = { XMODE, XIDATA[23:20] };
|
|
`else
|
|
reg [5:0] RESMODE = -1;
|
|
|
|
wire [5:0] DPTR = XRES ? RESMODE : { XMODE, XIDATA[11: 7] }; // set SP_RESET when RES==1
|
|
wire [5:0] S1PTR = { XMODE, XIDATA[19:15] };
|
|
wire [5:0] S2PTR = { XMODE, XIDATA[24:20] };
|
|
`endif
|
|
|
|
wire [6:0] OPCODE = FLUSH ? 0 : XIDATA[6:0];
|
|
wire [2:0] FCT3 = XIDATA[14:12];
|
|
wire [6:0] FCT7 = XIDATA[31:25];
|
|
|
|
|
wire [$clog2(`NTHREADS)+3:0] DPTR = XRES ? RESMODE : { XMODE, XIDATA[10: 7] }; // set SP_RESET when RES==1
|
|
wire [$clog2(`NTHREADS)+3:0] S1PTR = { XMODE, XIDATA[18:15] };
|
|
wire [$clog2(`NTHREADS)+3:0] S2PTR = { XMODE, XIDATA[23:20] };
|
`else
|
`else
|
|
reg [$clog2(`NTHREADS)+4:0] RESMODE = -1;
|
|
|
|
wire [$clog2(`NTHREADS)+4:0] DPTR = XRES ? RESMODE : { XMODE, XIDATA[11: 7] }; // set SP_RESET when RES==1
|
|
wire [$clog2(`NTHREADS)+4:0] S1PTR = { XMODE, XIDATA[19:15] };
|
|
wire [$clog2(`NTHREADS)+4:0] S2PTR = { XMODE, XIDATA[24:20] };
|
|
`endif
|
|
`else
|
`ifdef __RV32E__
|
`ifdef __RV32E__
|
|
|
reg [3:0] RESMODE = -1;
|
reg [3:0] RESMODE = -1;
|
|
|
wire [3:0] DPTR = XRES ? RESMODE : XIDATA[10: 7]; // set SP_RESET when RES==1
|
wire [3:0] DPTR = XRES ? RESMODE : XIDATA[10: 7]; // set SP_RESET when RES==1
|
Line 187... |
Line 180... |
|
|
wire [4:0] DPTR = XRES ? RESMODE : XIDATA[11: 7]; // set SP_RESET when RES==1
|
wire [4:0] DPTR = XRES ? RESMODE : XIDATA[11: 7]; // set SP_RESET when RES==1
|
wire [4:0] S1PTR = XIDATA[19:15];
|
wire [4:0] S1PTR = XIDATA[19:15];
|
wire [4:0] S2PTR = XIDATA[24:20];
|
wire [4:0] S2PTR = XIDATA[24:20];
|
`endif
|
`endif
|
|
`endif
|
|
|
wire [6:0] OPCODE = FLUSH ? 0 : XIDATA[6:0];
|
wire [6:0] OPCODE = FLUSH ? 0 : XIDATA[6:0];
|
wire [2:0] FCT3 = XIDATA[14:12];
|
wire [2:0] FCT3 = XIDATA[14:12];
|
wire [6:0] FCT7 = XIDATA[31:25];
|
wire [6:0] FCT7 = XIDATA[31:25];
|
|
|
`endif
|
|
|
|
wire [31:0] SIMM = XSIMM;
|
wire [31:0] SIMM = XSIMM;
|
wire [31:0] UIMM = XUIMM;
|
wire [31:0] UIMM = XUIMM;
|
|
|
// main opcode decoder:
|
// main opcode decoder:
|
|
|
Line 216... |
Line 208... |
//wire FCC = FLUSH ? 0 : XFCC; // OPCODE==7'b0001111; //FCT3
|
//wire FCC = FLUSH ? 0 : XFCC; // OPCODE==7'b0001111; //FCT3
|
//wire CCC = FLUSH ? 0 : XCCC; // OPCODE==7'b1110011; //FCT3
|
//wire CCC = FLUSH ? 0 : XCCC; // OPCODE==7'b1110011; //FCT3
|
|
|
`ifdef __THREADING__
|
`ifdef __THREADING__
|
`ifdef __3STAGE__
|
`ifdef __3STAGE__
|
reg [31:0] NXPC2 [0:1]; // 32-bit program counter t+2
|
reg [31:0] NXPC2 [0:`NTHREADS-1]; // 32-bit program counter t+2
|
`endif
|
`endif
|
reg [31:0] NXPC; // 32-bit program counter t+1
|
|
reg [31:0] PC; // 32-bit program counter t+0
|
|
|
|
`ifdef __RV32E__
|
`ifdef __RV32E__
|
reg [31:0] REG1 [0:31]; // general-purpose 16x32-bit registers (s1)
|
reg [31:0] REG1 [0:16*`NTHREADS-1]; // general-purpose 16x32-bit registers (s1)
|
reg [31:0] REG2 [0:31]; // general-purpose 16x32-bit registers (s2)
|
reg [31:0] REG2 [0:16*`NTHREADS-1]; // general-purpose 16x32-bit registers (s2)
|
`else
|
`else
|
reg [31:0] REG1 [0:63]; // general-purpose 32x32-bit registers (s1)
|
reg [31:0] REG1 [0:32*`NTHREADS-1]; // general-purpose 32x32-bit registers (s1)
|
reg [31:0] REG2 [0:63]; // general-purpose 32x32-bit registers (s2)
|
reg [31:0] REG2 [0:32*`NTHREADS-1]; // general-purpose 32x32-bit registers (s2)
|
`endif
|
`endif
|
`else
|
`else
|
`ifdef __3STAGE__
|
`ifdef __3STAGE__
|
reg [31:0] NXPC2; // 32-bit program counter t+2
|
reg [31:0] NXPC2; // 32-bit program counter t+2
|
`endif
|
`endif
|
reg [31:0] NXPC; // 32-bit program counter t+1
|
|
reg [31:0] PC; // 32-bit program counter t+0
|
|
|
|
`ifdef __RV32E__
|
`ifdef __RV32E__
|
reg [31:0] REG1 [0:15]; // general-purpose 16x32-bit registers (s1)
|
reg [31:0] REG1 [0:15]; // general-purpose 16x32-bit registers (s1)
|
reg [31:0] REG2 [0:15]; // general-purpose 16x32-bit registers (s2)
|
reg [31:0] REG2 [0:15]; // general-purpose 16x32-bit registers (s2)
|
`else
|
`else
|
reg [31:0] REG1 [0:31]; // general-purpose 32x32-bit registers (s1)
|
reg [31:0] REG1 [0:31]; // general-purpose 32x32-bit registers (s1)
|
reg [31:0] REG2 [0:31]; // general-purpose 32x32-bit registers (s2)
|
reg [31:0] REG2 [0:31]; // general-purpose 32x32-bit registers (s2)
|
`endif
|
`endif
|
`endif
|
`endif
|
|
|
|
reg [31:0] NXPC; // 32-bit program counter t+1
|
|
reg [31:0] PC; // 32-bit program counter t+0
|
|
|
// source-1 and source-1 register selection
|
// source-1 and source-1 register selection
|
|
|
wire signed [31:0] S1REG = REG1[S1PTR];
|
wire signed [31:0] S1REG = REG1[S1PTR];
|
wire signed [31:0] S2REG = REG2[S2PTR];
|
wire signed [31:0] S2REG = REG2[S2PTR];
|
|
|
Line 343... |
Line 334... |
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 SIMULATION
|
`ifdef __PERFMETER__
|
`ifdef __PERFMETER__
|
integer clocks=0, thread0=0, thread1=0, load=0, store=0, flush=0, halt=0;
|
|
|
integer clocks=0, running=0, load=0, store=0, flush=0, halt=0;
|
|
|
|
`ifdef __THREADING__
|
|
integer thread[0:`NTHREADS-1];
|
|
integer i;
|
|
|
|
initial for(i=0;i!=`NTHREADS;i=i+1) thread[i] = 0;
|
|
`endif
|
|
|
always@(posedge CLK)
|
always@(posedge CLK)
|
begin
|
begin
|
if(!XRES)
|
if(!XRES)
|
begin
|
begin
|
Line 365... |
Line 364... |
begin
|
begin
|
flush=flush+1;
|
flush=flush+1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
|
|
`ifdef __THREADING__
|
`ifdef __THREADING__
|
|
|
if(XMODE==0) thread0 = thread0+1;
|
for(i=0;i!=`NTHREADS;i=i+1)
|
if(XMODE==1) thread1 = thread1+1;
|
thread[i] = thread[i]+(i==XMODE?1:0);
|
`else
|
|
thread0 = thread0 +1;
|
|
`endif
|
`endif
|
|
running = running +1;
|
end
|
end
|
end
|
end
|
|
|
if(FINISH_REQ)
|
if(FINISH_REQ)
|
begin
|
begin
|
$display("****************************************************************************");
|
$display("****************************************************************************");
|
$display("DarkRISCV Pipeline Report:");
|
$display("DarkRISCV Pipeline Report:");
|
$display("core0 clocks: %0d",clocks);
|
$display("core0 clocks: %0d",clocks);
|
|
|
$display("core0 running: %0d%% (%0d%% thread0, %0d%% thread1)",
|
$display("core0: running %0d%%",100.0*running/clocks);
|
100.0*(thread0+thread1)/clocks,
|
|
100.0*thread0/clocks,
|
`ifdef __THREADING__
|
100.0*thread1/clocks);
|
for(i=0;i!=`NTHREADS;i=i+1) $display(" thread%0d: running %0d%%",i,100.0*thread[i]/clocks);
|
|
`endif
|
|
|
$display("core0 halted: %0d%% (%0d%% load, %0d%% store, %0d%% busy)",
|
$display("core0: halted %0d%% (%0d%% load, %0d%% store, %0d%% busy)",
|
100.0*(load+store)/clocks,
|
100.0*(load+store)/clocks,
|
100.0*load/clocks,
|
100.0*load/clocks,
|
100.0*store/clocks,
|
100.0*store/clocks,
|
100.0*halt/clocks);
|
100.0*halt/clocks);
|
|
|
$display("core0 stalled: %0d%%",100.0*flush/clocks);
|
$display("core0: stalled %0d%%",100.0*flush/clocks);
|
|
|
|
|
|
|
$display("****************************************************************************");
|
$display("****************************************************************************");
|
$finish();
|
$finish();
|
end
|
end
|
end
|
end
|
end
|
end
|
Line 461... |
Line 464... |
|
|
`ifdef __THREADING__
|
`ifdef __THREADING__
|
|
|
NXPC <= /*XRES ? `__RESETPC__ :*/ HLT ? NXPC : NXPC2[XMODE];
|
NXPC <= /*XRES ? `__RESETPC__ :*/ HLT ? NXPC : NXPC2[XMODE];
|
|
|
NXPC2[RES ? RESMODE[0] : XMODE] <= XRES ? `__RESETPC__ : HLT ? NXPC2[XMODE] : // reset and halt
|
NXPC2[XRES ? RESMODE[$clog2(`NTHREADS)-1: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
|
JAL ? XMODE+1 : XMODE;
|
XMODE==1/*&&!IREQ*/&&(JAL||JALR||BMUX) ? 0 : XMODE; // wait pipeflush to return from 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
|
|
|
`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
|