Line 96... |
Line 96... |
`define Wired 5'd15
|
`define Wired 5'd15
|
`define EP0 5'd16
|
`define EP0 5'd16
|
`define EP1 5'd17
|
`define EP1 5'd17
|
`define EP2 5'd18
|
`define EP2 5'd18
|
`define EP3 5'd19
|
`define EP3 5'd19
|
|
`define AXC 5'd20
|
`define MFTICK 7'd56
|
`define MFTICK 7'd56
|
`define MFEPC 7'd57
|
`define MFEPC 7'd57
|
`define MFTBA 7'd58
|
`define MFTBA 7'd58
|
`define MTTBA 7'd59
|
`define MTTBA 7'd59
|
`define MTREGSET 7'd60
|
`define MTREGSET 7'd60
|
Line 113... |
Line 114... |
`define OR 7'd9
|
`define OR 7'd9
|
`define XOR 7'd10
|
`define XOR 7'd10
|
`define ANDC 7'd11
|
`define ANDC 7'd11
|
`define NAND 7'd12
|
`define NAND 7'd12
|
`define NOR 7'd13
|
`define NOR 7'd13
|
`define ENOR 7'd14
|
`define XNOR 7'd14
|
`define MIN 7'd20
|
`define MIN 7'd20
|
`define MAX 7'd21
|
`define MAX 7'd21
|
`define MULU 7'd24
|
`define MULU 7'd24
|
`define MULS 7'd25
|
`define MULS 7'd25
|
`define DIVU 7'd26
|
`define DIVU 7'd26
|
Line 152... |
Line 153... |
|
|
`define SLT 7'd96
|
`define SLT 7'd96
|
`define SLE 7'd97
|
`define SLE 7'd97
|
`define SGT 7'd98
|
`define SGT 7'd98
|
`define SGE 7'd99
|
`define SGE 7'd99
|
`define SLO 7'd100
|
`define SLTU 7'd100
|
`define SLS 7'd101
|
`define SLEU 7'd101
|
`define SHI 7'd102
|
`define SGTU 7'd102
|
`define SHS 7'd103
|
`define SGEU 7'd103
|
`define SEQ 7'd104
|
`define SEQ 7'd104
|
`define SNE 7'd105
|
`define SNE 7'd105
|
|
|
`define BCD_ADD 7'd110
|
`define BCD_ADD 7'd110
|
`define BCD_SUB 7'd111
|
`define BCD_SUB 7'd111
|
Line 396... |
Line 397... |
output rd_en;
|
output rd_en;
|
reg rd_en;
|
reg rd_en;
|
input [31:0] rd_data;
|
input [31:0] rd_data;
|
input rd_empty;
|
input rd_empty;
|
|
|
|
reg resetA;
|
reg im; // interrupt mask
|
reg im; // interrupt mask
|
reg [1:0] rm; // fp rounding mode
|
reg [1:0] rm; // fp rounding mode
|
reg [41:0] dIR;
|
reg [41:0] dIR;
|
reg [41:0] xIR;
|
reg [41:0] xIR;
|
reg [4:0] epcnt;
|
reg [4:0] epcnt;
|
Line 416... |
Line 418... |
reg [63:0] dImm;
|
reg [63:0] dImm;
|
reg [63:0] ea;
|
reg [63:0] ea;
|
reg [63:0] iadr_o;
|
reg [63:0] iadr_o;
|
reg [31:0] idat;
|
reg [31:0] idat;
|
reg [4:0] cstate;
|
reg [4:0] cstate;
|
reg wr_icache;
|
//reg wr_icache;
|
reg dccyc;
|
reg dccyc;
|
wire [63:0] cdat;
|
wire [63:0] cdat;
|
reg [63:0] wr_addr;
|
reg [63:0] wr_addr;
|
wire [41:0] insn;
|
wire [41:0] insn;
|
reg [3:0] regset;
|
reg [3:0] regset;
|
Line 547... |
Line 549... |
end
|
end
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Instruction Cache
|
// Instruction Cache
|
// 8kB
|
// 8kB
|
|
//
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg icaccess;
|
reg icaccess;
|
|
wire wr_icache = !rd_empty & icaccess;
|
|
|
Raptor64_icache_ram_x32 u1
|
Raptor64_icache_ram_x32 u1
|
(
|
(
|
.clk(clk),
|
.clk(clk),
|
.icaccess(icaccess),
|
.wr(wr_icache),
|
.ack_i(ack_i),
|
.adr_i(iadr_o[12:0]),
|
.adr_i(adr_o[12:0]),
|
.dat_i(rd_data),
|
.dat_i(dat_i),
|
.pc(pc_axc),
|
.pc(ppc),
|
|
.insn(insn)
|
.insn(insn)
|
);
|
);
|
|
|
reg [63:13] tmem [127:0];
|
reg [63:13] tmem [127:0];
|
reg [127:0] tvalid;
|
reg [127:0] tvalid;
|
Line 572... |
Line 575... |
for (n=0; n < 128; n = n + 1)
|
for (n=0; n < 128; n = n + 1)
|
tvalid[n] = 0;
|
tvalid[n] = 0;
|
end
|
end
|
|
|
wire [64:13] tgout;
|
wire [64:13] tgout;
|
assign tgout = {tvalid[ppc[12:6]],tmem[ppc[12:6]]};
|
assign tgout = {tvalid[pc_axc[12:6]],tmem[pc_axc[12:6]]};
|
assign ihit = (tgout=={1'b1,ppc[63:13]});
|
assign ihit = (tgout=={1'b1,ppc[63:13]});
|
|
|
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
// Data Cache
|
// Data Cache
|
|
// No-allocate on write
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
reg dcaccess;
|
reg dcaccess;
|
wire dhit;
|
wire dhit;
|
wire [12:0] dtign;
|
wire [13:0] dtign;
|
wire [64:14] dtgout;
|
wire [64:14] dtgout;
|
reg dwe_o;
|
|
reg wrhit;
|
reg wrhit;
|
reg [7:0] dsel_o;
|
reg [7:0] dsel_o;
|
reg [63:0] dadr_o;
|
reg [63:0] dadr_o;
|
reg [31:0] ddat;
|
reg [31:0] ddat;
|
reg wr_dcache;
|
reg wr_dcache;
|
Line 607... |
Line 610... |
// tag ram
|
// tag ram
|
syncRam512x64_1rw1r u11
|
syncRam512x64_1rw1r u11
|
(
|
(
|
.wrst(1'b0),
|
.wrst(1'b0),
|
.wclk(clk),
|
.wclk(clk),
|
.wce(dcaccess && dadr_o[4:3]==2'b11),
|
.wce(dadr_o[4:2]==3'b111),
|
.we(wr_dcache),
|
.we(wr_dcache),
|
.wadr(dadr_o[13:5]),
|
.wadr(dadr_o[13:5]),
|
.i({14'h3FFF,dadr_o[63:14]}),
|
.i({14'h3FFF,dadr_o[63:14]}),
|
.wo(),
|
.wo(),
|
|
|
Line 626... |
Line 629... |
|
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
|
|
reg [64:0] xData;
|
reg [64:0] xData;
|
wire isCacheElement = adr_o < 64'hFFFF0000_00000000;
|
|
wire xisCacheElement = xData[63:52] != 12'hFFD;
|
wire xisCacheElement = xData[63:52] != 12'hFFD;
|
reg m1IsCacheElement;
|
reg m1IsCacheElement;
|
|
|
reg nopI;
|
reg nopI;
|
wire [6:0] dFunc = dIR[6:0];
|
wire [6:0] dFunc = dIR[6:0];
|
Line 1030... |
Line 1032... |
`ASID: xData = ASID;
|
`ASID: xData = ASID;
|
`EP0: xData = EP[0];
|
`EP0: xData = EP[0];
|
`EP1: xData = EP[1];
|
`EP1: xData = EP[1];
|
`EP2: xData = EP[2];
|
`EP2: xData = EP[2];
|
`EP3: xData = EP[3];
|
`EP3: xData = EP[3];
|
|
`AXC: xData = xAXC;
|
default: xData = 65'd0;
|
default: xData = 65'd0;
|
endcase
|
endcase
|
`MFTICK: xData = tick;
|
`MFTICK: xData = tick;
|
`MFEPC: xData = ipc;
|
`MFEPC: xData = ipc;
|
`MFTBA: xData = tba;
|
`MFTBA: xData = tba;
|
Line 1052... |
Line 1055... |
`SNE: xData = !eq;
|
`SNE: xData = !eq;
|
`SLT: xData = lt;
|
`SLT: xData = lt;
|
`SLE: xData = lt|eq;
|
`SLE: xData = lt|eq;
|
`SGT: xData = !(lt|eq);
|
`SGT: xData = !(lt|eq);
|
`SGE: xData = !lt;
|
`SGE: xData = !lt;
|
`SLO: xData = ltu;
|
`SLTU: xData = ltu;
|
`SLS: xData = ltu|eq;
|
`SLEU: xData = ltu|eq;
|
`SHI: xData = !(ltu|eq);
|
`SGTU: xData = !(ltu|eq);
|
`SHS: xData = !ltu;
|
`SGEU: xData = !ltu;
|
`AND: xData = a & b;
|
`AND: xData = a & b;
|
`OR: xData = a | b;
|
`OR: xData = a | b;
|
`XOR: xData = a ^ b;
|
`XOR: xData = a ^ b;
|
`ANDC: xData = a & ~b;
|
`ANDC: xData = a & ~b;
|
`NAND: xData = ~(a & b);
|
`NAND: xData = ~(a & b);
|
`NOR: xData = ~(a | b);
|
`NOR: xData = ~(a | b);
|
`ENOR: xData = ~(a ^ b);
|
`XNOR: xData = ~(a ^ b);
|
`MIN: xData = lt ? a : b;
|
`MIN: xData = lt ? a : b;
|
`MAX: xData = lt ? b : a;
|
`MAX: xData = lt ? b : a;
|
`MOVZ: xData = b;
|
`MOVZ: xData = b;
|
`MOVNZ: xData = b;
|
`MOVNZ: xData = b;
|
`MULS: xData = mult_out[63:0];
|
`MULS: xData = mult_out[63:0];
|
Line 1213... |
Line 1216... |
wire m1needWritePort = m1Opcode==`SW || m1Opcode==`SWC || m1Opcode==`SH || m1Opcode==`SC || m1Opcode==`SB;
|
wire m1needWritePort = m1Opcode==`SW || m1Opcode==`SWC || m1Opcode==`SH || m1Opcode==`SC || m1Opcode==`SB;
|
wire m2needWritePort = m2Opcode==`SW||m2Opcode==`SWC;
|
wire m2needWritePort = m2Opcode==`SW||m2Opcode==`SWC;
|
wire m1needCmdPort = m1IsLoad && !m1IsCacheElement;
|
wire m1needCmdPort = m1IsLoad && !m1IsCacheElement;
|
wire m2needCmdPort = m2Opcode==`SH||m2Opcode==`SC||m2Opcode==`SB;
|
wire m2needCmdPort = m2Opcode==`SH||m2Opcode==`SC||m2Opcode==`SB;
|
wire m3needCmdPort = m3Opcode==`SW || m3Opcode==`SWC;
|
wire m3needCmdPort = m3Opcode==`SW || m3Opcode==`SWC;
|
wire m3needReadPort = m3IsLoad;
|
wire m2needReadPort = m2IsLoad;
|
wire m4needReadPort = m4Opcode==`LW || m4Opcode==`LWR;
|
wire m3needReadPort = m3Opcode==`LW || m3Opcode==`LWR;
|
|
//wire m4needReadPort = m4Opcode==`LW || m4Opcode==`LWR;
|
|
|
// Stall for the write port
|
// Stall for the write port
|
wire StallM1 = (m1needWritePort && m2needWritePort) || // Write port collision
|
wire StallM1 = (m1needWritePort && m2needWritePort) || // Write port collision
|
// Stall on the command port
|
// Stall on the command port
|
(m1needCmdPort && (m2needCmdPort||m3needCmdPort)) || // SW,SWC are still using the wr port in M2
|
(m1needCmdPort && (m2needCmdPort||m3needCmdPort)) || // SW,SWC are still using the wr port in M2
|
// cache access is taking place
|
// cache access is taking place
|
icaccess || dcaccess
|
icaccess || dcaccess
|
;
|
;
|
// M3 is using the command port
|
// M3 is using the command port
|
wire StallM2 = m2needCmdPort & m3needCmdPort;
|
wire StallM2 = (m2needCmdPort & m3needCmdPort) | (m3needReadPort|icaccess|dcaccess);
|
wire StallM3 = m3needReadPort & m4needReadPort;
|
wire StallM3 = m3needReadPort & (icaccess|dcaccess);
|
wire advanceT = 1'b1;
|
wire advanceT = !resetA;
|
wire advanceW = advanceT;
|
wire advanceW = advanceT;
|
wire advanceM4 = advanceW & (m4needReadPort ? !rd_empty : 1'b1);
|
wire advanceM4 = advanceW & (m4IsLoad ? !rd_empty : 1'b1);
|
wire advanceM3 = advanceM4 &
|
wire advanceM3 = advanceM4 &
|
(m3IsIO ? ack_i : 1'b1) &
|
(m3IsIO ? ack_i : 1'b1) &
|
(m3needReadPort ? !rd_empty : 1'b1) &
|
(m3IsLoad ? !rd_empty : 1'b1) &
|
!StallM3
|
!StallM3
|
;
|
;
|
wire advanceM2 = advanceM3 & !StallM2;
|
wire advanceM2 = advanceM3 & !StallM2;
|
wire advanceM1 = advanceM2
|
wire advanceM1 = advanceM2
|
&
|
&
|
Line 1253... |
Line 1257... |
1'b1);
|
1'b1);
|
wire advanceR = advanceX & !xStall & !m1Stall && !m2Stall && !m3Stall && !m4Stall;
|
wire advanceR = advanceX & !xStall & !m1Stall && !m2Stall && !m3Stall && !m4Stall;
|
wire advanceI = advanceR & ihit;
|
wire advanceI = advanceR & ihit;
|
|
|
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
|
m3Opcode==`NOPI &&
|
m3Opcode==`NOPI &&
|
m4Opcode==`NOPI &&
|
m4Opcode==`NOPI &&
|
wr_empty // and the write buffer is empty
|
wr_empty // and the write buffer is empty
|
;
|
;
|
Line 1308... |
Line 1312... |
we_o <= 1'b0;
|
we_o <= 1'b0;
|
sel_o <= 8'h00;
|
sel_o <= 8'h00;
|
adr_o <= 64'd0;
|
adr_o <= 64'd0;
|
dat_o <= 64'd0;
|
dat_o <= 64'd0;
|
dccyc <= 1'b0;
|
dccyc <= 1'b0;
|
|
|
|
cmd_en <= 1'b0;
|
|
cmd_instr <= 3'b001;
|
|
cmd_bl <= 6'd1;
|
|
cmd_byte_addr <= 30'd0;
|
|
|
// pc[0] <= 64'hFFFF_FFFF_FFFF_FFE0;
|
// pc[0] <= 64'hFFFF_FFFF_FFFF_FFE0;
|
m1Opcode <= `NOPI;
|
m1Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m2Opcode <= `NOPI;
|
m3Opcode <= `NOPI;
|
m3Opcode <= `NOPI;
|
m4Opcode <= `NOPI;
|
m4Opcode <= `NOPI;
|
Line 1359... |
Line 1369... |
epcnt <= 5'd0;
|
epcnt <= 5'd0;
|
EP[0] <= 32'd0;
|
EP[0] <= 32'd0;
|
EP[1] <= 32'd0;
|
EP[1] <= 32'd0;
|
EP[2] <= 32'd0;
|
EP[2] <= 32'd0;
|
EP[3] <= 32'd0;
|
EP[3] <= 32'd0;
|
|
AXC <= 4'd0;
|
|
dAXC <= 4'd0;
|
|
xAXC <= 4'd0;
|
|
resetA <= 1'b1;
|
end
|
end
|
else begin
|
else begin
|
|
|
if (Random==Wired)
|
if (Random==Wired)
|
Random <= 4'hF;
|
Random <= 4'hF;
|
Line 1440... |
Line 1454... |
wData <= m4Data;
|
wData <= m4Data;
|
m4Rt <= 9'd0;
|
m4Rt <= 9'd0;
|
m4Opcode <= `NOPI;
|
m4Opcode <= `NOPI;
|
m4Data <= 64'd0;
|
m4Data <= 64'd0;
|
m4clkoff <= 1'b0;
|
m4clkoff <= 1'b0;
|
rd_en <= 1'b0;
|
|
m4Opcode <= `NOPI;
|
m4Opcode <= `NOPI;
|
case(m4Opcode)
|
case(m4Opcode)
|
`LW,`LWR: wData <= {rd_data,m4Data[31:0]};
|
`LW,`LWR: begin
|
|
wData <= {rd_data,m4Data[31:0]};
|
|
rd_en <= 1'b0; // only if LW/LWR
|
|
end
|
default: wData <= m4Data;
|
default: wData <= m4Data;
|
endcase
|
endcase
|
end
|
end
|
|
|
|
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// MEMORY:
|
// MEMORY:
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceM3) begin
|
if (advanceM3) begin
|
rd_en <= 1'b0;
|
|
m4Opcode <= m3Opcode;
|
m4Opcode <= m3Opcode;
|
m4Func <= m3Func;
|
m4Func <= m3Func;
|
m4irqf <= m3irqf;
|
m4irqf <= m3irqf;
|
m4extype <= m3extype;
|
m4extype <= m3extype;
|
m4Rt <= m3Rt;
|
m4Rt <= m3Rt;
|
Line 1490... |
Line 1505... |
begin
|
begin
|
rd_en <= 1'b1;
|
rd_en <= 1'b1;
|
m4Data <= {32'd0,rd_data};
|
m4Data <= {32'd0,rd_data};
|
end
|
end
|
`LH:
|
`LH:
|
|
begin
|
|
rd_en <= 1'b0;
|
m4Data <= {{32{rd_data[31]}},rd_data};
|
m4Data <= {{32{rd_data[31]}},rd_data};
|
|
end
|
`LHU:
|
`LHU:
|
|
begin
|
|
rd_en <= 1'b0;
|
m4Data <= rd_data;
|
m4Data <= rd_data;
|
|
end
|
`LC:
|
`LC:
|
|
begin
|
|
rd_en <= 1'b0;
|
case(m3Addr[1])
|
case(m3Addr[1])
|
1'b0: m4Data <= {{48{rd_data[15]}},rd_data[15:0]};
|
1'b0: m4Data <= {{48{rd_data[15]}},rd_data[15:0]};
|
1'b1: m4Data <= {{48{rd_data[31]}},rd_data[31:16]};
|
1'b1: m4Data <= {{48{rd_data[31]}},rd_data[31:16]};
|
endcase
|
endcase
|
|
end
|
`LCU:
|
`LCU:
|
|
begin
|
|
rd_en <= 1'b0;
|
case(m3Addr[1])
|
case(m3Addr[1])
|
1'b0: m4Data <= {48'd0,rd_data[15:0]};
|
1'b0: m4Data <= {48'd0,rd_data[15:0]};
|
1'b1: m4Data <= {48'd0,rd_data[31:16]};
|
1'b1: m4Data <= {48'd0,rd_data[31:16]};
|
endcase
|
endcase
|
|
end
|
`LB:
|
`LB:
|
|
begin
|
|
rd_en <= 1'b0;
|
case(m3Addr[1:0])
|
case(m3Addr[1:0])
|
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]};
|
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]};
|
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]};
|
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]};
|
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]};
|
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]};
|
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]};
|
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]};
|
endcase
|
endcase
|
|
end
|
`LBU:
|
`LBU:
|
|
begin
|
case(m3Addr[1:0])
|
case(m3Addr[1:0])
|
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]};
|
2'd0: m4Data <= {{56{rd_data[7]}},rd_data[7:0]};
|
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]};
|
2'd1: m4Data <= {{56{rd_data[15]}},rd_data[15:8]};
|
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]};
|
2'd2: m4Data <= {{56{rd_data[23]}},rd_data[23:16]};
|
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]};
|
2'd3: m4Data <= {{56{rd_data[31]}},rd_data[31:24]};
|
endcase
|
endcase
|
|
rd_en <= 1'b0;
|
|
end
|
`SW,`SWC:
|
`SW,`SWC:
|
begin
|
begin
|
cmd_en <= 1'b1;
|
cmd_en <= 1'b1;
|
cmd_instr <= 3'b000; // WRITE
|
cmd_instr <= 3'b000; // WRITE
|
cmd_bl <= 6'd2; // 2-words
|
cmd_bl <= 6'd2; // 2-words
|
Line 2128... |
Line 2161... |
// - fetch instruction
|
// - fetch instruction
|
// - increment PC
|
// - increment PC
|
// - set special register defaults for some instructions
|
// - set special register defaults for some instructions
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (advanceI) begin
|
if (advanceI) begin
|
|
if (dOpcode[6:4]!=`IMM) begin
|
epcnt <= epcnt + 5'd1;
|
epcnt <= epcnt + 5'd1;
|
case(epcnt)
|
case(epcnt)
|
5'd0: AXC <= EP[0][ 3: 0];
|
5'd0: AXC <= EP[0][ 3: 0];
|
5'd1: AXC <= EP[0][ 7: 4];
|
5'd1: AXC <= EP[0][ 7: 4];
|
5'd2: AXC <= EP[0][11: 8];
|
5'd2: AXC <= EP[0][11: 8];
|
Line 2163... |
Line 2197... |
5'd28: AXC <= EP[3][19:16];
|
5'd28: AXC <= EP[3][19:16];
|
5'd29: AXC <= EP[3][23:20];
|
5'd29: AXC <= EP[3][23:20];
|
5'd30: AXC <= EP[3][27:24];
|
5'd30: AXC <= EP[3][27:24];
|
5'd31: AXC <= EP[3][31:28];
|
5'd31: AXC <= EP[3][31:28];
|
endcase
|
endcase
|
|
end
|
// AXC <= EP[epcnt[4:3]][{epcnt[2:0],2'b11}:{epcnt[2:0],2'b00}];
|
// AXC <= EP[epcnt[4:3]][{epcnt[2:0],2'b11}:{epcnt[2:0],2'b00}];
|
if (nmi_edge) begin
|
if (nmi_edge) begin
|
nmi_edge <= 1'b0;
|
nmi_edge <= 1'b0;
|
dirqf <= 1'b1;
|
dirqf <= 1'b1;
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
Line 2180... |
Line 2215... |
else if (dirqf) begin
|
else if (dirqf) begin
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
else begin
|
else begin
|
dIR <= insn;
|
dIR <= insn;
|
$display("Fetched pc=%h insn: %h", pc, insn);
|
`include "insn_dump.v"
|
end
|
end
|
nopI <= 1'b0;
|
nopI <= 1'b0;
|
if (dOpcode[6:4]!=`IMM) begin
|
if (dOpcode[6:4]!=`IMM) begin
|
dpc <= pc_axc;
|
dpc <= pc_axc;
|
end
|
end
|
Line 2201... |
Line 2236... |
end
|
end
|
else
|
else
|
pc[AXC] <= fnIncPC(pc_axc);
|
pc[AXC] <= fnIncPC(pc_axc);
|
end
|
end
|
|
|
|
//---------------------------------------------------------
|
|
// Initialize program counters
|
|
//---------------------------------------------------------
|
|
if (resetA) begin
|
|
pc[xAXC] <= `RESET_VECTOR;
|
|
xAXC <= xAXC + 4'd1;
|
|
if (xAXC==4'hF)
|
|
resetA <= 1'b0;
|
|
end
|
|
|
//`include "RPSTAGE.v"
|
//`include "RPSTAGE.v"
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// EXECUTE - part two:
|
// EXECUTE - part two:
|
// - override the default program counter increment for
|
// - override the default program counter increment for
|
Line 2294... |
Line 2338... |
xRt <= 9'd0;
|
xRt <= 9'd0;
|
end
|
end
|
end
|
end
|
`RET: begin
|
`RET: begin
|
pc[xAXC][63:2] <= b[63:2];
|
pc[xAXC][63:2] <= b[63:2];
|
$display("returning to: %h", b);
|
$display("returning to: %h", {b,2'b00});
|
if (AXC==xAXC) begin
|
if (AXC==xAXC) begin
|
dpc[63:2] <= b[63:2];
|
dpc[63:2] <= b[63:2];
|
dIR <= `NOP_INSN;
|
dIR <= `NOP_INSN;
|
end
|
end
|
if (xAXC==dAXC) begin
|
if (xAXC==dAXC) begin
|
Line 2475... |
Line 2519... |
//---------------------------------------------------------
|
//---------------------------------------------------------
|
// Cache loader
|
// Cache loader
|
//---------------------------------------------------------
|
//---------------------------------------------------------
|
if (rst_i) begin
|
if (rst_i) begin
|
cstate <= IDLE;
|
cstate <= IDLE;
|
wr_icache <= 1'b0;
|
// wr_icache <= 1'b0;
|
wr_dcache <= 1'b0;
|
wr_dcache <= 1'b0;
|
end
|
end
|
else begin
|
else begin
|
cmd_en <= 1'b0; // allow this signal only to pulse for a single clock cycle
|
cmd_en <= 1'b0; // allow this signal only to pulse for a single clock cycle
|
wr_icache <= 1'b0;
|
//wr_icache <= 1'b0;
|
wr_dcache <= 1'b0;
|
wr_dcache <= 1'b0;
|
case(cstate)
|
case(cstate)
|
IDLE:
|
IDLE:
|
if (triggerDCacheLoad & !cmd_full) begin
|
|
dcaccess <= 1'b1;
|
|
// we can't do anything until the command buffer is available
|
// we can't do anything until the command buffer is available
|
cmd_en <= 1'b1; // the command fifo should always be available
|
// in theory the command fifo should always be available
|
|
if (!cmd_full) begin
|
|
if (triggerDCacheLoad) begin
|
|
dcaccess <= 1'b1;
|
|
cmd_en <= 1'b1;
|
cmd_instr <= 3'b001; // READ
|
cmd_instr <= 3'b001; // READ
|
cmd_byte_addr <= {pea[29:5],5'b00000};
|
cmd_byte_addr <= {pea[29:5],5'b00000};
|
dadr_o <= {pea[31:5],5'b00000};
|
dadr_o <= {pea[63:5],5'b00000};
|
cmd_bl <= 6'd8; // Eight words per cache line
|
cmd_bl <= 6'd8; // Eight words per cache line
|
cstate <= DCACT;
|
cstate <= DCACT;
|
end
|
end
|
else if (triggerICacheLoad & !cmd_full) begin
|
else if (triggerICacheLoad) begin
|
icaccess <= 1'b1;
|
icaccess <= 1'b1;
|
// we can't do anything until the command buffer is available
|
|
cmd_en <= 1'b1; // the command fifo should always be available
|
cmd_en <= 1'b1; // the command fifo should always be available
|
cmd_instr <= 3'b001; // READ
|
cmd_instr <= 3'b001; // READ
|
cmd_byte_addr <= {ppc[29:5],5'b00000};
|
cmd_byte_addr <= {ppc[29:6],6'h00};
|
iadr_o <= {ppc[31:5],5'b00000};
|
iadr_o <= {ppc[63:6],6'h00};
|
cmd_bl <= 6'd8; // Eight words per cache line
|
cmd_bl <= 6'd16; // Sixteen words per cache line
|
cstate <= ICACT;
|
cstate <= ICACT;
|
end
|
end
|
|
end
|
// Sometime after the read command is issued, the read fifo will begin to fill
|
// Sometime after the read command is issued, the read fifo will begin to fill
|
ICACT:
|
ICACT:
|
if (!rd_empty) begin
|
begin
|
rd_en <= 1'b1; // Data should be available on the next clock cycle
|
rd_en <= 1'b1;
|
cstate <= ICACT0;
|
cstate <= ICACT0;
|
end
|
end
|
ICACT0: // Read word 0
|
//ICACT0: // Read word 0
|
// At this point it should not be necessary to check rd_empty
|
// At this point it should not be necessary to check rd_empty
|
if (!rd_empty) begin
|
// if (!rd_empty) begin
|
wr_icache <= 1'b1;
|
// wr_icache <= 1'b1;
|
idat <= rd_data;
|
// idat <= rd_data;
|
iadr_o[4:2] <= 3'b000;
|
// cstate <= ICACT1;
|
cstate <= ICACT1;
|
// end
|
end
|
|
ICACT1: // Read word 1
|
ICACT0: // Read word 1-15
|
// Might have to wait for subsequent data to be available
|
// Might have to wait for subsequent data to be available
|
if (!rd_empty) begin
|
if (!rd_empty) begin
|
wr_icache <= 1'b1;
|
// wr_icache <= 1'b1;
|
idat <= rd_data;
|
// idat <= rd_data;
|
iadr_o[4:2] <= 3'b001;
|
iadr_o[5:2] <= iadr_o[5:2] + 4'h1;
|
cstate <= ICACT2;
|
if (iadr_o[5:2]==4'hF) begin
|
end
|
|
ICACT2: // Read word 2
|
|
if (!rd_empty) begin
|
|
wr_icache <= 1'b1;
|
|
idat <= rd_data;
|
|
iadr_o[4:2] <= 3'b010;
|
|
cstate <= ICACT3;
|
|
end
|
|
ICACT3: // Read word 3
|
|
if (!rd_empty) begin
|
|
wr_icache <= 1'b1;
|
|
idat <= rd_data;
|
|
iadr_o[4:2] <= 3'b011;
|
|
cstate <= ICACT4;
|
|
end
|
|
ICACT4: // Read word 4
|
|
if (!rd_empty) begin
|
|
wr_icache <= 1'b1;
|
|
idat <= rd_data;
|
|
iadr_o[4:2] <= 3'b100;
|
|
cstate <= ICACT5;
|
|
end
|
|
ICACT5: // Read word 5
|
|
if (!rd_empty) begin
|
|
wr_icache <= 1'b1;
|
|
idat <= rd_data;
|
|
iadr_o[4:2] <= 3'b101;
|
|
cstate <= ICACT6;
|
|
end
|
|
ICACT6: // Read word 6
|
|
if (!rd_empty) begin
|
|
wr_icache <= 1'b1;
|
|
idat <= rd_data;
|
|
iadr_o[4:2] <= 3'b110;
|
|
cstate <= ICACT7;
|
|
end
|
|
ICACT7: // Read word 7
|
|
if (!rd_empty) begin
|
|
rd_en <= 1'b0;
|
rd_en <= 1'b0;
|
wr_icache <= 1'b1;
|
tmem[iadr_o[12:6]] <= {1'b1,iadr_o[63:13]}; // This will cause ihit to go high
|
idat <= rd_data;
|
tvalid[iadr_o[12:6]] <= 1'b1;
|
iadr_o[4:2] <= 3'b111;
|
|
tmem[iadr_o[12:5]] <= {1'b1,iadr_o[31:13]}; // This will cause ihit to go high
|
|
tvalid[iadr_o[12:5]] <= 1'b1;
|
|
cstate <= ICDLY;
|
cstate <= ICDLY;
|
end
|
end
|
|
end
|
ICDLY:
|
ICDLY:
|
// The fifo should have emptied out
|
// The fifo should have emptied out, if not we force it to empty
|
if (!rd_empty) begin
|
if (!rd_empty) begin
|
rd_en <= 1'b1;
|
rd_en <= 1'b1;
|
end
|
end
|
else begin
|
else begin
|
icaccess <= 1'b0;
|
icaccess <= 1'b0;
|
rd_en <= 1'b0;
|
rd_en <= 1'b0;
|
cstate <= IDLE;
|
cstate <= IDLE;
|
end
|
end
|
// Sometime after the read command is issued, the read fifo will begin to fill
|
// Sometime after the read command is issued, the read fifo will begin to fill
|
DCACT:
|
DCACT:
|
if (!rd_empty) begin
|
begin
|
rd_en <= 1'b1; // Data should be available on the next clock cycle
|
rd_en <= 1'b1; // Data should be available on the next clock cycle
|
cstate <= DCACT0;
|
cstate <= DCACT0;
|
end
|
end
|
DCACT0: // Read word 0
|
DCACT0: // Read word 0
|
// At this point it should not be necessary to check rd_empty
|
// At this point it should not be necessary to check rd_empty
|
Line 2600... |
Line 2606... |
DCACT1: // Read word 1
|
DCACT1: // Read word 1
|
// Might have to wait for subsequent data to be available
|
// Might have to wait for subsequent data to be available
|
if (!rd_empty) begin
|
if (!rd_empty) begin
|
wr_dcache <= 1'b1;
|
wr_dcache <= 1'b1;
|
ddat <= rd_data;
|
ddat <= rd_data;
|
dadr_o[4:2] <= 3'b001;
|
dadr_o[4:2] <= dadr_o[4:2]+3'd1;
|
cstate <= DCACT2;
|
if (dadr_o[4:2]==3'b111) begin
|
end
|
|
DCACT2: // Read word 2
|
|
if (!rd_empty) begin
|
|
wr_dcache <= 1'b1;
|
|
ddat <= rd_data;
|
|
dadr_o[4:2] <= 3'b010;
|
|
cstate <= DCACT3;
|
|
end
|
|
DCACT3: // Read word 3
|
|
if (!rd_empty) begin
|
|
wr_dcache <= 1'b1;
|
|
ddat <= rd_data;
|
|
dadr_o[4:2] <= 3'b011;
|
|
cstate <= DCACT4;
|
|
end
|
|
DCACT4: // Read word 4
|
|
if (!rd_empty) begin
|
|
wr_dcache <= 1'b1;
|
|
ddat <= rd_data;
|
|
dadr_o[4:2] <= 3'b100;
|
|
cstate <= DCACT5;
|
|
end
|
|
DCACT5: // Read word 5
|
|
if (!rd_empty) begin
|
|
wr_dcache <= 1'b1;
|
|
ddat <= rd_data;
|
|
dadr_o[4:2] <= 3'b101;
|
|
cstate <= DCACT6;
|
|
end
|
|
DCACT6: // Read word 6
|
|
if (!rd_empty) begin
|
|
wr_dcache <= 1'b1;
|
|
ddat <= rd_data;
|
|
dadr_o[4:2] <= 3'b110;
|
|
cstate <= DCACT7;
|
|
end
|
|
DCACT7: // Read word 7
|
|
if (!rd_empty) begin
|
|
rd_en <= 1'b0;
|
rd_en <= 1'b0;
|
wr_dcache <= 1'b1;
|
|
ddat <= rd_data;
|
|
dadr_o[4:2] <= 3'b111;
|
|
cstate <= DCDLY;
|
cstate <= DCDLY;
|
end
|
end
|
|
end
|
DCDLY:
|
DCDLY:
|
// The fifo should have emptied out
|
// The fifo should have emptied out, if not, empty it out.
|
if (!rd_empty) begin
|
if (!rd_empty) begin
|
rd_en <= 1'b1;
|
rd_en <= 1'b1;
|
end
|
end
|
else begin
|
else begin
|
dcaccess <= 1'b0;
|
dcaccess <= 1'b0;
|