OpenCores
URL https://opencores.org/ocsvn/raptor64/raptor64/trunk

Subversion Repositories raptor64

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 47 to Rev 48
    Reverse comparison

Rev 47 → Rev 48

/raptor64/trunk/rtl/verilog/Raptor64_icache_ram.v
0,0 → 1,52
`timescale 1ns / 1ps
//=============================================================================
// __
// \\__/ o\ (C) 2013 Robert Finch
// \ __ / All rights reserved.
// \/_// robfinch<remove>@opencores.org
// ||
//
// Raptor64_icache_ram.v
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//
//=============================================================================
//
module Raptor64_icache_ram(wclk, we, adr, d, rclk, pc, insn);
input wclk;
input we;
input [13:0] adr;
input [63:0] d;
input rclk;
input [13:0] pc;
output [31:0] insn;
 
reg [31:0] ramLo [0:2047];
reg [31:0] ramHi [0:2047];
reg [13:2] radr;
 
always @(posedge wclk)
if (we) begin
ramLo[adr[13:3]] <= d[31: 0];
ramHi[adr[13:3]] <= d[63:32];
end
 
always @(posedge rclk)
radr <= pc[13:2];
 
assign insn = radr[2] ? ramHi[radr[13:3]] : ramLo[radr[13:3]];
 
endmodule
/raptor64/trunk/rtl/verilog/Raptor64_BranchHistory.v
26,11 → 26,10
//
//=============================================================================
//
module Raptor64_BranchHistory(rst, clk, advanceX, xIRvalid, xIR, pc, xpc, takb, predict_taken);
module Raptor64_BranchHistory(rst, clk, advanceX, xIR, pc, xpc, takb, predict_taken);
input rst;
input clk;
input advanceX;
input xIRvalid;
input [31:0] xIR;
input [63:0] pc;
input [63:0] xpc;
58,7 → 57,7
xOpcode==`BLTI || xOpcode==`BLEI || xOpcode==`BGTI || xOpcode==`BGEI ||
xOpcode==`BLTUI || xOpcode==`BLEUI || xOpcode==`BGTUI || xOpcode==`BGEUI)
;
wire isxBranch = xIRvalid && (isxBranchI || xOpcode==`TRAPcc || xOpcode==`TRAPcci || xOpcode==`BTRI || xOpcode==`BTRR);
wire isxBranch = (isxBranchI || xOpcode==`TRAPcc || xOpcode==`TRAPcci || xOpcode==`BTRI || xOpcode==`BTRR);
 
// Two bit saturating counter
reg [1:0] xbits_new;
/raptor64/trunk/rtl/verilog/Raptor64_TLB.v
105,13 → 105,13
end
 
wire unmappedArea = pc[63:52]==12'hFFD || pc[63:52]==12'hFFE || pc[63:52]==12'hFFF;
wire unmappedDataArea = ea[63:52]==12'hFFD || ea[63:52]==12'hFFE || ea[63:52]==12'hFFF;
wire m1UnmappedDataArea = pea[63:13]>=12'hFFD;
wire unmappedDataArea = ea[63:52]==12'hFFD || ea[63:52]==12'hFFE || ea[63:52]==12'hFFF || ea[63:52]==12'h000;
wire m1UnmappedDataArea = pea[63:52]==12'hFFD || pea[63:52]==12'hFFE || pea[63:52]==12'hFFF || pea[63:52]==12'h000;
 
always @(posedge clk)
if (rst) begin
Random <= 4'hF;
Wired <= 4'd0;
Random <= 3'h7;
Wired <= 3'd0;
end
else begin
if (Random==Wired)
128,10 → 128,10
`TLBWired: Wired <= dati[2:0];
`TLBIndex: Index <= dati[5:0];
`TLBRandom: Random <= dati[2:0];
`TLBPageMask: HTLBPageMask <= {dati[63:13],13'd0};
`TLBVirtPage: HTLBVirtPage <= {dati[63:13],13'd0};
`TLBPhysPage0: HTLBPhysPage0 <= {dati[63:13],13'd0};
`TLBPhysPage1: HTLBPhysPage1 <= {dati[63:13],13'd0};
`TLBPageMask: HTLBPageMask <= dati[63:13];
`TLBVirtPage: HTLBVirtPage <= dati[63:13];
`TLBPhysPage0: HTLBPhysPage0 <= dati[63:13];
`TLBPhysPage1: HTLBPhysPage1 <= dati[63:13];
`TLBASID: begin
HTLBValid <= dati[0];
HTLBD <= dati[1];
154,7 → 154,7
HTLBD <= TLBD[i];
HTLBValid <= TLBValid[i];
end
if (wTlbwi) begin
else if (wTlbwi) begin
TLBVirtPage[i] <= HTLBVirtPage;
TLBPhysPage0[i] <= HTLBPhysPage0;
TLBPhysPage1[i] <= HTLBPhysPage1;
163,7 → 163,7
TLBD[i] <= HTLBD;
TLBValid[i] <= HTLBValid;
end
if (wTlbwr) begin
else if (wTlbwr) begin
TLBVirtPage[i] <= HTLBVirtPage;
TLBPhysPage0[i] <= HTLBPhysPage0;
TLBPhysPage1[i] <= HTLBPhysPage1;
/raptor64/trunk/rtl/verilog/Raptor64_SetOperandRegs.v
28,7 → 28,7
// avoided, which would otherwise occur.
//=============================================================================
 
module Raptor64_SetOperandRegs(rst, clk, advanceI, advanceR, advanceX, b, AXC, xAXC, insn, xIR, dRa, dRb, dRc);
module Raptor64_SetOperandRegs(rst, clk, advanceI, advanceR, advanceX, b, AXC, xAXC, insn, xIR, dRa, dRb, dRc, nxt_Ra, nxt_Rb, nxt_Rc);
input rst;
input clk;
input advanceI;
45,6 → 45,12
reg [8:0] dRb;
output [8:0] dRc;
reg [8:0] dRc;
output [8:0] nxt_Ra;
reg [8:0] nxt_Ra;
output [8:0] nxt_Rb;
reg [8:0] nxt_Rb;
output [8:0] nxt_Rc;
reg [8:0] nxt_Rc;
 
wire [6:0] iOpcode = insn[31:25];
wire [6:0] xOpcode = xIR[31:25];
51,114 → 57,125
wire [5:0] xFunc = xIR[5:0];
wire [6:0] iFunc7 = insn[6:0];
 
always @(posedge clk)
if (rst) begin
dRa <= 9'd0;
dRb <= 9'd0;
dRc <= 9'd0;
end
else begin
 
always @*
begin
nxt_Ra <= dRa;
nxt_Rb <= dRb;
nxt_Rc <= dRc;
if (advanceI) begin
// Default settings, to be overridden
dRa <= {AXC,insn[24:20]};
dRb <= {AXC,insn[19:15]};
dRc <= {AXC,insn[14:10]};
nxt_Ra <= {AXC,insn[24:20]};
nxt_Rb <= {AXC,insn[19:15]};
nxt_Rc <= {AXC,insn[14:10]};
casex(iOpcode)
`MISC:
case(iFunc7)
`IRET: begin
dRa <= {AXC,5'd25};
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Ra <= {AXC,5'd25};
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
`ERET: begin
dRa <= {AXC,5'd24};
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Ra <= {AXC,5'd24};
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
default:
begin
dRa <= 9'd0;
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Ra <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
endcase
`R: begin dRb <= 9'd0; dRc <= 9'd0; end
`RR: dRc <= 9'd0;
`TRAPcc: dRc <= 9'd0;
`TRAPcci: begin dRb <= 9'd0; dRc <= 9'd0; end
`R: begin nxt_Rb <= 9'd0; nxt_Rc <= 9'd0; end
`RR: nxt_Rc <= 9'd0;
`TRAPcc: nxt_Rc <= 9'd0;
`TRAPcci: begin nxt_Rb <= 9'd0; nxt_Rc <= 9'd0; end
`CALL,`JMP,`NOPI:
begin
dRa <= 9'd0;
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Ra <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
`RET: begin
dRa <= {AXC,5'd30};
dRb <= {AXC,5'd31};
dRc <= 9'd0;
nxt_Ra <= {AXC,5'd30};
nxt_Rb <= {AXC,5'd31};
nxt_Rc <= 9'd0;
end
`LB,`LBU,`LH,`LHU,`LC,`LCU,`LW,`LP,`LSH,`LSW,`LF,`LFD,`LFP,`LFDP,`LWR:
begin
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
`SB,`SC,`SH,`SW,`SP,`SSH,`SSW,`SF,`SFD,`SFP,`SFDP,`SWC:
dRc <= 9'd0;
nxt_Rc <= 9'd0;
`INB,`INBU,`INCH,`INCU,`INH,`INHU,`INW:
begin
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
`OUTB,`OUTC,`OUTH,`OUTW:
dRc <= 9'd0;
nxt_Rc <= 9'd0;
`BLTI,`BLEI,`BGTI,`BGEI,
`BLTUI,`BLEUI,`BGTUI,`BGEUI,
`BEQI,`BNEI:
begin
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
`BTRI: dRc <= 9'd0;
`BTRI: nxt_Rc <= 9'd0;
`SLTI,`SLEI,`SGTI,`SGEI,
`SLTUI,`SLEUI,`SGTUI,`SGEUI,
`SEQI,`SNEI:
begin
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
`ADDI,`ADDUI,`SUBI,`SUBUI,`CMPI,`CMPUI,
`ANDI,`XORI,`ORI,`MULUI,`MULSI,`DIVUI,`DIVSI:
begin
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
`JAL:
begin
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
`SETLO: begin dRa <= {AXC,insn[26:22]}; dRb <= 9'd0; dRc <= 9'd0; end
`SETMID: begin dRa <= {AXC,insn[26:22]}; dRb <= 9'd0; dRc <= 9'd0; end
`SETHI: begin dRa <= {AXC,insn[26:22]}; dRb <= 9'd0; dRc <= 9'd0; end
default: dRa <= {AXC,insn[24:20]};
`SETLO: begin nxt_Ra <= {AXC,insn[26:22]}; nxt_Rb <= 9'd0; nxt_Rc <= 9'd0; end
`SETMID: begin nxt_Ra <= {AXC,insn[26:22]}; nxt_Rb <= 9'd0; nxt_Rc <= 9'd0; end
`SETHI: begin nxt_Ra <= {AXC,insn[26:22]}; nxt_Rb <= 9'd0; nxt_Rc <= 9'd0; end
default: nxt_Ra <= {AXC,insn[24:20]};
endcase
end
else if (advanceR) begin
dRa <= 9'd0;
dRb <= 9'd0;
dRc <= 9'd0;
nxt_Ra <= 9'd0;
nxt_Rb <= 9'd0;
nxt_Rc <= 9'd0;
end
// no else here
if (advanceX) begin
if (xOpcode==`R) begin
if (xFunc==`EXEC) begin
dRa <= {xAXC,b[24:20]};
dRb <= {xAXC,b[19:15]};
dRc <= {xAXC,b[14:10]};
nxt_Ra <= {xAXC,b[24:20]};
nxt_Rb <= {xAXC,b[19:15]};
nxt_Rc <= {xAXC,b[14:10]};
end
end
end
end
 
always @(posedge clk)
if (rst) begin
dRa <= 9'd0;
dRb <= 9'd0;
dRc <= 9'd0;
end
else begin
dRa <= nxt_Ra;
dRb <= nxt_Rb;
dRc <= nxt_Rc;
end
 
endmodule
/raptor64/trunk/rtl/verilog/Raptor64_BypassMux.v
0,0 → 1,53
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2012-2013 Robert Finch, Stratford
// \ __ / All rights reserved.
// \/_// robfinch<remove>@opencores.org
// ||
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ============================================================================
//
module Raptor64_BypassMux(dpc,dRn,xRt,m1Rt,m2Rt,wRt,tRt,rfo,xData,m1Data,m2Data,wData,tData,nxt);
input [63:0] dpc;
input [8:0] dRn;
input [8:0] xRt;
input [8:0] m1Rt;
input [8:0] m2Rt;
input [8:0] wRt;
input [8:0] tRt;
input [63:0] rfo; // register file output
input [63:0] xData;
input [63:0] m1Data;
input [63:0] m2Data;
input [63:0] wData;
input [63:0] tData;
output [63:0] nxt;
reg [63:0] nxt;
 
always @(dRn or xData or m1Data or m2Data or wData or tData or rfo or dpc or xRt or m1Rt or m2Rt or wRt or tRt)
casex(dRn)
9'bxxxx00000: nxt <= 64'd0;
9'bxxxx11101: nxt <= dpc;
xRt: nxt <= xData;
m1Rt: nxt <= m1Data;
m2Rt: nxt <= m2Data;
wRt: nxt <= wData;
tRt: nxt <= tData;
default: nxt <= rfo;
endcase
 
endmodule
/raptor64/trunk/rtl/verilog/Raptor64_opcodes.v
98,6 → 98,10
`define ERRADR 6'd24
`define TBA 6'd25
`define NON_ICACHE_SEG 6'd26
`define CS 6'd27
`define DS 6'd28
`define SS 6'd29
`define ES 6'd30
`define FPCR 6'd32
`define IPC 6'd33
`define RAND 6'd34
214,13 → 218,23
`define TGTUI 5'd9
`define TRAI 5'd10
`define TRNI 5'd11
 
`define SIMD 7'd20
`define SIMD_ADD 5'd0
`define SIMD_SUB 5'd1
`define SIMD_MUL 5'd2
`define SIMD_DIV 5'd3
`define SIMD_CMP 5'd4
`define SIMD_AND 5'd8
`define SIMD_OR 5'd9
`define SIMD_XOR 5'd10
`define BITFIELD 7'd21
`define BFINS 3'd0
`define BFSET 3'd1
`define BFCLR 3'd2
`define BFCHG 3'd3
`define BFEXT 3'd4
`define BFEXTU 3'd4
`define BFEXTS 3'd5
`define SEXT 3'd6
`define MUX 7'd22
`define MYST 7'd23
`define CALL 7'd24
420,6 → 434,9
`define SETLO 7'b11100xx
`define SETMID 7'b11101xx
`define SETHI 7'b11110xx
`define IMM1 7'd124
`define IMM2 7'd125
`define IMM3 7'd126
 
`define NOP_INSN 32'b1101111_0_00000000_00000000_00000000
 
/raptor64/trunk/rtl/verilog/Raptor64_tb.v
32,6 → 32,8
reg pulse1000Hz,pulse100Hz;
wire [7:0] config_rec;
reg [7:0] config_reco;
//wire sm_ack;
wire [7:0] sm_dato;
 
wire uart_ack = sys_iocyc && sys_stb && (sys_adr[23:8]==16'hDC_0A);
wire rast_ack = sys_iocyc && sys_stb && (sys_adr[23:8]==16'hDA_01);
41,12 → 43,12
wire dt_ack = sys_iocyc && sys_stb && (sys_adr[23:8]==16'hDC_04);
wire p100ack = sys_iocyc && sys_stb && (sys_adr[23:0]==24'hDCFFFC);
wire p1000ack = sys_iocyc && sys_stb && (sys_adr[23:0]==24'hDCFFFD);
wire config_rec_ack = sys_iocyc && sys_stb && sys_adr[23:0]==24'hDCFFFF;
wire config_rec_ack = sys_iocyc && sys_stb && sys_adr[23:3]==21'b1101_1100_1111_1111_1111_0;
wire perr_ack = sys_iocyc && sys_stb && sys_adr[23:0]==24'hDCFFFE;
wire tmp_ack = sys_iocyc && sys_stb && (sys_adr[23:8]==16'hDC03);
wire sm_ack = sys_iocyc && sys_stb && (sys_adr[23:16]==8'hDB);
 
assign ram_ack = sys_cyc && sys_stb && (sys_adr[63:32]==32'd1);
assign sys_ack = br_ack|stk_ack|scr_ack|tc_ack|pic_ack|ram_ack|uart_ack|rast_ack|AC97_ack|spr_ack|Led_ack|dt_ack|p100ack|p1000ack|config_rec_ack|tmp_ack|perr_ack;
//assign ram_ack = sys_cyc && sys_stb && (sys_adr[63:32]==32'd1);
 
assign config_rec = 8'b0000_0111;
 
53,7 → 55,32
always @(config_rec_ack)
config_reco <= config_rec_ack ? config_rec : 8'd0;
 
wire cs_ram = sys_cyc && sys_stb && (sys_adr[63:32]==32'd1);
reg [63:0] sysram [0:16000];
always @(posedge clk)
if (cs_ram & sys_we) begin
$display("Wrote ram[%h]=%h", sys_adr, sys_dbo);
sysram[sys_adr[15:3]] <= sys_dbo;
end
wire [63:0] ramo = cs_ram ? sysram[sys_adr[15:3]] : 64'd0;
reg ack1,ack2,ack3,ack4,ack5,ack6,ack7,ack8;
always @(posedge clk)
begin
ack1 <= cs_ram;
ack2 <= ack1 & cs_ram;
ack3 <= ack2 & cs_ram;
ack4 <= ack3 & cs_ram;
ack5 <= ack4 & cs_ram;
ack6 <= ack5 & cs_ram;
ack7 <= ack6 & cs_ram;
ack8 <= ack7 & cs_ram;
end
wire ram_ack = cs_ram & ack8;
 
assign sys_ack = br_ack|stk_ack|scr_ack|tc_ack|pic_ack|ram_ack|uart_ack|rast_ack|
AC97_ack|spr_ack|Led_ack|dt_ack|
p100ack|p1000ack|config_rec_ack|tmp_ack|perr_ack|sm_ack;
initial begin
clk = 1;
pulse1000Hz = 0;
94,7 → 121,20
end
end
 
//sema_mem usm
//(
// .rst_i(rst),
// .clk_i(clk),
// .cyc_i(sys_iocyc),
// .stb_i(sys_stb),
// .ack_o(sm_ack),
// .we_i(sys_we),
// .adr_i(sys_adr[23:0]),
// .dat_i(sys_dbo[7:0]),
// .dat_o(sm_dato)
//);
 
 
rtfTextController tc1
(
.rst_i(rst),
830,7 → 870,8
64'hFFFFFFFFFFFFFFF8: romout <= 64'h37800000000DE000;
default: romout <= 64'd0;
endcase
assign sys_dbi = br_dato|keybdout|stk_dato|scr_dato| {4{tc_dato}} | {4{pic_dato}} | {8{config_reco}};
assign sys_dbi = br_dato|keybdout|stk_dato|scr_dato| {4{tc_dato}}
| {4{pic_dato}} | {8{config_reco}} | ramo | {8{sm_dato}};
 
 
Raptor64sc u1
/raptor64/trunk/rtl/verilog/Raptor64_dcache_ram.v
21,18 → 21,37
//
// ============================================================================
//
module Raptor64_dcache_ram(clk,wr,sel,wadr,i,radr,o);
input clk;
module Raptor64_dcache_ram(wclk,wr,sel,wadr,i,rclk,radr,o);
input wclk;
input wr;
input [3:0] sel;
input [13:2] wadr;
input [31:0] i;
input [13:3] radr;
input [7:0] sel;
input [14:3] wadr;
input [63:0] i;
input rclk;
input [14:3] radr;
output [63:0] o;
 
reg [7:0] mem0 [2047:0];
reg [31:0] memH [2047:0];
reg [63:0] mem [0:4095];
reg [14:3] rradr;
 
always @(posedge wclk)
if (wr) begin
if (sel[0]) mem[wadr][ 7: 0] <= i[ 7: 0];
if (sel[1]) mem[wadr][15: 8] <= i[15: 8];
if (sel[2]) mem[wadr][23:16] <= i[23:16];
if (sel[3]) mem[wadr][31:24] <= i[31:24];
if (sel[4]) mem[wadr][39:32] <= i[39:32];
if (sel[5]) mem[wadr][47:40] <= i[47:40];
if (sel[6]) mem[wadr][55:48] <= i[55:48];
if (sel[7]) mem[wadr][63:56] <= i[63:56];
end
 
always @(posedge rclk)
rradr <= radr[14:3];
 
assign o = mem[rradr];
 
/*
syncRam2kx8_1rw1r u1
(
.wrst(1'b0),
161,5 → 180,5
.o(o[63:56])
);
 
endmodule
*/endmodule
 
/raptor64/trunk/rtl/verilog/Raptor64sc.v
30,15 → 30,14
//`define FLOATING_POINT 1
//`define BTB 1
//`define TLB 1
//`define SIMD 1
`define SEGMENTATION 1
 
`define RESET_VECTOR 64'hFFFF_FFFF_FFFF_FFF0
 
`define ITLB_MissHandler 64'hFFFF_FFFF_FFFF_FFC0
`define DTLB_MissHandler 64'hFFFF_FFFF_FFFF_FFB0
 
`define EX_NON 9'd000
`define EX_TRAP 9'd32 // Trap exception
`define EX_IRQ 9'd449 // interrupt
`define EX_IRQ 9'd448 // base IRQ interrupt
`define EX_DBZ 9'd488 // divide by zero
`define EX_OFL 9'd489 // overflow
`define EX_UNIMP_INSN 9'd495 // unimplemented instruction
52,7 → 51,7
 
`include "Raptor64_opcodes.v"
 
module Raptor64sc(rst_i, clk_i, nmi_i, irq_i, 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
);
parameter IDLE = 5'd1;
68,6 → 67,7
input clk_i;
input nmi_i;
input irq_i;
input [4:0] irq_no;
 
output [1:0] bte_o; // burst type
reg [1:0] bte_o;
101,44 → 101,51
reg [3:0] state;
reg [5:0] fltctr;
wire fltdone = fltctr==6'd0;
reg resetA;
reg im,bu_im; // interrupt mask
reg bu_im; // interrupt mask
reg im1; // temporary interrupt mask for LM/SM
reg [7:0] ie_fuse; // interrupt enable fuse
wire im = ~ie_fuse[7];
reg [1:0] rm; // fp rounding mode
reg FXE; // fp exception enable
wire KernelMode;
wire [31:0] sr = {bu_im,15'd0,im,1'b0,KernelMode,FXE,2'b00,10'b0};
reg [31:0] dIR,xIR,m1IR,m2IR,wIR;
reg [31:0] dIR,d1IR,xIR,m1IR,m2IR,wIR;
reg [31:0] ndIR; // next dIR
reg [63:0] pc; // ipc
wire [63:0] pchistoric;
reg pccap;
reg pccap; // flag 1=capture PC history
reg [63:0] ErrorEPC;
reg [63:0] EPC [0:15];
reg [63:0] IPC [0:15];
reg [63:0] PCS [0:15];
reg [15:0] StatusEXL;
reg [63:0] dpc,xpc,m1pc,m2pc,wpc;
reg ipcv,dpcv,xpcv,m1pcv,m2pcv,wpcv; // PC valid indicators
wire [63:0] rfoa,rfob,rfoc;
reg [63:0] EPC [0:15]; // Exception return address
reg [63:0] IPC [0:15]; // Interrupt return address
`ifdef SEGMENTATION
reg [63:16] CS [0:15]; // Code segment
reg [63:16] DS [0:15]; // Data segment
reg [63:16] SS [0:15]; // Stack segment
reg [63:16] ES [0:15]; // BSS segment
`endif
reg dStatusHWI,xStatusHWI,m1StatusHWI,m2StatusHWI;
reg dIm,xIm,m1Im,m2Im;
reg dNmi,xNmi,m1Nmi,m2Nmi,wNmi;
reg [15:0] StatusEXL; // 1= context in exception state
reg [63:0] dpc,d1pc,xpc,m1pc,m2pc,wpc; // PC's associated with instruction in pipeline
wire [63:0] rfoa,rfob,rfoc; // register file outputs
wire [8:0] dRa,dRb,dRc;
reg [8:0] wRt,m1Rt,m2Rt,tRt;
wire [8:0] xRt;
reg xRtZero;
reg [63:0] ea;
reg [4:0] cstate;
reg dbranch_taken,xbranch_taken;
reg [8:0] xRt,wRt,m1Rt,m2Rt,tRt; // target register
reg [63:0] ea; // effective data address
reg [4:0] cstate; // cache state
reg dbranch_taken,xbranch_taken; // flag: 1=branch taken
reg [63:0] mutex_gate;
reg [63:0] TBA; // Trap Base Address
reg [8:0] dextype,xextype,m1extype,m2extype,wextype,textype;
reg [63:0] TBA; // Trap Base Address
reg [8:0] dextype,d1extype,xextype,m1extype,m2extype,wextype,textype;
reg [3:0] epat [0:255];
reg [7:0] eptr;
reg [3:0] dAXC,xAXC,m1AXC,m2AXC,wAXC;
reg [3:0] dAXC,d1AXC,xAXC,m1AXC,m2AXC,wAXC; // context active per pipeline stage
wire [3:0] AXC = (eptr==8'h00) ? 4'h0 : epat[eptr];
reg dtinit;
reg dcache_on;
reg dtinit; // 1=data cache tags are being intialized
reg dcache_on; // 1= data cache is enabled
wire [63:0] cdat; // data cache output
reg [63:32] nonICacheSeg;
reg [1:0] FPC_rm;
reg [1:0] FPC_rm; // fp: rounding mode
reg FPC_SL; // result is negative (and non-zero)
reg FPC_SE; // result is zero
reg FPC_SG; // result is positive (and non-zero)
155,7 → 162,6
FPC_SI,
16'd0
};
wire [63:0] cdat;
reg [63:0] wr_addr;
reg [31:0] insn;
reg clk_en;
172,6 → 178,7
 
wire [6:0] iOpcode = insn[31:25];
wire [6:0] iFunc = insn[6:0];
wire [5:0] iFunc6 = insn[5:0];
wire [6:0] dOpcode = dIR[31:25];
wire [6:0] dFunc = dIR[6:0];
wire [5:0] dFunc6 = dIR[5:0];
179,8 → 186,14
wire [6:0] xFunc = xIR[6:0];
wire [5:0] xFunc6 = xIR[5:0];
wire [4:0] xFunc5 = xIR[4:0];
reg [6:0] m1Opcode,m2Opcode,wOpcode;
reg [6:0] m1Func,m2Func,wFunc;
wire [6:0] m1Opcode,m2Opcode,wOpcode;
assign m1Opcode = m1IR[31:25];
assign m2Opcode = m2IR[31:25];
assign wOpcode = wIR[31:25];
wire [6:0] m1Func,m2Func,wFunc;
assign m1Func = m1IR[6:0];
assign m2Func = m2IR[6:0];
assign wFunc = wIR[6:0];
wire [5:0] m1Func6 = m1Func[5:0];
wire [5:0] m2Func6 = m2Func[5:0];
wire [5:0] wFunc6 = wIR[5:0];
188,20 → 201,23
reg [63:0] m2Addr;
reg [63:0] tick;
reg [63:0] a,b,c,imm,m1b;
reg [1:0] scale;
reg prev_ihit;
reg rsf;
reg [63:5] resv_address;
wire [1:0] scale = xIR[9:8];
wire [1:0] offset2 = xIR[7:6];
reg rsf; // reserrved address flag
reg [63:5] resv_address; // reserved address
reg dirqf,rirqf,m1irqf,m2irqf,wirqf,tirqf;
reg xirqf;
wire advanceX_edge;
wire takb;
wire advanceI,advanceR,advanceX,advanceM1,advanceW,advanceT;
wire advanceI,advanceR,advanceR1,advanceX,advanceM1,advanceW,advanceT; // Pipeline advance signals
reg m1clkoff,m2clkoff,m3clkoff,m4clkoff,wclkoff;
reg dFip,xFip,m1Fip,m2Fip,m3Fip,m4Fip,wFip;
reg dFip,d1Fip,xFip,m1Fip,m2Fip,m3Fip,m4Fip,wFip;
reg cyc1;
reg LoadNOPs;
reg dIRvalid,xIRvalid,m1IRvalid,m2IRvalid,wIRvalid,tIRvalid;
reg m1IsLoad,m1IsStore;
reg m2IsLoad,m2IsStore;
reg wIsStore;
reg m1IsOut,m1IsIn;
 
function [63:0] fnIncPC;
input [63:0] fpc;
210,12 → 226,119
end
endfunction
 
function [7:0] fnSelect;
input [6:0] opcode;
input [2:0] addr;
case(opcode)
`LBU,`LB,`SB,`INB,`INBU,`OUTB:
case(addr)
3'b000: fnSelect = 8'b00000001;
3'b001: fnSelect = 8'b00000010;
3'b010: fnSelect = 8'b00000100;
3'b011: fnSelect = 8'b00001000;
3'b100: fnSelect = 8'b00010000;
3'b101: fnSelect = 8'b00100000;
3'b110: fnSelect = 8'b01000000;
3'b111: fnSelect = 8'b10000000;
endcase
`LC,`LCU,`SC,`INCH,`INCU,`OUTC:
case(addr[2:1])
2'b00: fnSelect = 8'b00000011;
2'b01: fnSelect = 8'b00001100;
2'b10: fnSelect = 8'b00110000;
2'b11: fnSelect = 8'b11000000;
endcase
`LHU,`LH,`SH,`LSH,`LF,`LFP,`SF,`SFP,`SSH,`INH,`INHU,`OUTH:
case(addr[2])
1'b0: fnSelect = 8'b00001111;
1'b1: fnSelect = 8'b11110000;
endcase
`LW,`LWR,`LM,`LFD,`LSW,`LP,`LFDP,
`SW,`SM,`SFD,`SSW,`SWC,`SP,`SFDP,`INW,`OUTW:
fnSelect = 8'b11111111;
endcase
endfunction
 
reg [7:0] data8;
reg [15:0] data16;
reg [31:0] data32;
reg [63:0] data64;
 
always @(sel_o or dat_i)
case(sel_o)
8'b00000001: data8 <= #1 dat_i[ 7: 0];
8'b00000010: data8 <= #1 dat_i[15: 8];
8'b00000100: data8 <= #1 dat_i[23:16];
8'b00001000: data8 <= #1 dat_i[31:24];
8'b00010000: data8 <= #1 dat_i[39:32];
8'b00100000: data8 <= #1 dat_i[47:40];
8'b01000000: data8 <= #1 dat_i[55:48];
8'b10000000: data8 <= #1 dat_i[63:56];
default: data8 <= 8'h00;
endcase
 
always @(sel_o or dat_i)
case(sel_o)
8'b00000011: data16 <= #1 dat_i[15: 0];
8'b00001100: data16 <= #1 dat_i[31:16];
8'b00110000: data16 <= #1 dat_i[47:32];
8'b11000000: data16 <= #1 dat_i[63:48];
default: data16 <= #1 16'hDEAD;
endcase
 
always @(sel_o or dat_i)
case(sel_o)
8'b00001111: data32 <= #1 dat_i[31: 0];
8'b11110000: data32 <= #1 dat_i[63:32];
default: data32 <= #1 32'hDEADDEAD;
endcase
 
always @(sel_o or dat_i)
data64 <= #1 dat_i;
 
assign KernelMode = StatusEXL[xAXC]|StatusHWI;
 
wire iIsLSPair = iOpcode==`SP || iOpcode==`LP || iOpcode==`SFP || iOpcode==`LFP || iOpcode==`SFDP || iOpcode==`LFDP;
wire dIsLSPair = dOpcode==`SP || dOpcode==`LP || dOpcode==`SFP || dOpcode==`LFP || dOpcode==`SFDP || dOpcode==`LFDP;
//wire iIsLSPair = iOpcode==`SP || iOpcode==`LP || iOpcode==`SFP || iOpcode==`LFP || iOpcode==`SFDP || iOpcode==`LFDP ||
// (iOpcode==`MEMNDX && (iFunc6==`SPX || iFunc6==`LPX || iFunc6==`SFPX || iFunc6==`LFPX || iFunc6==`SFDPX || iFunc6==`LFDPX));
//wire dIsLSPair = dOpcode==`SP || dOpcode==`LP || dOpcode==`SFP || dOpcode==`LFP || dOpcode==`SFDP || dOpcode==`LFDP ||
// (dOpcode==`MEMNDX && (dFunc6==`SPX || dFunc6==`LPX || dFunc6==`SFPX || dFunc6==`LFPX || dFunc6==`SFDPX || dFunc6==`LFDPX));
//wire xIsLSPair = xOpcode==`SP || xOpcode==`LP || xOpcode==`SFP || xOpcode==`LFP || xOpcode==`SFDP || xOpcode==`LFDP ||
// (xOpcode==`MEMNDX && (xFunc6==`SPX || xFunc6==`LPX || xFunc6==`SFPX || xFunc6==`LFPX || xFunc6==`SFDPX || xFunc6==`LFDPX));
 
 
//-----------------------------------------------------------------------------
// Segmentation
//
// If the upper nybble of the address is 'F' then segmentation is not applied.
// This allows for bootstrapping and operating system use. Also when in kernel
// mode the lowest 64k of memory is unsegmented to allow easier access to
// operating system variables.
//
// Otherwise: the CS register is always in use for code addresses.
// Which segment is used for data addresses depends on the upper nybble of
// the address.
//-----------------------------------------------------------------------------
`ifdef SEGMENTATION
wire [63:0] spc; // segmented PC
reg [63:0] sea; // segmented effective address
assign spc = pc[63:60]==4'hF ? pc : {CS[AXC][63:16] + pc[59:16],pc[15:0]};
always @(ea or KernelMode)
if (KernelMode && ea[63:16]==48'h0)
sea <= ea;
else
case(ea[63:60])
4'hF: sea <= ea;
4'hE: sea <= {SS[xAXC][63:16] + ea[59:16],ea[15:0]};
4'hD: sea <= {ES[xAXC][63:16] + ea[59:16],ea[15:0]};
default:
sea <= {DS[xAXC][63:16] + ea[59:16],ea[15:0]};
endcase
`else
wire [63:0] spc = pc;
wire [63:0] sea = ea;
`endif
 
//-----------------------------------------------------------------------------
// TLB
// The TLB contains 64 entries, that are 8 way set associative.
// The TLB is dual ported and shared between the instruction and data streams.
225,22 → 348,22
wire [63:0] tlbo;
`ifdef TLB
wire [63:0] TLBVirtPage;
wire wTlbp = wIRvalid && advanceW && wOpcode==`MISC && wFunc==`TLBP;
wire wTlbrd = wIRvalid && advanceW && wOpcode==`MISC && wFunc==`TLBR;
wire wTlbwr = wIRvalid && advanceW && wOpcode==`MISC && wFunc==`TLBWR;
wire wTlbwi = wIRvalid && advanceW && wOpcode==`MISC && wFunc==`TLBWI;
wire wMtspr = wIRvalid && advanceW && wOpcode==`R && wFunc==`MTSPR;
wire xTlbrd = xIRvalid && advanceX && xOpcode==`MISC && xFunc==`TLBR;
wire xTlbwr = xIRvalid && advanceX && xOpcode==`MISC && xFunc==`TLBWR;
wire xTlbwi = xIRvalid && advanceX && xOpcode==`MISC && xFunc==`TLBWI;
wire wTlbp = advanceW && wOpcode==`MISC && wFunc==`TLBP;
wire wTlbrd = advanceW && wOpcode==`MISC && wFunc==`TLBR;
wire wTlbwr = advanceW && wOpcode==`MISC && wFunc==`TLBWR;
wire wTlbwi = advanceW && wOpcode==`MISC && wFunc==`TLBWI;
wire wMtspr = advanceW && wOpcode==`R && wFunc==`MTSPR;
wire xTlbrd = advanceX && xOpcode==`MISC && xFunc==`TLBR;
wire xTlbwr = advanceX && xOpcode==`MISC && xFunc==`TLBWR;
wire xTlbwi = advanceX && xOpcode==`MISC && xFunc==`TLBWI;
wire ITLBMiss,DTLBMiss;
 
Raptor64_TLB u22
Raptor64_TLB u26
(
.rst(rst_i),
.clk(clk),
.pc(pc),
.ea(ea),
.pc(spc),
.ea(sea),
.ppc(ppc),
.pea(pea),
.m1IsStore(advanceM1 && m1IsStore),
253,9 → 376,9
.xTlbwr(xTlbwr),
.xTlbwi(xTlbwi),
.wr(wMtspr),
.wregno(wIR[12:7]),
.wregno(wIR[11:6]),
.dati(wData),
.xregno(xIR[12:7]),
.xregno(xIR[11:6]),
.dato(tlbo),
.ITLBMiss(ITLBMiss),
.DTLBMiss(DTLBMiss),
263,8 → 386,8
);
 
`else
assign ppc = pc;
assign pea = ea;
assign ppc = spc;
assign pea = sea;
`endif
 
//-----------------------------------------------------------------------------
285,6 → 408,7
else
cpu_clk_en <= clk_en;
end
//assign clk = clk_i;
 
//-----------------------------------------------------------------------------
// Random number register:
317,6 → 441,7
//
// On a bus error, the instruction cache / buffer is loaded with a SYSCALL 509
// instruction, which is a call to the bus error handler.
// Line size is 16 half-words (64 bytes). Total cache size is 16kB.
//
//-----------------------------------------------------------------------------
//reg lfdir;
334,19 → 459,18
reg [63:0] icadr;
 
// SYSCALL 509
wire syscall509 = 32'b0000000_11000_0000_11111110_10010111;
wire syscall509 = 32'b0000000_00000_0000_11111110_10010111;
wire [63:0] bevect = {syscall509,syscall509};
 
// Xilinx Core Generator Component
Raptor64_icache_ram u1
(
.clka(clk), // input clka
.wea(icaccess & (ack_i|err_i)), // input [0 : 0] wea
.addra(icadr[12:3]), // input [9 : 0] addra
.dina(err_i ? bevect : dat_i), // input [63 : 0] dina
.clkb(~clk), // input clkb
.addrb(pc[12:2]), // input [8 : 0] addrb
.doutb(insnbundle) // output [127 : 0] doutb
.wclk(clk),
.we(icaccess & (ack_i|err_i)),
.adr(icadr[13:0]),
.d(err_i ? bevect : dat_i),
.rclk(~clk),
.pc(pc[13:0]),
.insn(insnbundle)
);
 
always @(insnbundle or ICacheAct or insnbuf)
361,24 → 485,25
always @(insn1,insnkey)
insn <= insn1 ^ insnkey;
 
reg [63:13] tmem [127:0];
reg [127:0] tvalid;
reg [63:14] tmem [255:0];
reg [255:0] tvalid;
 
initial begin
for (n=0; n < 128; n = n + 1)
for (n=0; n < 256; n = n + 1)
tmem[n] = 0;
for (n=0; n < 128; n = n + 1)
for (n=0; n < 256; n = n + 1)
tvalid[n] = 0;
end
 
wire [64:13] tgout;
assign tgout = {tvalid[pc[12:6]],tmem[pc[12:6]]};
assign ihit = (tgout=={1'b1,ppc[63:13]});
wire [64:14] tgout;
assign tgout = {tvalid[pc[13:6]],tmem[pc[13:6]]};
assign ihit = (tgout=={1'b1,ppc[63:14]});
assign ibufrdy = ibufadr[63:2]==ppc[63:2];
 
//-----------------------------------------------------------------------------
// Data Cache
// No-allocate on write
// Line size is 8 words (64 bytes). Total cache size is 32kB
//-----------------------------------------------------------------------------
reg dcaccess;
wire dhit;
388,43 → 513,74
reg [14:0] dcadr;
 
// cache RAM 32Kb
// Xilinx Core Generator Component
Raptor64_dcache_ram u10
(
.clka(clk), // input clka
.ena(1'b1),
.wea(dcaccess ? {8{ack_i}} : wrhit ? sel_o : 8'h00), // input [7 : 0] wea
.addra(dcaccess ? dcadr[14:3] : adr_o[14:3]), // input [11 : 0] addra
.dina(dcaccess ? dat_i : dat_o), // input [63 : 0] dina
 
.clkb(~clk), // input clkb
.addrb(pea[14:3]), // input [11 : 0] addrb
.doutb(cdat) // output [63 : 0] doutb
.wclk(clk),
.wr(1'b1),
.sel(dcaccess ? {8{ack_i}} : wrhit ? sel_o : 8'h00),
.wadr(dcaccess ? dcadr[14:3] : adr_o[14:3]),
.i(dcaccess ? dat_i : dat_o),
.rclk(~clk),
.radr(pea[14:3]),
.o(cdat)
);
 
 
// Xilinx Core Generator Component
// tag RAM 512 b
Raptor64_dcache_tagram u11
(
.clka(clk), // input clka
.ena(dtinit | (dcadr[5:3]==3'b111)), // input ena
.wea(dtinit | (dcaccess & ack_i)), // input [0 : 0] wea
.addra(dcadr[14:6]), // input [8 : 0] addra
.dina({~dtinit,adr_o[63:15]}), // input [49 : 0] dina
.wclk(clk),
.we(dtinit | (dcaccess && ack_i && dcadr[5:3]==3'b111)),
.adr(dcadr[14:6]),
.d({~dtinit,adr_o[63:15]}),
 
.clkb(~clk), // input clkb
.addrb(pea[14:6]), // input [8 : 0] addrb
.doutb(dtgout) // output [49 : 0] doutb
.rclk(~clk),
.ea(pea[14:6]),
.tago(dtgout)
);
 
assign dhit = (dtgout=={1'b1,pea[63:15]});
 
reg [ 7:0] cdata8;
reg [15:0] cdata16;
reg [31:0] cdata32;
reg [63:0] cdata64;
 
always @(pea or cdat)
case(pea[2:0])
3'b000: cdata8 <= cdat[ 7: 0];
3'b001: cdata8 <= cdat[15: 8];
3'b010: cdata8 <= cdat[23:16];
3'b011: cdata8 <= cdat[31:24];
3'b100: cdata8 <= cdat[39:32];
3'b101: cdata8 <= cdat[47:40];
3'b110: cdata8 <= cdat[55:48];
3'b111: cdata8 <= cdat[63:56];
endcase
 
always @(pea or cdat)
case(pea[2:1])
2'b00: cdata16 <= cdat[15: 0];
2'b01: cdata16 <= cdat[31:16];
2'b10: cdata16 <= cdat[47:32];
2'b11: cdata16 <= cdat[63:48];
endcase
 
always @(pea or cdat)
case(pea[2])
1'b0: cdata32 <= cdat[31: 0];
1'b1: cdata32 <= cdat[63:32];
endcase
 
always @(pea or cdat)
cdata64 <= cdat;
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
 
reg [64:0] xData;
wire xisCacheElement = (xData[63:52] != 12'hFFD && xData[63:52]!=12'hFFF) && dcache_on;
// Load word and reserve is never cached.
wire xisCacheElement = (xData[63:52] != 12'hFFD && xData[63:52]!=12'hFFF &&
xOpcode!=`LWR && !(xOpcode==`MEMNDX && xFunc6==`LWRX)) && dcache_on;
reg m1IsCacheElement;
 
 
433,7 → 589,7
wire [63:0] div_q;
wire [63:0] div_r;
wire sqrt_done,mult_done,div_done;
wire isSqrt = xIRvalid && xOpcode==`R && xFunc==`SQRT;
wire isSqrt =xOpcode==`R && xFunc==`SQRT;
 
isqrt #(64) u14
(
446,16 → 602,16
.done(sqrt_done)
);
 
wire isMulu = xIRvalid && xOpcode==`RR && xFunc==`MULU;
wire isMuls = xIRvalid && ((xOpcode==`RR && xFunc==`MULS) || xOpcode==`MULSI);
wire isMuli = xIRvalid && (xOpcode==`MULSI || xOpcode==`MULUI);
wire isMult = xIRvalid && (xOpcode==`MULSI || xOpcode==`MULUI || (xOpcode==`RR && (xFunc==`MULS || xFunc==`MULU)));
wire isDivu = xIRvalid && (xOpcode==`RR && xFunc==`DIVU);
wire isDivs = xIRvalid && ((xOpcode==`RR && xFunc==`DIVS) || xOpcode==`DIVSI);
wire isDivi = xIRvalid && (xOpcode==`DIVSI || xOpcode==`DIVUI);
wire isDiv = xIRvalid && (xOpcode==`DIVSI || xOpcode==`DIVUI || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU)));
wire isModu = xIRvalid && (xOpcode==`RR && xFunc==`MODU);
wire isMods = xIRvalid && (xOpcode==`RR && xFunc==`MODS);
wire isMulu = xOpcode==`RR && xFunc==`MULU;
wire isMuls = ((xOpcode==`RR && xFunc==`MULS) || xOpcode==`MULSI);
wire isMuli = (xOpcode==`MULSI || xOpcode==`MULUI);
wire isMult = (xOpcode==`MULSI || xOpcode==`MULUI || (xOpcode==`RR && (xFunc==`MULS || xFunc==`MULU)));
wire isDivu = (xOpcode==`RR && xFunc==`DIVU);
wire isDivs = ((xOpcode==`RR && xFunc==`DIVS) || xOpcode==`DIVSI);
wire isDivi = (xOpcode==`DIVSI || xOpcode==`DIVUI);
wire isDiv = (xOpcode==`DIVSI || xOpcode==`DIVUI || (xOpcode==`RR && (xFunc==`DIVS || xFunc==`DIVU)));
wire isModu = (xOpcode==`RR && xFunc==`MODU);
wire isMods = (xOpcode==`RR && xFunc==`MODS);
wire isMod = isModu|isMods;
 
Raptor64Mult u18
496,6 → 652,7
wire [63:0] fpLooOut;
wire fpLooDone;
 
 
/*
fpZLUnit #(64) u30
(
530,8 → 687,110
wire f2i_iop,fpmul_iop,fpdiv_iop,fpaddsub_iop,fpcmp_iop;
wire f2i_ovr,fpmul_ovr,fpdiv_ovr,fpaddsub_ovr;
wire fpmul_uf,fpaddsub_uf,fpdiv_uf;
wire [11:0] fcmp_result;
 
`ifdef SIMD
 
Raptor64_fpAdd21 u61
(
.a(a[20:0]),
.b(b[20:0]),
.operation(xFunc6),
.clk(clk),
.result(daddsub_result[20:0])
);
 
Raptor64_fpAdd21 u62
(
.a(a[41:21]),
.b(b[41:21]),
.operation(xFunc6),
.clk(clk),
.result(daddsub_result[41:21])
);
 
Raptor64_fpAdd21 u63
(
.a(a[62:42]),
.b(b[62:42]),
.operation(xFunc6),
.clk(clk),
.result(daddsub_result[62:42])
);
 
Raptor64_fpMul21 u64
(
.a(a[20:0]),
.b(b[20:0]),
.clk(clk),
.result(dmul_result[20:0])
);
 
Raptor64_fpMul21 u65
(
.a(a[41:21]),
.b(b[41:21]),
.clk(clk),
.result(dmul_result[41:21])
);
 
Raptor64_fpMul21 u66
(
.a(a[62:42]),
.b(b[62:42]),
.clk(clk),
.result(dmul_result[62:42])
);
 
Raptor64_fpDiv21 u67
(
.a(a[20:0]),
.b(b[20:0]),
.clk(clk),
.result(ddiv_result[20:0])
);
 
Raptor64_fpDiv21 u68
(
.a(a[41:21]),
.b(b[41:21]),
.clk(clk),
.result(ddiv_result[41:21])
);
 
Raptor64_fpDiv21 u69
(
.a(a[62:42]),
.b(b[62:42]),
.clk(clk),
.result(ddiv_result[62:42])
);
 
Raptor64_fCmp21 u70
(
.a(a[20:0]),
.b(b[20:0]),
.clk(clk),
.result(fcmp_result[3:0])
);
 
Raptor64_fCmp21 u71
(
.a(a[41:21]),
.b(b[41:21]),
.clk(clk),
.result(fcmp_result[7:4])
);
 
Raptor64_fCmp21 u72
(
.a(a[62:42]),
.b(b[62:42]),
.clk(clk),
.result(fcmp_result[11:8])
);
`endif
 
`ifdef FLOATING_POINT
// Xilinx Core Generator Components
 
607,7 → 866,20
FPC_overx <= fp_ovr;
end
if (advanceX) begin
if (xOpcode==`FP && xIRvalid) begin
`ifdef SIMD
if (xOpcode==`SIMD) begin
case(xFunc6)
`SIMD_ADD: fltctr <= 6'd10;
`SIMD_SUB: fltctr <= 6'd10;
`SIMD_MUL: fltctr <= 6'd7;
`SIMD_DIV: fltctr <= 6'd19;
`SIMD_CMP: fltctr <= 6'd2;
default: fltctr <= 6'd1;
endcase
end
else
`endif
if (xOpcode==`FP) begin
if (xFunc6==`FDADD) // FDADD
fltctr <= 6'd12;
else if (xFunc6==`FDSUB) // FDSUB
759,7 → 1031,6
.rst(rst_i),
.clk(clk),
.advanceX(advanceX),
.xIRvalid(xIRvalid),
.xIR(xIR),
.pc(pc),
.xpc(xpc),
815,15 → 1086,15
wire ltu = a < b;
wire ltui = a < imm;
 
always @(xOpcode or xFunc or xFunc5 or a or b or imm or xpc or aeqz or
sqrt_out or cntlzo or cntloo or tick or AXC or
always @(xOpcode or xFunc or xFunc5 or a or b or c or imm or xpc or aeqz or xFunc6 or
sqrt_out or cntlzo or cntloo or tick or AXC or scale or
lt or eq or ltu or mult_out or lti or eqi or ltui or xIR or div_q or div_r or
shfto or masko or bcdmulo or fpLooOut or fpZLOut or m_z or m_w or
`ifdef TLB
PageTableAddr or BadVAddr or ASID or tlbo or
`endif
ASID or EPC or mutex_gate or IPC or TBA or xAXC or nonICacheSeg or rm or
rando or errorAddress
ASID or TBA or xAXC or nonICacheSeg or rm or
rando or errorAddress or insnkey or pchistoric
)
casex(xOpcode)
`MISC:
889,6 → 1160,12
`PageTableAddr: xData1 = {PageTableAddr,13'd0};
`BadVAddr: xData1 = {BadVAddr,13'd0};
`endif
`ifdef SEGMENTATION
`CS: xData1 = {CS[xAXC],16'h0};
`DS: xData1 = {DS[xAXC],16'h0};
`ES: xData1 = {ES[xAXC],16'b0};
`SS: xData1 = {SS[xAXC],16'h0};
`endif
`ASID: xData1 = ASID;
`Tick: xData1 = tick;
`EPC: xData1 = EPC[xAXC];
916,8 → 1193,8
endcase
`RR:
case(xFunc6)
`CMP: xData1 = lt ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
`CMPU: xData1 = ltu ? 64'hFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
`CMP: xData1 = lt ? 64'hFFFFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
`CMPU: xData1 = ltu ? 64'hFFFFFFFFFFFFFFFF : eq ? 64'd0 : 64'd1;
`MIN: xData1 = lt ? a : b;
`MAX: xData1 = lt ? b : a;
`MOVZ: xData1 = b;
934,6 → 1211,64
`MFEP: xData1 = epat[a[7:0]];
default: xData1 = 64'd0;
endcase
`ifdef SIMD
`SIMD:
case(xFunc6)
`SIMD_ADD: xData1 = daddsub_result;
`SIMD_SUB: xData1 = daddsub_result;
`SIMD_MUL: xData1 = dmul_result;
`SIMD_DIV: xData1 = ddiv_result;
`SIMD_CMP: xData1 = {fcmp_result[11:8],17'd0,fcmp_result[7:4],17'd0,fcmp_result[3:0]};
default: xData1 = 64'd0;
endcase
`endif
`ifdef ISIMD
`SIMD:
case(xFunc6)
`SIMD_ADD:
begin
xData1[15: 0] <= a[15: 0] + b[15: 0];
xData1[31:16] <= a[31:16] + b[31:16];
xData1[47:32] <= a[47:32] + b[47:32];
xData1[63:48] <= a[63:48] + b[63:48];
end
`SIMD_SUB:
begin
xData1[15: 0] <= a[15: 0] - b[15: 0];
xData1[31:16] <= a[31:16] - b[31:16];
xData1[47:32] <= a[47:32] - b[47:32];
xData1[63:48] <= a[63:48] - b[63:48];
end
`SIMD_MUL:
begin
xData1[15: 0] <= a[15: 0] * b[15: 0];
xData1[31:16] <= a[31:16] * b[31:16];
xData1[47:32] <= a[47:32] * b[47:32];
xData1[63:48] <= a[63:48] * b[63:48];
end
`SIMD_AND:
begin
xData1[15: 0] <= a[15: 0] & b[15: 0];
xData1[31:16] <= a[31:16] & b[31:16];
xData1[47:32] <= a[47:32] & b[47:32];
xData1[63:48] <= a[63:48] & b[63:48];
end
`SIMD_OR:
begin
xData1[15: 0] <= a[15: 0] | b[15: 0];
xData1[31:16] <= a[31:16] | b[31:16];
xData1[47:32] <= a[47:32] | b[47:32];
xData1[63:48] <= a[63:48] | b[63:48];
end
`SIMD_XOR:
begin
xData1[15: 0] <= a[15: 0] ^ b[15: 0];
xData1[31:16] <= a[31:16] ^ b[31:16];
xData1[47:32] <= a[47:32] ^ b[47:32];
xData1[63:48] <= a[63:48] ^ b[63:48];
end
endcase
`endif
`BTRR:
case(xFunc5)
`LOOP: xData1 = b - 64'd1;
947,27 → 1282,13
`SETLO: xData1 = {{42{xIR[21]}},xIR[21:0]};
`SETMID: xData1 = {{20{xIR[21]}},xIR[21:0],a[21:0]};
`SETHI: xData1 = {xIR[19:0],a[43:0]};
`CMPI: xData1 = lti ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
`CMPUI: xData1 = ltui ? 64'hFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
`CMPI: xData1 = lti ? 64'hFFFFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
`CMPUI: xData1 = ltui ? 64'hFFFFFFFFFFFFFFFF : eqi ? 64'd0 : 64'd1;
`MULSI: xData1 = mult_out[63:0];
`MULUI: xData1 = mult_out[63:0];
`DIVSI: xData1 = div_q;
`DIVUI: xData1 = div_q;
`INB,`INCH,`INH,`INW,`INCU,`INHU,`INBU:
xData1 = a + imm;
`OUTB,`OUTC,`OUTH,`OUTW,`OUTBC:
xData1 = a + imm;
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LEA:
xData1 = a + imm;
`SW,`SH,`SC,`SB:
xData1 = a + imm;
`ifdef ADDRESS_RESERVATION
`LWR: xData1 = a + imm;
`SWC: xData1 = a + imm;
`endif
`ifdef FLOATING_POINT
`LF,`LFD: xData1 = a + imm;
`SF,`SFD: xData1 = a + imm;
`LFP,`LFDP: xData1 = a + imm + xIR[15];
`SFP,`SFDP: xData1 = a + imm + xIR[15];
`endif
976,9 → 1297,9
`MEMNDX:
case(xFunc6)
// `LPX,`LFPX,`LFDPX,`SPX,`SFPX,`SFDPX:
// xData1 = a + (b << scale) + imm + xIR[15];
// xData1 = a + (b << scale) + offset2 + xIR[15];
default:
xData1 = a + (b << scale) + imm;
xData1 = a + (b << scale) + offset2;
endcase
`TRAPcc: xData1 = fnIncPC(xpc);
`TRAPcci: xData1 = fnIncPC(xpc);
1016,17 → 1337,19
overflow u2 (.op(xOpcode==`SUBI), .a(a[63]), .b(imm[63]), .s(xAddsubo[63]), .v(v_ri));
overflow u3 (.op(xOpcode==`RR && xFunc==`SUB), .a(a[63]), .b(b[63]), .s(xAddsubo[63]), .v(v_rr));
 
wire dbz_error = xIRvalid && (((xOpcode==`DIVSI||xOpcode==`DIVUI) && imm==64'd0) || (xOpcode==`RR && (xFunc6==`DIVS || xFunc6==`DIVU) && b==64'd0));
wire ovr_error = xIRvalid && (((xOpcode==`ADDI || xOpcode==`SUBI) && v_ri) || ((xOpcode==`RR && (xFunc6==`SUB || xFunc6==`ADD)) && v_rr));
wire dbz_error = (((xOpcode==`DIVSI||xOpcode==`DIVUI) && imm==64'd0) || (xOpcode==`RR && (xFunc6==`DIVS || xFunc6==`DIVU) && b==64'd0));
wire ovr_error = (((xOpcode==`ADDI || xOpcode==`SUBI) && v_ri) || ((xOpcode==`RR && (xFunc6==`SUB || xFunc6==`ADD)) && v_rr));
// ToDo: add more priv violations
wire priv_violation = xIRvalid && !KernelMode && (xOpcode==`MISC &&
wire priv_violation = !KernelMode && (xOpcode==`MISC &&
(xFunc==`IRET || xFunc==`ERET || xFunc==`CLI || xFunc==`SEI ||
xFunc==`TLBP || xFunc==`TLBR || xFunc==`TLBWR || xFunc==`TLBWI || xFunc==`IEPP
));
// ToDo: detect illegal instructions in the hives (sub-opcodes)
wire illegal_insn = xIRvalid && (
wire illegal_insn = (
xOpcode==7'd19 ||
`ifndef SIMD
xOpcode==7'd20 ||
`endif
xOpcode==7'd28 ||
xOpcode==7'd29 ||
xOpcode==7'd30 ||
1053,6 → 1376,30
// using regs. However the core is trickier to get working that way; decoding
// in multiple stages is simpler.
//-----------------------------------------------------------------------------
//wire dIsFlowCtrl =
// dOpcode==`JAL || dOpcode==`RET ||
// dOpcode==`BTRI || dOpcode==`BTRR || dOpcode==`TRAPcci || dOpcode==`TRAPcc ||
// dOpcode==`BEQI || dOpcode==`BNEI ||
// dOpcode==`BLTI || dOpcode==`BLEI || dOpcode==`BGTI || dOpcode==`BGEI ||
// dOpcode==`BLTUI || dOpcode==`BLEUI || dOpcode==`BGTUI || dOpcode==`BGEUI ||
// (dOpcode==`MISC && (dFunc==`SYSCALL || dFunc==`IRET || dFunc==`ERET))
// ;
//wire xIsFlowCtrl =
// xOpcode==`JAL || xOpcode==`RET ||
// xOpcode==`BTRI || xOpcode==`BTRR || xOpcode==`TRAPcci || xOpcode==`TRAPcc ||
// xOpcode==`BEQI || xOpcode==`BNEI ||
// xOpcode==`BLTI || xOpcode==`BLEI || xOpcode==`BGTI || xOpcode==`BGEI ||
// xOpcode==`BLTUI || xOpcode==`BLEUI || xOpcode==`BGTUI || xOpcode==`BGEUI ||
// (xOpcode==`MISC && (xFunc==`SYSCALL || xFunc==`IRET || xFunc==`ERET))
// ;
//wire m1IsFlowCtrl =
// (m1Opcode==`MISC && m1Func==`SYSCALL)
// ;
//wire m2IsFlowCtrl =
// (m2Opcode==`MISC && m2Func==`SYSCALL)
// ;
//
//
//wire dIsLoad = dIRvalid && (
// dOpcode==`LW || dOpcode==`LH || dOpcode==`LB || dOpcode==`LWR ||
// dOpcode==`LHU || dOpcode==`LBU ||
1096,15 → 1443,15
//-----------------------------------------------------------------------------
// Pipeline advance and stall logic
//-----------------------------------------------------------------------------
wire xIsSqrt = xIRvalid && xOpcode==`R && xFunc6==`SQRT;
wire xIsMult = xIRvalid && ((xOpcode==`RR && (xFunc6==`MULU || xFunc6==`MULS)) || xOpcode==`MULSI || xOpcode==`MULUI);
wire xIsDiv = xIRvalid && ((xOpcode==`RR && (xFunc6==`DIVU || xFunc6==`DIVS || xFunc6==`MODU || xFunc6==`MODS)) || xOpcode==`DIVSI || xOpcode==`DIVUI);
wire xIsCnt = xIRvalid && (xOpcode==`R && (xFunc6==`CTLZ || xFunc6==`CTLO || xFunc6==`CTPOP));
wire xIsSqrt = xOpcode==`R && xFunc6==`SQRT;
wire xIsMult = ((xOpcode==`RR && (xFunc6==`MULU || xFunc6==`MULS)) || xOpcode==`MULSI || xOpcode==`MULUI);
wire xIsDiv = ((xOpcode==`RR && (xFunc6==`DIVU || xFunc6==`DIVS || xFunc6==`MODU || xFunc6==`MODS)) || xOpcode==`DIVSI || xOpcode==`DIVUI);
wire xIsCnt = (xOpcode==`R && (xFunc6==`CTLZ || xFunc6==`CTLO || xFunc6==`CTPOP));
reg m1IsCnt,m2IsCnt;
reg m2IsCacheElement;
 
// Have to set the xIsLoad/xIsStore flag to false when xIR is nopped out
wire xIsLoad = xIRvalid && (
wire xIsLoad = (
xOpcode==`LW || xOpcode==`LH || xOpcode==`LB || xOpcode==`LWR ||
xOpcode==`LHU || xOpcode==`LBU ||
xOpcode==`LC || xOpcode==`LCU || xOpcode==`LM ||
1120,7 → 1467,7
(xOpcode==`MISC && (xFunc==`SYSCALL))
)
;
wire xIsStore = xIRvalid && (
wire xIsStore = (
xOpcode==`SW || xOpcode==`SH || xOpcode==`SB || xOpcode==`SC || xOpcode==`SWC || xOpcode==`SM ||
xOpcode==`SF || xOpcode==`SFD || xOpcode==`SP || xOpcode==`SFP || xOpcode==`SFDP ||
xOpcode==`SSH || xOpcode==`SSW || xOpcode==`STBC ||
1131,8 → 1478,8
))
)
;
wire xIsSWC = xOpcode==`SWC && xIRvalid;
wire xIsIn = xIRvalid && (
wire xIsSWC = xOpcode==`SWC;
wire xIsIn = (
xOpcode==`INW || xOpcode==`INH || xOpcode==`INCH || xOpcode==`INB ||
xOpcode==`INHU || xOpcode==`INCU || xOpcode==`INBU ||
(xOpcode==`MEMNDX && (
1141,17 → 1488,12
))
)
;
wire xIsOut = xIRvalid && (
wire xIsOut = (
xOpcode==`OUTW || xOpcode==`OUTH || xOpcode==`OUTC || xOpcode==`OUTB ||
(xOpcode==`MEMNDX && (
xFunc6==`OUTWX || xFunc6==`OUTHX || xFunc6==`OUTCX || xFunc6==`OUTBX
)))
;
reg m1IsLoad,m1IsStore;
reg m2IsLoad,m2IsStore;
reg wIsStore;
reg m1IsOut,m1IsIn;
 
//wire mIsSWC = mOpcode==`SWC;
//reg m1IsIn;
 
1158,9 → 1500,11
wire m2IsInW = m2Opcode==`INW;
wire xIsIO = xIsIn || xIsOut;
wire m1IsIO = m1IsIn || m1IsOut;
wire xIsSetmid = xOpcode==`SETMID;
 
wire xIsFPLoo = xIRvalid && xOpcode==`FPLOO;
wire xIsFP = xIRvalid && xOpcode==`FP;
wire xIsFPLoo = xOpcode==`FPLOO;
wire xIsFP = xOpcode==`FP;
wire xIsSIMD = xOpcode==`SIMD;
wire xneedBus = xIsIO;
//wire m1needBus = (m1IsLoad & !m1IsCacheElement) || m1IsStore || m1IsIO;
wire m1needBus = m1IsLoad || m1IsStore || m1IsIO;
1171,22 → 1515,37
wire m2Rtz = m2Rt[4:0]==5'd0;
 
//wire StallI = dIsLSPair & ~dIR[15];
wire intPending = nmi_edge || (irq_i & ~im); // || ITLBMiss
 
// Check if there are results being forwarded, to allow the pipeline to empty if result
// forwarding isn't needed.
wire tForwardingActive = tRt==dRa || tRt==dRb || tRt==dRc;
wire wForwardingActive = wRt==dRa || wRt==dRb || wRt==dRc;
wire m2ForwardingActive = m2Rt==dRa || m2Rt==dRb || m2Rt==dRc;
wire m1ForwardingActive = m1Rt==dRa || m1Rt==dRb || m1Rt==dRc;
wire xForwardingActive = xRt==dRa || xRt==dRb || xRt==dRc;
wire memCycleActive = ((iocyc_o & !(ack_i|err_i)) || (cyc_o & !(ack_i|err_i)));
wire StallI = 1'b0;
 
// Stall on SWC allows rsf flag to be loaded for the next instruction
// Could check for dRa,dRb,dRc==0, for non-stalling
wire StallR = ((( xIsLoad||xIsIn||xIsCnt) && (( xRt==dRa)||( xRt==dRb)||( xRt==dRc)) && !xRtz) || xIsSWC) ||
(((m1IsLoad||m1IsIn||m1IsCnt) && ((m1Rt==dRa)||(m1Rt==dRb)||(m1Rt==dRc)) && !m1Rtz)) ||
(((m2IsLoad||m2IsCnt) && ((m2Rt==dRa)||(m2Rt==dRb)||(m2Rt==dRc)) && !m2Rtz))
wire StallR = ((( xIsLoad||xIsIn||xIsCnt) && (xForwardingActive) && !xRtz) || xIsSWC) ||
(((m1IsLoad||m1IsIn||m1IsCnt) && (m1ForwardingActive) && !m1Rtz)) ||
(((m2IsLoad||m2IsCnt) && (m2ForwardingActive) && !m2Rtz))
;
wire StallX = (xneedBus||xIsLoad||xIsStore) & (m1needBus|m2needBus|icaccess|dcaccess);
wire StallM1 = (m1needBus & (m2needBus|icaccess|dcaccess)) ||
( m1IsLoad & m1IsCacheElement & (m2IsStore|wIsStore)) // wait for a preceding store to complete
wire StallX = ((xneedBus||xIsLoad||xIsStore) & (m1needBus|m2needBus|icaccess));
wire StallM1 = (m1needBus & (m2needBus|icaccess)) ||
( m1IsLoad & m1IsCacheElement & (m2IsStore|wIsStore)) || // wait for a preceding store to complete
memCycleActive
;
wire StallM2 = m2needBus & (icaccess|dcaccess);
// We need to stall the pipeline stages *after* the memory load so that result forwarding
// isn't lost during a data cache load.
wire StallM2 = (m2needBus & icaccess) || (m2ForwardingActive && (((m1IsLoad & m1IsCacheElement & !dhit) || memCycleActive)));
wire StallW = (wForwardingActive && ((m1IsLoad & m1IsCacheElement & !dhit) || memCycleActive));
wire StallT = (tForwardingActive && ((m1IsLoad & m1IsCacheElement & !dhit) || memCycleActive)) || dcaccess;
 
assign advanceT = !resetA;
assign advanceW = advanceT;
assign advanceT = (state==RUN) && !StallT;
assign advanceW = advanceT & !StallW;
assign advanceM2 = advanceW && (cyc_o ? (ack_i|err_i) : 1'b1) && !StallM2;
assign advanceM1 = advanceM2 &
(iocyc_o ? (ack_i|err_i) : 1'b1) &
1197,8 → 1556,13
xIsSqrt ? sqrt_done :
xIsMult ? mult_done :
xIsDiv ? div_done :
`ifdef FLOATING_POINT
xIsFPLoo ? fpLooDone :
xIsFP ? fltdone :
`endif
`ifdef SIMD
xIsSIMD ? fltdone :
`endif
1'b1) &
!StallX;
assign advanceR = advanceX & !StallR;
1208,14 → 1572,14
// Cache loading control
//-----------------------------------------------------------------------------
wire pipelineEmpty =
(dOpcode==`NOPI || !dIRvalid) && // and the pipeline is flushed
(xOpcode==`NOPI || !xIRvalid) &&
(m1Opcode==`NOPI || !m1IRvalid) &&
(m2Opcode==`NOPI || !m2IRvalid)
(dOpcode==`NOPI) && // and the pipeline is flushed
(xOpcode==`NOPI) &&
(m1Opcode==`NOPI) &&
(m2Opcode==`NOPI)
;
wire triggerDCacheLoad = (m1IsLoad & m1IsCacheElement & !dhit) && // there is a miss
!(icaccess | dcaccess) && // caches are not active
(m2Opcode==`NOPI || !m2IRvalid); // 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
!(icaccess | dcaccess) && // caches are not active
1241,61 → 1605,124
//-----------------------------------------------------------------------------
 
wire [63:0] nxt_a, nxt_b, nxt_c;
wire [8:0] nxt_Ra,nxt_Rb,nxt_Rc;
 
Raptor64_regfile u5
Raptor64_SetOperandRegs u7
(
.rst(rst_i),
.clk(clk),
.advanceI(advanceI),
.advanceR(advanceR),
.advanceW(advanceW),
.wIRvalid(wIRvalid),
.advanceX(advanceX),
.b(b),
.AXC(AXC),
.xAXC(xAXC),
.insn(insn),
.xIR(xIR),
.dRa(dRa),
.dRb(dRb),
.dRc(dRc),
.nxt_Ra(nxt_Ra),
.nxt_Rb(nxt_Rb),
.nxt_Rc(nxt_Rc)
);
 
syncRam512x64_1rw3r u5
(
.wrst(1'b0),
.wclk(clk),
.wce(1'b1), // advanceW
.we(1'b1),
.wadr(wRt),
.i(wData),
.wo(),
.rrsta(1'b0),
.rclka(~clk),
.rcea(advanceR),
.radra(dRa),
.roa(rfoa),
 
.rrstb(1'b0),
.rclkb(~clk),
.rceb(advanceR),
.radrb(dRb),
.rob(rfob),
 
.rrstc(1'b0),
.rclkc(~clk),
.rcec(advanceR),
.radrc(dRc),
.roc(rfoc)
);
 
Raptor64_BypassMux u8
(
.dpc(dpc),
.dRn(dRa),
.xRt(xRt),
.m1Rt(m1Rt),
.m2Rt(m2Rt),
.wRt(wRt),
.tRt(tRt),
.xData(xData[63:0]),
.rfo(rfoa),
.xData(xData),
.m1Data(m1Data),
.m2Data(m2Data),
.wData(wData),
.tData(tData),
.nxt_a(nxt_a),
.nxt_b(nxt_b),
.nxt_c(nxt_c)
.nxt(nxt_a)
);
 
Raptor64_SetOperandRegs u7
Raptor64_BypassMux u25
(
.rst(rst_i),
.clk(clk),
.advanceI(advanceI),
.advanceR(advanceR),
.advanceX(advanceX),
.b(b),
.AXC(AXC),
.xAXC(xAXC),
.insn(insn),
.xIR(xIR),
.dRa(dRa),
.dRb(dRb),
.dRc(dRc)
.dpc(dpc),
.dRn(dRb),
.xRt(xRt),
.m1Rt(m1Rt),
.m2Rt(m2Rt),
.wRt(wRt),
.tRt(tRt),
.rfo(rfob),
.xData(xData),
.m1Data(m1Data),
.m2Data(m2Data),
.wData(wData),
.tData(tData),
.nxt(nxt_b)
);
 
Raptor64_SetTargetRegister u8
Raptor64_BypassMux u24
(
.rst(rst_i),
.clk(clk),
.advanceR(advanceR),
.advanceX(advanceX),
.dIRvalid(dIRvalid),
.dIR(dIR),
.dAXC(dAXC),
.xRt(xRt)
.dpc(dpc),
.dRn(dRc),
.xRt(xRt),
.m1Rt(m1Rt),
.m2Rt(m2Rt),
.wRt(wRt),
.tRt(tRt),
.rfo(rfoc),
.xData(xData),
.m1Data(m1Data),
.m2Data(m2Data),
.wData(wData),
.tData(tData),
.nxt(nxt_c)
);
 
// We need to zero out xRt because it'll match in the operand bypass multiplexers if it isn't zeroed out.
//Raptor64_SetTargetRegister u8
//(
// .rst(rst_i),
// .clk(clk),
// .advanceR(advanceR),
// .advanceX(advanceX),
// .dIRvalid(dIRvalid),
// .dIR(dIR),
// .dAXC(dAXC),
// .xRt(xRt)
//);
 
reg [5:0] pchi;
vtdl #(64,64) u23
(
1306,6 → 1733,12
.q(pchistoric)
);
 
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 isxNonHWI = (xIR[15:7]!=`EX_NMI &&
!(xIR[15:7]>=`EX_IRQ && xIR[15:7] < `EX_IRQ+32) &&
xIR[15:7]!=`EX_TLBI || xIR[15:7]!=`EX_TLBD);
 
always @(posedge clk)
if (rst_i) begin
bte_o <= 2'b00;
1324,13 → 1757,11
nonICacheSeg <= 32'hFFFF_FFFD;
TBA <= 64'd0;
pc <= `RESET_VECTOR;
m1Opcode <= `NOPI;
m2Opcode <= `NOPI;
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
m1IR <= `NOP_INSN;
m2IR <= `NOP_INSN;
wIR <= `NOP_INSN;
wOpcode <= `NOPI;
dIR <= `NOP_INSN;
m1IsLoad <= 1'b0;
m1IsStore <= 1'b0;
m2IsLoad <= 1'b0;
1338,7 → 1769,6
wIsStore <= 1'b0;
m1IsOut <= 1'b0;
m1IsIn <= 1'b0;
xRtZero <= 1'b0;
tRt <= 9'd0;
wRt <= 9'd0;
m1Rt <= 9'd0;
1349,7 → 1779,6
m2Data <= 64'd0;
icaccess <= 1'b0;
dcaccess <= 1'b0;
prev_ihit <= 1'b0;
wFip <= 1'b0;
m2Fip <= 1'b0;
m1Fip <= 1'b0;
1356,12 → 1785,10
xFip <= 1'b0;
dFip <= 1'b0;
dirqf <= 1'b0;
ipcv <= 1'b1;
dpcv <= 1'b0;
xpcv <= 1'b0;
m1pcv <= 1'b0;
m2pcv <= 1'b0;
wpcv <= 1'b0;
dNmi <= 1'b0;
xNmi <= 1'b0;
m1Nmi <= 1'b0;
m2Nmi <= 1'b0;
tick <= 64'd0;
cstate <= IDLE;
dAXC <= 4'd0;
1376,7 → 1803,6
m2extype <= 9'h00;
wextype <= 9'h00;
textype <= 9'h00;
xIR <= `NOP_INSN;
xpc <= 64'd0;
a <= 64'd0;
b <= 64'd0;
1384,7 → 1810,6
clk_en <= 1'b1;
StatusEXL <= 16'hFFFF;
StatusHWI <= 1'b0;
resetA <= 1'b1;
mutex_gate <= 64'h0;
dcache_on <= 1'b0;
ICacheOn <= 1'b0;
1392,7 → 1817,6
m1IsCacheElement <= 1'b0;
dtinit <= 1'b1;
ras_sp <= 6'd63;
im <= 1'b1;
im1 <= 1'b1;
// These must be non-zero in order to produce random numbers
// We set them here in case the user doesn't bother to set them.
1401,11 → 1825,7
insnkey <= 32'd0;
LoadNOPs <= 1'b0;
eptr <= 8'h00;
dIRvalid <= 1'b1;
xIRvalid <= 1'b1;
m1IRvalid <= 1'b0;
m2IRvalid <= 1'b0;
wIRvalid <= 1'b0;
ie_fuse <= 8'h00;
end
else begin
 
1418,11 → 1838,9
RESET:
begin
pc <= `RESET_VECTOR;
ipcv <= 1'b1;
adr_o[14:6] <= adr_o[14:6]+9'd1;
if (adr_o[14:6]==9'h1FF) begin
dtinit <= 1'b0;
resetA <= 1'b0;
state <= RUN;
end
epat[a[7:0]] <= b[3:0]; /// b=0, to make this line the same as MTEP
1431,6 → 1849,8
RUN:
begin
 
ie_fuse <= {ie_fuse[6:0],ie_fuse[0]}; // shift counter
 
tick <= tick + 64'd1;
 
prev_nmi <= nmi_i;
1462,51 → 1882,47
dextype <= `EX_NON;
// record instruction and associated pc value
dIR <= insn;
dIRvalid <= 1'b1;
dpc <= pc;
dpcv <= ipcv;
dIm <= im;
dStatusHWI <= StatusHWI;
// Interrupt: stomp on the incoming instruction and replace it with
// a system call.
if (nmi_edge & !StatusHWI) begin
$display("*****************");
$display("NMI edge detected");
$display("*****************");
ie_fuse <= 8'h00;
StatusHWI <= 1'b1;
nmi_edge <= 1'b0;
dextype <= `EX_NMI;
dIRvalid <= 1'b0;
LoadNOPs <= 1'b1;
dNmi <= 1'b1;
dIR <= {`MISC,9'd0,`EX_NMI,`SYSCALL};
end
else if (irq_i & !im & !StatusHWI) begin
$display("*****************");
$display("IRQ detected");
$display("*****************");
bu_im <= 1'b0;
im <= 1'b1;
ie_fuse <= 8'h00;
StatusHWI <= 1'b1;
dextype <= `EX_IRQ;
dIRvalid <= 1'b0;
LoadNOPs <= 1'b1;
dIR <= {`MISC,9'd0,`EX_IRQ|irq_no,`SYSCALL};
dextype <= `EX_IRQ|irq_no;
end
`ifdef TLB
// A TLB miss is treated like a hardware interrupt.
else if (ITLBMiss) begin
$display("TLB miss on instruction fetch.");
dextype <= `EX_TLBI;
dIR <= {`MISC,9'd0,`EX_TLBI,`SYSCALL};
BadVAddr <= pc[63:13];
end
`endif
// Are we filling the pipeline with NOP's as a result of a previous
// hardware interrupt ?
else if (|dFip|LoadNOPs)
dIRvalid <= 1'b0;
`ifdef TLB
else if (ITLBMiss)
dIRvalid <= 1'b0;
`endif
else if (|dFip|LoadNOPs) begin
dIR <= `NOP_INSN;
end
else begin
`include "insn_dumpsc.v"
end
`ifdef TLB
if (ITLBMiss) begin
$display("TLB miss on instruction fetch.");
StatusEXL <= 1'b1;
BadVAddr <= pc[63:13];
dextype <= `EX_TLBI;
EPC <= pc;
end
else
`endif
begin
dbranch_taken <= 1'b0;
pc <= fnIncPC(pc);
1520,18 → 1936,15
ras[ras_sp] <= fnIncPC(pc);
ras_sp <= ras_sp - 6'd1;
pc <= jmp_tgt;
ipcv <= 1'b1;
end
`RET:
begin
pc <= ras[ras_sp + 6'd1];
ras_sp <= ras_sp + 6'd1;
ipcv <= 1'b1;
end
`JMP:
begin
pc <= jmp_tgt;
ipcv <= 1'b1;
end
`BTRR:
case(insn[4:0])
1540,7 → 1953,6
// $display("Taking predicted branch: %h",{pc[63:4] + {{42{insn[24]}},insn[24:7]},insn[6:5],2'b00});
dbranch_taken <= 1'b1;
pc <= pc + {{52{insn[14]}},insn[14:5],2'b00};
ipcv <= 1'b1;
end
default: ;
endcase
1558,7 → 1970,6
if (predict_taken) begin
dbranch_taken <= 1'b1;
pc <= btb[pc[7:2]];
ipcv <= 1'b1;
end
`endif
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
1566,7 → 1977,6
if (predict_taken) begin
dbranch_taken <= 1'b1;
pc <= pc + {{50{insn[19]}},insn[19:8],2'b00};
ipcv <= 1'b1;
end
end
default: ;
1576,13 → 1986,10
// Stage tail
// Pipeline annul for when a bubble in the pipeline occurs.
else if (advanceR) begin
dbranch_taken <= 1'b0;
dextype <= `EX_NON;
dIRvalid <= 1'b0;
dpcv <= 1'b0;
dextype <= #1 `EX_NON;
dIR <= #1 `NOP_INSN;
end
 
 
//-----------------------------------------------------------------------------
// RFETCH:
// Register fetch stage
1594,16 → 2001,16
//-----------------------------------------------------------------------------
//
if (advanceR) begin
xIm <= dIm;
xNmi <= dNmi;
xStatusHWI <= dStatusHWI;
xAXC <= dAXC;
xFip <= dFip;
xextype <= dextype;
xpc <= dpc;
xpcv <= dpcv;
xbranch_taken <= dbranch_taken;
xRtZero <= 1'b0;
xIRvalid <= dIRvalid;
if (dOpcode==`R && dFunc==`MYST && dIRvalid)
xIR <= nxt_c;
if (dOpcode==`R && dFunc==`MYST)
xIR <= nxt_c[31:0];
else
xIR <= dIR;
a <= nxt_a;
1613,14 → 2020,62
c <= nxt_c;
 
case(dOpcode)
`BTRI: imm <= {{53{dIR[10]}},dIR[10:0]};
`BTRI:
imm <= {{53{dIR[7]}},dIR[10:0]};
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
imm <= {{56{dIR[7]}},dIR[7:0]};
`RET: imm <= {49'h00000000,dIR[14:3],3'b000};
`MEMNDX: imm <= dIR[7:6];
default: imm <= {{49{dIR[14]}},dIR[14:0]};
`MEMNDX:
imm <= dIR[7:6];
default:
imm <= {{49{dIR[14]}},dIR[14:0]};
endcase
scale <= dIR[9:8];
 
casex(dOpcode)
`MISC:
case(dFunc)
`SYSCALL: xRt <= 9'd0;
default: xRt <= 9'd0;
endcase
`R:
case(dFunc)
`MTSPR,`CMG,`CMGI,`EXEC:
xRt <= 9'd0;
default: xRt <= {dAXC,dIR[19:15]};
endcase
`MYST,`MUX: xRt <= {dAXC,dIR[ 9: 5]};
`SETLO: xRt <= {dAXC,dIR[26:22]};
`SETMID: xRt <= {dAXC,dIR[26:22]};
`SETHI: xRt <= {dAXC,dIR[26:22]};
`RR,`FP: xRt <= {dAXC,dIR[14:10]};
`BTRI: xRt <= 9'd0;
`BTRR:
case(dIR[4:0])
`LOOP: xRt <= {dAXC,dIR[19:15]};
default: xRt <= 9'd0;
endcase
`TRAPcc: xRt <= 9'd0;
`TRAPcci: xRt <= 9'd0;
`JMP: xRt <= 9'd00;
`CALL: xRt <= {dAXC,5'd31};
`RET: xRt <= {dAXC,5'd30};
`MEMNDX:
case(dFunc[5:0])
`LSHX,`LSWX,
`SWX,`SHX,`SCX,`SBX,`SFX,`SFDX,`SPX,`SFPX,`SFDPX,`SSHX,`SSWX,
`OUTWX,`OUTHX,`OUTCX,`OUTBX:
xRt <= 9'd0;
default: xRt <= {dAXC,dIR[14:10]};
endcase
`LSH,`LSW,
`SW,`SH,`SC,`SB,`SF,`SFD,`SSH,`SSW,`SP,`SFP,`SFDP, // but not SWC!
`OUTW,`OUTH,`OUTC,`OUTB:
xRt <= 9'd0;
`NOPI: xRt <= 9'd0;
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
xRt <= 9'd0;
default: xRt <= {dAXC,dIR[19:15]};
endcase
 
// if (dIsLSPair & ~dIR[15])
// dIR <= dIR|32'h8000;
end
1627,11 → 2082,9
// Stage tail
// Pipeline annul for when a bubble in the pipeline occurs.
else if (advanceX) begin
xRtZero <= #1 1'b1;
xRt <= #1 9'd0;
xextype <= #1 `EX_NON;
xbranch_taken <= #1 1'b0;
xIRvalid <= #1 1'b0;
xpcv <= #1 1'b0;
xIR <= #1 `NOP_INSN;
xFip <= #1 1'b0;
end
 
1643,24 → 2096,23
// - m1???? signals to M1 stage
//---------------------------------------------------------
if (advanceX) begin
m1StatusHWI <= xStatusHWI;
m1Im <= xIm;
m1Nmi <= xNmi;
m1extype <= xextype;
m1Fip <= xFip;
m1Func <= xFunc;
m1pcv <= xpcv;
m1pc <= xpc;
m1IR <= xIR;
m1IsCnt <= xIsCnt;
m1Opcode <= xOpcode;
m1IsLoad <= xIsLoad & xIRvalid;
m1IsStore <= xIsStore & xIRvalid;
m1IsOut <= xIsOut & xIRvalid;
m1IsIn <= xIsIn & xIRvalid;
m1Rt <= xRtZero ? 9'd0 : xRt;
m1IsLoad <= xIsLoad;
m1IsStore <= xIsStore;
m1IsOut <= xIsOut;
m1IsIn <= xIsIn;
m1Rt <= xRt;
m1Data <= xData;
m1IsCacheElement <= xisCacheElement;
m1IRvalid <= xIRvalid;
m1AXC <= xAXC;
if (xOpcode==`RR && xIRvalid) begin
if (xOpcode==`RR) begin
if (xFunc6==`MOVZ && !aeqz) begin
m1Rt <= 9'd0;
m1Data <= 64'd0;
1679,12 → 2131,12
end
end
 
if (xIRvalid) begin
begin
case(xOpcode)
`MISC:
case(xFunc)
`SEI: im <= 1'b1;
`CLI: im <= 1'b0;
`SEI: begin ie_fuse <= 8'h00; end
`CLI: begin ie_fuse[0] <= 1'b1; end
`WAIT: m1clkoff <= 1'b1;
`ICACHE_ON: ICacheOn <= 1'b1;
`ICACHE_OFF: ICacheOn <= 1'b0;
1691,12 → 2143,17
`DCACHE_ON: dcache_on <= 1'b1;
`DCACHE_OFF: dcache_on <= 1'b0;
`FIP: begin
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b0;
// In case we stomped on am interrupt, we have to re-enable
// interrupts which were disable in the I-Stage. We go backwards
// in time and set the interrupt status to what it used to be
// when this instruction is executed.
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
dFip <= 1'b1;
xFip <= 1'b1;
m1Fip <= 1'b1;
1703,12 → 2160,13
end
`IEPP: begin
eptr <= eptr + 8'd1;
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b0;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
dFip <= 1'b1;
xFip <= 1'b1;
m1Fip <= 1'b1;
1726,25 → 2184,25
`IRET:
if (StatusHWI) begin
StatusHWI <= 1'b0;
im <= 1'b0;
ie_fuse[0] <= 1'b1;
pc <= IPC[xAXC]; //a;
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
`ERET:
if (StatusEXL[xAXC]) begin
StatusEXL[xAXC] <= 1'b0;
pc <= EPC[xAXC];
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
// Note: we can't mask off the interrupts in the I-stage because this
// instruction might not be valid. Eg. a branch could occur causing
1758,25 → 2216,28
// end of the real IRQ routine would re-enable interrupts too soon.
`SYSCALL:
begin
if ((xIR[15:7]==`EX_NMI || xIR[15:7]==`EX_IRQ) && // Is this a IRQ SYSCALL ?
((dextype==`EX_NMI || dextype==`EX_IRQ) || // Is there an interrupt in the pipeline ?
(nmi_edge & !StatusHWI) || (irq_i & ~im & !StatusHWI))) begin // OR about to happen
m1Opcode <= `NOPI; // Then turn this into a NOP
m1IRvalid <= 1'b0;
if (isxIRQ && // Is this a software IRQ SYSCALL ?
(isPipeIRQ || intPending)) begin // Is there an interrupt in the pipeline ? OR about to happen
m1IR <= `NOP_INSN; // Then turn this into a NOP
m1Rt <= 9'd0;
end
else begin
if (xIR[15:7]!=`EX_NMI && xIR[15:7]!=`EX_IRQ)
if (isxNonHWI) begin
StatusEXL[xAXC] <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
end
else begin
StatusHWI <= 1'b1;
im <= 1'b1;
ie_fuse <= 8'h00;
if (xNmi)
nmi_edge <= 1'b0;
end
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b0;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
ea <= {TBA[63:12],xIR[15:7],3'b000};
LoadNOPs <= 1'b1;
$display("EX SYSCALL thru %h",{TBA[63:12],xIR[15:7],3'b000});
1793,11 → 2254,13
begin
pc <= fnIncPC(xpc);
dIR <= b;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
`MTSPR:
begin
1816,7 → 2279,7
`SRAND2: begin
m_w <= a;
end
`INSNKEY: insnkey <= a[41:0];
`INSNKEY: insnkey <= a[31:0];
`PCHI: pchi <= a[5:0];
default: ;
endcase
1842,22 → 2305,24
if (dpc[63:2] != a[63:2] + imm[63:2]) begin
pc[63:2] <= a[63:2] + imm[63:2];
btb[xpc[7:2]] <= {a[63:2] + imm[63:2],2'b00};
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtzero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
`else
begin
pc[63:2] <= a[63:2] + imm[63:2];
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
`endif
// Check the pc of the instruction after the RET instruction (the dpc), to
1867,12 → 2332,13
`RET:
if (dpc[63:2]!=b[63:2]) begin
pc[63:2] <= b[63:2];
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
`BTRR:
case(xFunc5)
1881,22 → 2347,24
if (!takb & xbranch_taken) begin
$display("Taking mispredicted branch %h",fnIncPC(xpc));
pc <= fnIncPC(xpc);
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
else if (takb & !xbranch_taken) begin
$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]};
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
// BEQ r1,r2,r10
`BEQR,`BNER,`BLTR,`BLER,`BGTR,`BGER,`BLTUR,`BLEUR,`BGTUR,`BGEUR://,`BANDR,`BORR,`BNRR:
1906,12 → 2374,13
`ifdef BTB
btb[xpc[7:2]] <= c;
`endif
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
default: ;
endcase
1924,33 → 2393,36
pc[63:2] <= b[63:2];
pc[1:0] <= 2'b00;
btb[xpc[7:2]] <= b;
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtzero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
end
else if (xbranch_taken) begin // took the branch, and weren't supposed to
pc <= fnIncPC(xpc);
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtzero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
`else
if (takb) begin
pc[63:2] <= b[63:2];
pc[1:0] <= 2'b00;
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
`endif
// BEQI r1,#3,label
1958,12 → 2430,13
if (takb) begin
if (!xbranch_taken) begin
pc[63:2] <= xpc[63:2] + {{50{xIR[19]}},xIR[19:8]};
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
end
else begin
1970,12 → 2443,13
if (xbranch_taken) begin
$display("Taking mispredicted branch %h",fnIncPC(xpc));
pc <= fnIncPC(xpc);
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b1;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
end
end
`TRAPcc,`TRAPcci:
1982,64 → 2456,30
if (takb) begin
StatusEXL[xAXC] <= 1'b1;
xextype <= `EX_TRAP;
dIRvalid <= 1'b0;
xIRvalid <= 1'b0;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b0;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= 9'd0;
LoadNOPs <= 1'b1;
end
 
`INW:
`INW,`INH,`INHU,`INCH,`INCU,`INB,`INBU:
begin
iocyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= 8'hFF;
adr_o <= xData1;
sel_o <= fnSelect(xOpcode,xData[2:0]);
adr_o <= xData;
end
`INH,`INHU:
begin
iocyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= xData1[2] ? 8'b11110000 : 8'b00001111;
adr_o <= xData1;
end
`INCH,`INCU:
begin
iocyc_o <= 1'b1;
stb_o <= 1'b1;
case(xData1[2:1])
2'b00: sel_o <= 8'b00000011;
2'b01: sel_o <= 8'b00001100;
2'b10: sel_o <= 8'b00110000;
2'b11: sel_o <= 8'b11000000;
endcase
adr_o <= xData1;
end
`INB,`INBU:
begin
iocyc_o <= 1'b1;
stb_o <= 1'b1;
case(xData1[2:0])
3'b000: sel_o <= 8'b00000001;
3'b001: sel_o <= 8'b00000010;
3'b010: sel_o <= 8'b00000100;
3'b011: sel_o <= 8'b00001000;
3'b100: sel_o <= 8'b00010000;
3'b101: sel_o <= 8'b00100000;
3'b110: sel_o <= 8'b01000000;
3'b111: sel_o <= 8'b10000000;
endcase
adr_o <= xData1;
end
`OUTW:
begin
iocyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
sel_o <= 8'hFF;
adr_o <= xData1;
sel_o <= fnSelect(xOpcode,xData[2:0]);
adr_o <= xData;
dat_o <= b;
end
`OUTH:
2047,8 → 2487,8
iocyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
sel_o <= xData1[2] ? 8'b11110000 : 8'b00001111;
adr_o <= xData1;
sel_o <= fnSelect(xOpcode,xData[2:0]);
adr_o <= xData;
dat_o <= {2{b[31:0]}};
end
`OUTC:
2056,13 → 2496,8
iocyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
case(xData1[2:1])
2'b00: sel_o <= 8'b00000011;
2'b01: sel_o <= 8'b00001100;
2'b10: sel_o <= 8'b00110000;
2'b11: sel_o <= 8'b11000000;
endcase
adr_o <= xData1;
sel_o <= fnSelect(xOpcode,xData[2:0]);
adr_o <= xData;
dat_o <= {4{b[15:0]}};
end
`OUTB:
2070,17 → 2505,8
iocyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
case(xData1[2:0])
3'b000: sel_o <= 8'b00000001;
3'b001: sel_o <= 8'b00000010;
3'b010: sel_o <= 8'b00000100;
3'b011: sel_o <= 8'b00001000;
3'b100: sel_o <= 8'b00010000;
3'b101: sel_o <= 8'b00100000;
3'b110: sel_o <= 8'b01000000;
3'b111: sel_o <= 8'b10000000;
endcase
adr_o <= xData1;
sel_o <= fnSelect(xOpcode,xData[2:0]);
adr_o <= xData;
dat_o <= {8{b[7:0]}};
end
// `OUTBC:
2102,15 → 2528,15
// dat_o <= {8{xIR[19:12]}};
// end
`LEA: begin
$display("LEA %h", xData1);
m1Data <= xData1;
$display("LEA %h", xData);
m1Data <= xData;
end
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWR,`LF,`LFD,`LM,`LSH,`LSW,`LP,`LFP,`LFDP,
`SW,`SH,`SC,`SB,`SWC,`SF,`SFD,`SM,`SSW,`SP,`SFP,`SFDP:
begin
m1Data <= b;
ea <= xData1;
$display("EX MEMOP %h", xData1);
ea <= xData;
$display("EX MEMOP %h", xData);
end
// `STBC:
// begin
2127,10 → 2553,10
`CACHE:
begin
m1Data <= b;
ea <= xData1;
ea <= xData;
case(xIR[19:15])
`INVIL: ; // handled in M1 stage
`INVIALL: tvalid <= 128'd0;
`INVIALL: tvalid <= 256'd0;
`ICACHEON: ICacheOn <= 1'b1;
`ICACHEOFF: ICacheOn <= 1'b0;
`DCACHEON: dcache_on <= 1'b1;
2140,12 → 2566,12
end
`MEMNDX:
begin
m1Opcode <= 7'd32+xFunc6;
m1IR[31:25] <= 7'd32+xFunc6;
case(xFunc6)
`LEAX:
begin
$display("LEAX %h", xData1);
m1Data <= xData1;
$display("LEAX %h", xData);
m1Data <= xData;
end
`INWX:
begin
2152,32 → 2578,32
iocyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= 8'hFF;
adr_o <= xData1;
adr_o <= xData;
end
`INHX,`INHUX:
begin
iocyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= xData1[2] ? 8'b11110000 : 8'b00001111;
adr_o <= xData1;
sel_o <= xData[2] ? 8'b11110000 : 8'b00001111;
adr_o <= xData;
end
`INCX,`INCUX:
begin
iocyc_o <= 1'b1;
stb_o <= 1'b1;
case(xData1[2:1])
case(xData[2:1])
2'b00: sel_o <= 8'b00000011;
2'b01: sel_o <= 8'b00001100;
2'b10: sel_o <= 8'b00110000;
2'b11: sel_o <= 8'b11000000;
endcase
adr_o <= xData1;
adr_o <= xData;
end
`INBX,`INBUX:
begin
iocyc_o <= 1'b1;
stb_o <= 1'b1;
case(xData1[2:0])
case(xData[2:0])
3'b000: sel_o <= 8'b00000001;
3'b001: sel_o <= 8'b00000010;
3'b010: sel_o <= 8'b00000100;
2187,7 → 2613,7
3'b110: sel_o <= 8'b01000000;
3'b111: sel_o <= 8'b10000000;
endcase
adr_o <= xData1;
adr_o <= xData;
end
`OUTWX:
begin
2195,7 → 2621,7
stb_o <= 1'b1;
we_o <= 1'b1;
sel_o <= 8'hFF;
adr_o <= xData1;
adr_o <= xData;
dat_o <= c;
end
`OUTHX:
2203,8 → 2629,8
iocyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
sel_o <= xData1[2] ? 8'b11110000 : 8'b00001111;
adr_o <= xData1;
sel_o <= xData[2] ? 8'b11110000 : 8'b00001111;
adr_o <= xData;
dat_o <= {2{c[31:0]}};
end
`OUTCX:
2212,13 → 2638,13
iocyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
case(xData1[2:1])
case(xData[2:1])
2'b00: sel_o <= 8'b00000011;
2'b01: sel_o <= 8'b00001100;
2'b10: sel_o <= 8'b00110000;
2'b11: sel_o <= 8'b11000000;
endcase
adr_o <= xData1;
adr_o <= xData;
dat_o <= {4{c[15:0]}};
end
`OUTBX:
2226,7 → 2652,7
iocyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
case(xData1[2:0])
case(xData[2:0])
3'b000: sel_o <= 8'b00000001;
3'b001: sel_o <= 8'b00000010;
3'b010: sel_o <= 8'b00000100;
2236,13 → 2662,13
3'b110: sel_o <= 8'b01000000;
3'b111: sel_o <= 8'b10000000;
endcase
adr_o <= xData1;
adr_o <= xData;
dat_o <= {8{c[7:0]}};
end
default:
begin
m1Data <= c;
ea <= xData1;
ea <= xData;
end
endcase
end
2250,7 → 2676,7
endcase
end
`ifdef FLOATING_POINT
if (xOpcode==`FP && xIRvalid) begin
if (xOpcode==`FP) begin
case (xFunc6)
`FDADD,`FDSUB:
begin
2294,45 → 2720,58
`endif
if (dbz_error) begin
$display("Divide by zero error");
LoadNOPs <= #1 1'b1;
// Squash a pending IRQ, but not an NMI
m1extype <= #1 `EX_DBZ;
LoadNOPs <= #1 1'b1;
xRtZero <= #1 1'b1;
xpcv <= #1 1'b0;
dpcv <= #1 1'b0;
ipcv <= 1'b0;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= #1 9'd0;
end
else if (ovr_error) begin
$display("Overflow error");
LoadNOPs <= 1'b1;
m1extype <= `EX_OFL;
LoadNOPs <= 1'b1;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b0;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= #1 9'd0;
end
// else if (priv_violation) begin
// $display("Priviledge violation");
// m1extype <= `EX_PRIV;
// LoadNOPs <= 1'b1;
// xRtZero <= 1'b1;
// xpcv <= 1'b0;
// dpcv <= 1'b0;
// ipcv <= 1'b0;
// if (!xNmi&!dNmi) begin
// m1extype <= `EX_PRIV;
// StatusHWI <= xStatusHWI;
// ie_fuse[0] <= ~xIm;
// end
// dIR <= #1 `NOP_INSN;
// xIR <= #1 `NOP_INSN;
// xRt <= #1 9'd0;
// end
else if (illegal_insn) begin
$display("Unimplemented Instruction");
LoadNOPs <= 1'b1;
m1extype <= `EX_UNIMP_INSN;
LoadNOPs <= 1'b1;
xRtZero <= 1'b1;
xpcv <= 1'b0;
dpcv <= 1'b0;
ipcv <= 1'b0;
StatusHWI <= xStatusHWI;
ie_fuse[0] <= ~xIm;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
xRt <= #1 9'd0;
end
end
// Stage tail
// Pipeline annul for when a bubble in the pipeline occurs.
else if (advanceM1) begin
m1IRvalid <= #1 1'b0;
m1IR <= #1 `NOP_INSN;
m1IsLoad <= #1 1'b0;
m1IsStore <= #1 1'b0;
m1IsOut <= #1 1'b0;
2340,7 → 2779,6
m1Rt <= #1 9'd0;
m1clkoff <= #1 1'b0;
m1Fip <= #1 1'b0;
m1pcv <= #1 1'b0;
m1extype <= #1 `EX_NON;
m1IsCnt <= #1 1'b0;
m1IsCacheElement <= #1 1'b0;
2363,31 → 2801,29
// - m2???? signals to M2 stage
//-----------------------------------------------------------------------------
if (advanceM1) begin
m2StatusHWI <= m1StatusHWI;
m2Im <= m1Im;
m2Nmi <= m1Nmi;
m2extype <= m1extype;
m2Addr <= pea;
m2Data <= m1Data;
m2Fip <= m1Fip;
m2pc <= m1pc;
m2pcv <= m1pcv;
m2IR <= m1IR;
m2Opcode <= m1Opcode;
m2Func <= m1Func;
m2IsCnt <= m1IsCnt;
m2Func <= m1Func;
m2Rt <= m1Rt;
m2clkoff <= m1clkoff;
m2AXC <= m1AXC;
m2IsCacheElement <= m1IsCacheElement;
m2IRvalid <= m1IRvalid;
m2IsLoad <= m1IsLoad & m1IRvalid;
m2IsStore <= m2IsStore & m1IRvalid;
m2IsLoad <= m1IsLoad;
m2IsStore <= m2IsStore;
 
if (m1IsIO & err_i & m1IRvalid) begin
if (m1IsIO & err_i) begin
m2extype <= `EX_DBERR;
errorAddress <= adr_o;
end
 
if (m1extype == `EX_NON && m1IRvalid) begin
if (m1extype == `EX_NON) begin
case(m1Opcode)
`MISC:
case(m1Func)
2401,10 → 2837,9
end
else begin // dhit must be true
$display("fetched vector: %h", {cdat[63:2],2'b00});
m2Opcode <= `NOPI;
m2IR <= `NOP_INSN;
m2IsLoad <= 1'b0;
pc <= {cdat[63:2],2'b00};
ipcv <= 1'b1;
LoadNOPs <= 1'b0;
end
endcase
2413,7 → 2848,7
iocyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
m2Data <= dat_i;
m2Data <= data64;
end
`INH:
begin
2420,7 → 2855,7
iocyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
m2Data <= sel_o[7] ? {{32{dat_i[63]}},dat_i[63:32]}:{{32{dat_i[31]}},dat_i[31: 0]};
m2Data <= {{32{data32[31]}},data32};
end
`INHU:
begin
2427,7 → 2862,7
iocyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
m2Data <= sel_o[7] ? dat_i[63:32] : dat_i[31: 0];
m2Data <= data32;
end
`INCH:
begin
2434,13 → 2869,7
iocyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
case(sel_o)
8'b00000011: m2Data <= {{48{dat_i[15]}},dat_i[15: 0]};
8'b00001100: m2Data <= {{48{dat_i[31]}},dat_i[31:16]};
8'b00110000: m2Data <= {{48{dat_i[47]}},dat_i[47:32]};
8'b11000000: m2Data <= {{48{dat_i[63]}},dat_i[63:48]};
default: m2Data <= 64'hDEADDEADDEADDEAD;
endcase
m2Data <= {{48{data16[15]}},data16};
end
`INCU:
begin
2447,13 → 2876,7
iocyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
case(sel_o)
8'b00000011: m2Data <= dat_i[15: 0];
8'b00001100: m2Data <= dat_i[31:16];
8'b00110000: m2Data <= dat_i[47:32];
8'b11000000: m2Data <= dat_i[63:48];
default: m2Data <= 64'hDEADDEADDEADDEAD;
endcase
m2Data <= data16;
end
`INB:
begin
2460,17 → 2883,7
iocyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
case(sel_o)
8'b00000001: m2Data <= {{56{dat_i[ 7]}},dat_i[ 7: 0]};
8'b00000010: m2Data <= {{56{dat_i[15]}},dat_i[15: 8]};
8'b00000100: m2Data <= {{56{dat_i[23]}},dat_i[23:16]};
8'b00001000: m2Data <= {{56{dat_i[31]}},dat_i[31:24]};
8'b00010000: m2Data <= {{56{dat_i[39]}},dat_i[39:32]};
8'b00100000: m2Data <= {{56{dat_i[47]}},dat_i[47:40]};
8'b01000000: m2Data <= {{56{dat_i[55]}},dat_i[55:48]};
8'b10000000: m2Data <= {{56{dat_i[63]}},dat_i[63:56]};
default: m2Data <= 64'hDEADDEADDEADDEAD;
endcase
m2Data <= {{56{data8[7]}},data8};
end
`INBU:
begin
2477,17 → 2890,7
iocyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
case(sel_o)
8'b00000001: m2Data <= dat_i[ 7: 0];
8'b00000010: m2Data <= dat_i[15: 8];
8'b00000100: m2Data <= dat_i[23:16];
8'b00001000: m2Data <= dat_i[31:24];
8'b00010000: m2Data <= dat_i[39:32];
8'b00100000: m2Data <= dat_i[47:40];
8'b01000000: m2Data <= dat_i[55:48];
8'b10000000: m2Data <= dat_i[63:56];
default: m2Data <= 64'hDEADDEADDEADDEAD;
endcase
m2Data <= data8;
end
`OUTW,`OUTH,`OUTC,`OUTB,`OUTBC:
begin
2498,58 → 2901,47
end
`CACHE:
case(m1IR[19:15])
`INVIL: tvalid[pea[12:6]] <= 1'b0;
`INVIL: tvalid[pea[13:6]] <= 1'b0;
default: ;
endcase
 
`LW,`LM,`LFD,`LSW,`LP,`LFDP:
if (!m1IsCacheElement) begin
cyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= 8'hFF;
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
m2Addr <= pea;
end
else begin
m2IsLoad <= 1'b0;
m2Opcode <= `NOPI;
m2Data <= cdat;
m2IR <= `NOP_INSN;
m2Data <= cdata64;
end
`ifdef ADDRESS_RESERVATION
`LWR:
if (!m1IsCacheElement) begin
begin
rsv_o <= 1'b1;
resv_address <= pea[63:5];
cyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= 8'hFF;
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
m2Addr <= pea;
end
else begin
m2IsLoad <= 1'b0;
m2Opcode <= `NOPI;
m2Data <= cdat;
rsv_o <= 1'b1; // ???
resv_address <= pea[63:5];
end
`endif
`LH,`LF,`LFP:
if (!m1IsCacheElement) begin
cyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
m2Addr <= pea;
end
else begin
m2IsLoad <= 1'b0;
m2Opcode <= `NOPI;
if (pea[2])
m2Data <= {{32{cdat[31]}},cdat[31:0]};
else
m2Data <= {{32{cdat[63]}},cdat[63:32]};
m2IR <= `NOP_INSN;
m2Data <= {{32{cdata32[31]}},cdata32};
end
 
`LHU,`LSH:
2556,17 → 2948,14
if (!m1IsCacheElement) begin
cyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= pea[2] ? 8'b11110000 : 8'b00001111;
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
m2Addr <= pea;
end
else begin
m2IsLoad <= 1'b0;
m2Opcode <= `NOPI;
if (pea[2])
m2Data <= {32'd0,cdat};
else
m2Data <= {32'd0,cdat[63:32]};
m2IR <= `NOP_INSN;
m2Data <= cdata32;
end
 
`LC:
2573,12 → 2962,7
if (!m1IsCacheElement) begin
cyc_o <= 1'b1;
stb_o <= 1'b1;
case(pea[2:1])
2'b00: sel_o <= 8'b00000011;
2'b01: sel_o <= 8'b00001100;
2'b10: sel_o <= 8'b00110000;
2'b11: sel_o <= 8'b11000000;
endcase
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
m2Addr <= pea;
end
2585,13 → 2969,8
else begin
$display("dhit=1, cdat=%h",cdat);
m2IsLoad <= 1'b0;
m2Opcode <= `NOPI;
case(pea[2:1])
2'd0: m2Data <= {{48{cdat[15]}},cdat[15:0]};
2'd1: m2Data <= {{48{cdat[31]}},cdat[31:16]};
2'd2: m2Data <= {{48{cdat[47]}},cdat[47:32]};
2'd3: m2Data <= {{48{cdat[63]}},cdat[63:48]};
endcase
m2IR <= `NOP_INSN;
m2Data <= {{48{cdata16[15]}},cdata16};
end
 
`LCU:
2598,24 → 2977,14
if (!m1IsCacheElement) begin
cyc_o <= 1'b1;
stb_o <= 1'b1;
case(pea[2:1])
2'b00: sel_o <= 8'b00000011;
2'b01: sel_o <= 8'b00001100;
2'b10: sel_o <= 8'b00110000;
2'b11: sel_o <= 8'b11000000;
endcase
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
m2Addr <= pea;
end
else begin
m2IsLoad <= 1'b0;
m2Opcode <= `NOPI;
case(pea[2:1])
2'd0: m2Data <= {48'd0,cdat[15: 0]};
2'd1: m2Data <= {48'd0,cdat[31:16]};
2'd2: m2Data <= {48'd0,cdat[47:32]};
2'd3: m2Data <= {48'd0,cdat[63:48]};
endcase
m2IR <= `NOP_INSN;
m2Data <= cdata16;
end
 
`LB:
2623,49 → 2992,21
$display("Load byte:");
cyc_o <= 1'b1;
stb_o <= 1'b1;
case(pea[2:0])
3'b000: sel_o <= 8'b00000001;
3'b001: sel_o <= 8'b00000010;
3'b010: sel_o <= 8'b00000100;
3'b011: sel_o <= 8'b00001000;
3'b100: sel_o <= 8'b00010000;
3'b101: sel_o <= 8'b00100000;
3'b110: sel_o <= 8'b01000000;
3'b111: sel_o <= 8'b10000000;
endcase
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
m2Addr <= pea;
end
else begin
m2IsLoad <= 1'b0;
m2Opcode <= `NOPI;
case(pea[2:0])
3'b000: m2Data <= {{56{cdat[ 7]}},cdat[ 7: 0]};
3'b001: m2Data <= {{56{cdat[15]}},cdat[15: 8]};
3'b010: m2Data <= {{56{cdat[23]}},cdat[23:16]};
3'b011: m2Data <= {{56{cdat[31]}},cdat[31:24]};
3'b100: m2Data <= {{56{cdat[39]}},cdat[39:32]};
3'b101: m2Data <= {{56{cdat[47]}},cdat[47:40]};
3'b110: m2Data <= {{56{cdat[55]}},cdat[55:48]};
3'b111: m2Data <= {{56{cdat[63]}},cdat[63:56]};
endcase
m2IR <= `NOP_INSN;
m2Data <= {{56{cdata8[7]}},cdata8};
end
 
`LBU:
if (!m1IsCacheElement) begin
$display("Load unsigned byte:");
cyc_o <= 1'b1;
stb_o <= 1'b1;
case(pea[2:0])
3'b000: sel_o <= 8'b00000001;
3'b001: sel_o <= 8'b00000010;
3'b010: sel_o <= 8'b00000100;
3'b011: sel_o <= 8'b00001000;
3'b100: sel_o <= 8'b00010000;
3'b101: sel_o <= 8'b00100000;
3'b110: sel_o <= 8'b01000000;
3'b111: sel_o <= 8'b10000000;
endcase
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
m2Addr <= pea;
end
2672,17 → 3013,8
else begin
$display("m2IsLoad <= 0");
m2IsLoad <= 1'b0;
m2Opcode <= `NOPI;
case(pea[2:0])
3'b000: m2Data <= {56'd0,cdat[ 7: 0]};
3'b001: m2Data <= {56'd0,cdat[15: 8]};
3'b010: m2Data <= {56'd0,cdat[23:16]};
3'b011: m2Data <= {56'd0,cdat[31:24]};
3'b100: m2Data <= {56'd0,cdat[39:32]};
3'b101: m2Data <= {56'd0,cdat[47:40]};
3'b110: m2Data <= {56'd0,cdat[55:48]};
3'b111: m2Data <= {56'd0,cdat[63:56]};
endcase
m2IR <= `NOP_INSN;
m2Data <= cdata8;
end
 
`SW,`SM,`SFD,`SSW,`SP,`SFDP:
2697,7 → 3029,7
cyc_o <= #1 1'b1;
stb_o <= #1 1'b1;
we_o <= #1 1'b1;
sel_o <= #1 8'hFF;
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
dat_o <= #1 m1Data;
end
2713,7 → 3045,7
cyc_o <= #1 1'b1;
stb_o <= #1 1'b1;
we_o <= #1 1'b1;
sel_o <= #1 pea[2] ? 8'b11110000 : 8'b00001111;
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
dat_o <= #1 {2{m1Data[31:0]}};
end
2730,12 → 3062,7
cyc_o <= #1 1'b1;
stb_o <= #1 1'b1;
we_o <= #1 1'b1;
case(pea[2:1])
2'b00: sel_o <= #1 8'b00000011;
2'b01: sel_o <= #1 8'b00001100;
2'b10: sel_o <= #1 8'b00110000;
2'b11: sel_o <= #1 8'b11000000;
endcase
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
dat_o <= #1 {4{m1Data[15:0]}};
end
2751,16 → 3078,7
cyc_o <= #1 1'b1;
stb_o <= #1 1'b1;
we_o <= #1 1'b1;
case(pea[2:0])
3'b000: sel_o <= #1 8'b00000001;
3'b001: sel_o <= #1 8'b00000010;
3'b010: sel_o <= #1 8'b00000100;
3'b011: sel_o <= #1 8'b00001000;
3'b100: sel_o <= #1 8'b00010000;
3'b101: sel_o <= #1 8'b00100000;
3'b110: sel_o <= #1 8'b01000000;
3'b111: sel_o <= #1 8'b10000000;
endcase
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
dat_o <= #1 {8{m1Data[7:0]}};
end
2775,7 → 3093,7
cyc_o <= #1 1'b1;
stb_o <= #1 1'b1;
we_o <= #1 1'b1;
sel_o <= #1 8'hFF;
sel_o <= fnSelect(m1Opcode,pea[2:0]);
adr_o <= pea;
dat_o <= #1 m1Data;
resv_address <= #1 59'd0;
2782,7 → 3100,7
rsf <= #1 1'b1;
end
else
m2Opcode <= #1 `NOPI;
m2IR <= `NOP_INSN;
end
`endif
endcase
2795,24 → 3113,26
//---------------------------------------------------------
`ifdef TLB
if (m1IsLoad && m1Rt[4:0]==5'd0 && DTLBMiss) begin
m1Opcode <= `NOPI;
m1IR <= `NOP_INSN;
end
if ((m1IsLoad&&m1Rt[4:0]!=5'd0)|m1IsStore) begin
if (DTLBMiss) begin
$display("DTLB miss on address: %h",ea);
cyc_o <= 1'b0;
stb_o <= 1'b0;
we_o <= 1'b0;
sel_o <= 8'h00;
m1extype <= `EX_TLBD;
StatusEXL <= 1'b1;
StatusHWI <= 1'b1;
BadVAddr <= ea[63:13];
m1Opcode <= `NOPI;
if (!xNmi&!dNmi) begin
dIR <= `NOP_INSN;
xIR <= `NOP_INSN;
end
m1IR <= `NOP_INSN;
m1Rt <= 9'd0;
pc <= 64'hC;
xIR <= `NOP_INSN;
xRtzero <= 1'b1;
dIR <= `NOP_INSN;
m1pcv <= 1'b0;
xpcv <= 1'b0;
dpcv <= 1'b0;
dhwxtype <= 2'b11;
xRt <= #1 9'd0;
LoadNOPs <= 1'b1;
end
end
`endif
2821,16 → 3141,14
// Pipeline annul for when a bubble in the pipeline occurs.
else if (advanceM2) begin
m2Rt <= #1 9'd0;
m2IRvalid <= 1'b0;
m2IR <= #1 `NOP_INSN;
m2IsCnt <= #1 1'b0;
m2IsLoad <= #1 1'b0;
m2IsStore <= #1 1'b0;
m2Func <= #1 7'd0;
m2Addr <= 64'd0;
m2Data <= #1 64'd0;
m2clkoff <= #1 1'b0;
m2Fip <= #1 1'b0;
m2pcv <= #1 1'b0;
m2extype <= #1 `EX_NON;
m2IsCacheElement <= 1'b0;
end
2848,25 → 3166,21
if (advanceM2) begin
wextype <= #1 m2extype;
wpc <= #1 m2pc;
wpcv <= #1 m2pcv;
wFip <= #1 m2Fip;
wIR <= #1 m2IR;
wIsStore <= #1 m2IsStore & m2IRvalid;
wOpcode <= #1 m2Opcode;
wFunc <= #1 m2Func;
wIsStore <= #1 m2IsStore;
wData <= #1 m2Data;
wRt <= #1 m2Rt;
wclkoff <= #1 m2clkoff;
wAXC <= #1 m2AXC;
wIRvalid <= m2IRvalid;
// There's not an error is a prefetch is taking place (m2Rt=0).
if (((m2IsLoad&&m2Rt[4:0]!=5'd0)|m2IsStore) & err_i & m2IRvalid) begin
if (((m2IsLoad&&m2Rt[4:0]!=5'd0)|m2IsStore) & err_i) begin
wextype <= #1 `EX_DBERR;
errorAddress <= #1 adr_o;
end
if (m2extype==`EX_NON & m2IRvalid) begin
if (m2extype==`EX_NON) begin
case(m2Opcode)
`MISC:
if (m2Func==`SYSCALL)
2874,10 → 3188,9
cyc_o <= #1 1'b0;
stb_o <= #1 1'b0;
sel_o <= #1 8'h00;
pc <= #1 {dat_i[63:2],2'b00};
ipcv <= 1'b1;
pc <= #1 {data64[63:2],2'b00};
LoadNOPs <= 1'b0;
$display("M2 Fetched vector: %h",{dat_i[63:2],2'b00});
$display("M2 Fetched vector: %h",{data64[63:2],2'b00});
end
`SH,`SC,`SB,`SW,`SWC,`SF,`SFD,`SSH,`SSW,`SP,`SFP,`SFDP:
begin
2891,7 → 3204,7
cyc_o <= #1 1'b0;
stb_o <= #1 1'b0;
sel_o <= #1 8'h00;
wData <= #1 sel_o[7] ? {{32{dat_i[63]}},dat_i[63:32]}:{{32{dat_i[31]}},dat_i[31: 0]};
wData <= #1 {{32{data32[31]}},data32};
end
`LW,`LWR,`LFD,`LSW,`LP,`LFDP:
begin
2898,7 → 3211,7
cyc_o <= #1 1'b0;
stb_o <= #1 1'b0;
sel_o <= #1 8'h00;
wData <= #1 dat_i;
wData <= #1 data64;
end
`LHU:
begin
2905,7 → 3218,7
cyc_o <= #1 1'b0;
stb_o <= #1 1'b0;
sel_o <= #1 8'h00;
wData <= #1 sel_o[7] ? dat_i[63:32] : dat_i[31: 0];
wData <= #1 data32;
end
`LC:
begin
2912,13 → 3225,7
cyc_o <= #1 1'b0;
stb_o <= #1 1'b0;
sel_o <= #1 8'h00;
case(sel_o)
8'b00000011: wData <= #1 {{48{dat_i[15]}},dat_i[15: 0]};
8'b00001100: wData <= #1 {{48{dat_i[31]}},dat_i[31:16]};
8'b00110000: wData <= #1 {{48{dat_i[47]}},dat_i[47:32]};
8'b11000000: wData <= #1 {{48{dat_i[63]}},dat_i[63:48]};
default: wData <= #1 64'hDEADDEADDEADDEAD;
endcase
wData <= #1 {{48{data16[15]}},data16};
end
`LCU:
begin
2925,13 → 3232,7
cyc_o <= #1 1'b0;
stb_o <= #1 1'b0;
sel_o <= #1 8'h00;
case(sel_o)
8'b00000011: wData <= #1 dat_i[15: 0];
8'b00001100: wData <= #1 dat_i[31:16];
8'b00110000: wData <= #1 dat_i[47:32];
8'b11000000: wData <= #1 dat_i[63:48];
default: wData <= #1 64'hDEADDEADDEADDEAD;
endcase
wData <= #1 data16;
end
`LB:
begin
2938,17 → 3239,7
cyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
case(sel_o)
8'b00000001: wData <= {{56{dat_i[ 7]}},dat_i[ 7: 0]};
8'b00000010: wData <= {{56{dat_i[15]}},dat_i[15: 8]};
8'b00000100: wData <= {{56{dat_i[23]}},dat_i[23:16]};
8'b00001000: wData <= {{56{dat_i[31]}},dat_i[31:24]};
8'b00010000: wData <= {{56{dat_i[39]}},dat_i[39:32]};
8'b00100000: wData <= {{56{dat_i[47]}},dat_i[47:40]};
8'b01000000: wData <= {{56{dat_i[55]}},dat_i[55:48]};
8'b10000000: wData <= {{56{dat_i[63]}},dat_i[63:56]};
default: wData <= 64'hDEADDEADDEADDEAD;
endcase
wData <= {{56{data8[7]}},data8};
end
`LBU:
begin
2955,17 → 3246,7
cyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
case(sel_o)
8'b00000001: wData <= dat_i[ 7: 0];
8'b00000010: wData <= dat_i[15: 8];
8'b00000100: wData <= dat_i[23:16];
8'b00001000: wData <= dat_i[31:24];
8'b00010000: wData <= dat_i[39:32];
8'b00100000: wData <= dat_i[47:40];
8'b01000000: wData <= dat_i[55:48];
8'b10000000: wData <= dat_i[63:56];
default: wData <= 64'hDEADDEADDEADDEAD;
endcase
wData <= data8;
end
default: ;
endcase
2977,14 → 3258,13
// Stage tail
// Pipeline annul for when a bubble in the pipeline occurs.
else if (advanceW) begin
wIR <= #1 `NOP_INSN;
wextype <= `EX_NON;
wRt <= 9'd0;
wData <= 64'd0;
wIsStore <= 1'b0;
wIRvalid <= 1'b0;
wclkoff <= 1'b0;
wFip <= 1'b0;
wpcv <= 1'b0;
end
 
 
3000,46 → 3280,55
//-----------------------------------------------------------------------------
//
if (advanceW) begin
textype <= wextype;
tRt <= wRt;
tData <= wData;
// Hold onto the last register update
if (wRt[4:0]!=5'd0 && wRt[4:0]!=5'd29) begin
tRt <= wRt;
tData <= wData;
end
if (wRt!=5'd0) begin
$display("Writing regfile[%d:%d] with %h", wRt[8:5],wRt[4:0], wData);
end
if (wIRvalid) begin
case(wOpcode)
`LSH:
case (wRt)
`SR: begin
bu_im <= wData[31];
im <= wData[15];
FXE <= wData[12];
case(wOpcode)
`LSH:
case (wRt)
`SR: begin
bu_im <= wData[31];
if (wData[15])
ie_fuse <= 8'h00;
else
ie_fuse[0] <= 1'b1;
FXE <= wData[12];
end
default: ;
endcase
`MISC:
case(wFunc)
`SYSCALL:
if (wIR[15:7]==`EX_NMI || (wIR[15:7]>=`EX_IRQ && wIR[15:7]<`EX_IRQ+32) || wIR[15:7]==`EX_TLBI || wIR[15:7]==`EX_TLBD)
IPC[wAXC] <= wData;
else
EPC[wAXC] <= wData;
default: ;
endcase
`R:
case(wFunc6)
`MTSPR:
case(wIR[11:6])
`ifdef SEGMENTATION
`CS: CS[wAXC][63:16] <= wData[63:16];
`DS: DS[wAXC][63:16] <= wData[63:16];
`ES: ES[wAXC][63:16] <= wData[63:16];
`SS: SS[wAXC][63:16] <= wData[63:16];
`endif
`IPC: begin
$display("mtspr IPC[%d]=%h",wAXC,wData);
IPC[wAXC] <= wData;
end
`EPC: EPC[wAXC] <= wData;
default: ;
endcase
`MISC:
case(wFunc)
`SYSCALL:
if (wIR[15:7]==`EX_NMI || wIR[15:7]==`EX_IRQ)
IPC[wAXC] <= wData;
else
EPC[wAXC] <= wData;
default: ;
endcase
`R:
case(wFunc6)
`MTSPR:
case(wIR[11:6])
`IPC: begin
$display("mtspr IPC[%d]=%h",wAXC,wData);
IPC[wAXC] <= wData;
end
`EPC: EPC[wAXC] <= wData;
default: ;
endcase
endcase
endcase
end
endcase
if (wclkoff)
clk_en <= 1'b0;
else
3053,7 → 3342,6
xFip <= 1'b0;
dFip <= 1'b0;
pc <= fnIncPC(wpc);
ipcv <= 1'b1;
end
//---------------------------------------------------------
// WRITEBACK (WB') - part two:
3077,58 → 3365,65
pc <= `RESET_VECTOR;
end
// Hardware exceptions
`EX_NMI,`EX_IRQ:
`EX_NMI,`EX_IRQ,`EX_TLBI,`EX_TLBD,
`EX_IRQ+1,`EX_IRQ+2,`EX_IRQ+3,`EX_IRQ+4,`EX_IRQ+5,`EX_IRQ+6,`EX_IRQ+7,
`EX_IRQ+8,`EX_IRQ+9,`EX_IRQ+10,`EX_IRQ+11,`EX_IRQ+12,`EX_IRQ+13,`EX_IRQ+14,
`EX_IRQ+15,`EX_IRQ+16,`EX_IRQ+17,`EX_IRQ+18,`EX_IRQ+19,`EX_IRQ+20,`EX_IRQ+21,
`EX_IRQ+22,`EX_IRQ+23,`EX_IRQ+24,`EX_IRQ+25,`EX_IRQ+26,`EX_IRQ+27,`EX_IRQ+28,
`EX_IRQ+29,`EX_IRQ+30,`EX_IRQ+31:
begin
$display("Stuffing SYSCALL %d",wextype);
dIR <= {`MISC,5'd25,4'd0,wextype,`SYSCALL};
dIRvalid <= 1'b1;
dNmi <= 1'b0;
xNmi <= 1'b0;
m1Nmi <= 1'b0;
m2Nmi <= 1'b0;
// $display("Stuffing SYSCALL %d",wextype);
// dIR <= {`MISC,9'd0,wextype,`SYSCALL};
// One of the following pc's MUST be valid.
// wpc will be valid if the interrupt occurred outside of a branch
// shadow. m1pc or m2pc (the branch target address) will be valid
// depending on where in the branch shadow the interrupt falls.
// Syscall has a larger shadow than a branch because it loads the
// vector from memory. Eventually syscall flags the pc valid.
case(1'b1)
wpcv: dpc <= wpc;
m2pcv: dpc <= m2pc;
m1pcv: dpc <= m1pc;
xpcv: dpc <= xpc;
dpcv: dpc <= dpc;
default: dpc <= pc;
endcase
dpcv <= 1'b1;
// vector from memory. xpc or dpc should be valid depending on
// whether or not the vector is cached. Eventually syscall flags
// the pc valid. If none of the PC's are valid, then there is a
// hardware problem.
// dpc <= wpc;
// case(1'b1)
// wpcv: dpc <= wpc;
// m2pcv: dpc <= m2pc;
// m1pcv: dpc <= m1pc;
// xpcv: dpc <= xpc;
// dpcv: dpc <= dpc;
// ipcv: dpc <= pc;
// default: dpc <= `RESET_VECTOR; // Can't happen
// endcase
// dpcv <= 1'b1;
end
// Software exceptions
// We probably want to return to the excepting instruction.
`EX_TLBD,`EX_DBERR:
`EX_DBERR:
begin
pccap <= 1'b0;
dIR <= {`MISC,5'd24,4'd0,wextype,`SYSCALL};
dIRvalid <= 1'b1;
dIR <= {`MISC,9'd0,wextype,`SYSCALL};
dpc <= wpc;
dpcv <= 1'b1;
end
default:
begin
dIR <= {`MISC,5'd24,4'd0,wextype,`SYSCALL};
dIRvalid <= 1'b1;
pccap <= 1'b0;
dIR <= {`MISC,9'd0,wextype,`SYSCALL};
dpc <= wpc;
dpcv <= 1'b1;
end
endcase
end
// Stage tail
// Pipeline annul for when a bubble in the pipeline occurs.
// T and W advance together, meaning an else would never be executed.
 
//-----------------------------------------------------------------------------
// TRAILER:
// - placeholder to allow the use of synchronous register memory
//-----------------------------------------------------------------------------
if (advanceT) begin
end
// Hold onto the last register update
//begin
// if (tRt[4:0]!=5'd0 && tRt[4:0]!=5'd29) begin
// uRt <= tRt;
// uData <= tData;
// end
//end
 
 
//=============================================================================
// Cache loader
//=============================================================================
3178,8 → 3473,8
cyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 8'h00;
tmem[adr_o[12:6]] <= {1'b1,adr_o[63:13]}; // This will cause ihit to go high
tvalid[adr_o[12:6]] <= 1'b1;
tmem[adr_o[13:6]] <= adr_o[63:14]; // This will cause ihit to go high
tvalid[adr_o[13:6]] <= 1'b1;
icaccess <= 1'b0;
cstate <= IDLE;
end
/raptor64/trunk/rtl/verilog/Raptor64_SetTargetRegister.v
91,6 → 91,9
`NOPI: xRt <= 9'd0;
`BEQI,`BNEI,`BLTI,`BLEI,`BGTI,`BGEI,`BLTUI,`BLEUI,`BGTUI,`BGEUI:
xRt <= 9'd0;
`IMM1: xRt <= 9'd0;
`IMM2: xRt <= 9'd0;
`IMM3: xRt <= 9'd0;
default: xRt <= {dAXC,dIR[19:15]};
endcase
end
/raptor64/trunk/rtl/verilog/Raptor64_regfile.v
81,44 → 81,42
);
 
 
reg [63:0] nxt_a;
always @(dRa or xData or m1Data or m2Data or wData or tData or rfoa or dpc or xRt or m1Rt or m2Rt or wRt or tRt)
casex(dRa)
9'bxxxx00000: nxt_a <= 64'd0;
9'bxxxx11101: nxt_a <= dpc;
xRt: nxt_a <= xData;
m1Rt: nxt_a <= m1Data;
m2Rt: nxt_a <= m2Data;
wRt: nxt_a <= wData;
tRt: nxt_a <= tData;
default: nxt_a <= rfoa;
endcase
// casex(dRa)
// 9'bxxxx00000: nxt_a <= 64'd0;
// 9'bxxxx11101: nxt_a <= dpc;
// xRt: nxt_a <= xData;
// m1Rt: nxt_a <= m1Data;
// m2Rt: nxt_a <= m2Data;
// wRt: nxt_a <= wData;
// tRt: nxt_a <= tData;
// default: nxt_a <= rfoa;
// endcase
 
reg [63:0] nxt_b;
always @(dRb or xData or m1Data or m2Data or wData or tData or rfob or dpc or xRt or m1Rt or m2Rt or wRt or tRt)
casex(dRb)
9'bxxxx00000: nxt_b <= 64'd0;
9'bxxxx11101: nxt_b <= dpc;
xRt: nxt_b <= xData;
m1Rt: nxt_b <= m1Data;
m2Rt: nxt_b <= m2Data;
wRt: nxt_b <= wData;
tRt: nxt_b <= tData;
default: nxt_b <= rfob;
endcase
//reg [63:0] nxt_b;
//always @(dRb or xData or m1Data or m2Data or wData or tData or rfob or dpc or xRt or m1Rt or m2Rt or wRt or tRt)
// casex(dRb)
// 9'bxxxx00000: nxt_b <= 64'd0;
// 9'bxxxx11101: nxt_b <= dpc;
// xRt: nxt_b <= xData;
// m1Rt: nxt_b <= m1Data;
// m2Rt: nxt_b <= m2Data;
// wRt: nxt_b <= wData;
// tRt: nxt_b <= tData;
// default: nxt_b <= rfob;
// endcase
//
//reg [63:0] nxt_c;
//always @(dRc or xData or m1Data or m2Data or wData or tData or rfoc or dpc or xRt or m1Rt or m2Rt or wRt or tRt)
// casex(dRc)
// 9'bxxxx00000: nxt_c <= 64'd0;
// 9'bxxxx11101: nxt_c <= dpc;
// xRt: nxt_c <= xData;
// m1Rt: nxt_c <= m1Data;
// m2Rt: nxt_c <= m2Data;
// wRt: nxt_c <= wData;
// tRt: nxt_c <= tData;
// default: nxt_c <= rfoc;
// endcase
 
reg [63:0] nxt_c;
always @(dRc or xData or m1Data or m2Data or wData or tData or rfoc or dpc or xRt or m1Rt or m2Rt or wRt or tRt)
casex(dRc)
9'bxxxx00000: nxt_c <= 64'd0;
9'bxxxx11101: nxt_c <= dpc;
xRt: nxt_c <= xData;
m1Rt: nxt_c <= m1Data;
m2Rt: nxt_c <= m2Data;
wRt: nxt_c <= wData;
tRt: nxt_c <= tData;
default: nxt_c <= rfoc;
endcase
 
 
endmodule
/raptor64/trunk/rtl/verilog/Raptor64_bitfield.v
2,7 → 2,7
`timescale 1ns / 1ps
//=============================================================================
// __
// \\__/ o\ (C) 2012 Robert Finch
// \\__/ o\ (C) 2012,2013 Robert Finch
// \ __ / All rights reserved.
// \/_// robfinch<remove>@opencores.org
// ||
27,27 → 27,32
//
//=============================================================================
//
//`define I_BFEXTS 1
//`define I_SEXT 1
 
module Raptor64_bitfield(xIR, a, b, o, masko);
parameter DWIDTH=64;
input [31:0] xIR;
input [63:0] a;
input [63:0] b;
output [63:0] o;
reg [63:0] o;
output [63:0] masko;
input [DWIDTH-1:0] a;
input [DWIDTH-1:0] b;
output [DWIDTH-1:0] o;
reg [DWIDTH-1:0] o;
output [DWIDTH-1:0] masko;
 
reg [63:0] o1;
reg [63:0] o2;
reg [DWIDTH-1:0] o1;
reg [DWIDTH-1:0] o2;
wire [6:0] xOpcode = xIR[31:25];
wire [2:0] xFunc3 = xIR[2:0];
 
// generate mask
reg [63:0] mask;
reg [DWIDTH-1:0] mask;
assign masko = mask;
wire [5:0] mb = xIR[8:3];
wire [5:0] me = xIR[14:9];
wire [5:0] ml = me-mb; // mask length-1
integer nn,n;
always @(mb or me or nn)
for (nn = 0; nn < 64; nn = nn + 1)
for (nn = 0; nn < DWIDTH; nn = nn + 1)
mask[nn] <= (nn >= mb) ^ (nn <= me) ^ (me >= mb);
 
always @(xOpcode,xFunc3,mask,b,a,mb)
56,19 → 61,31
case(xFunc3)
`BFINS: begin
o2 = a << mb;
for (n = 0; n < 64; n = n + 1) o[n] = mask[n] ? o2[n] : b[n];
for (n = 0; n < DWIDTH; n = n + 1) o[n] = mask[n] ? o2[n] : b[n];
end
`BFSET: begin for (n = 0; n < 64; n = n + 1) o[n] = mask[n] ? 1'b1 : a[n]; end
`BFCLR: begin for (n = 0; n < 64; n = n + 1) o[n] = mask[n] ? 1'b0 : a[n]; end
`BFCHG: begin for (n = 0; n < 64; n = n + 1) o[n] = mask[n] ? ~a[n] : a[n]; end
`BFEXT: begin
for (n = 0; n < 64; n = n + 1)
`BFSET: begin for (n = 0; n < DWIDTH; n = n + 1) o[n] = mask[n] ? 1'b1 : a[n]; end
`BFCLR: begin for (n = 0; n < DWIDTH; n = n + 1) o[n] = mask[n] ? 1'b0 : a[n]; end
`BFCHG: begin for (n = 0; n < DWIDTH; n = n + 1) o[n] = mask[n] ? ~a[n] : a[n]; end
`BFEXTU: begin
for (n = 0; n < DWIDTH; n = n + 1)
o1[n] = mask[n] ? a[n] : 1'b0;
o = o1 >> mb;
end
default: o = 64'd0;
`ifdef I_BFEXTS
`BFEXTS: begin
for (n = 0; n < DWIDTH; n = n + 1)
o1[n] = mask[n] ? a[n] : 1'b0;
o2 = o1 >> mb;
for (n = 0; n < DWIDTH; n = n + 1)
o[n] = n > ml ? o2[ml] : o2[n];
end
`endif
`ifdef I_SEXT
`SEXT: begin for (n = 0; n < DWIDTH; n = n + 1) o[n] = mask[n] ? a[mb] : a[n]; end
`endif
default: o = {DWIDTH{1'b0}};
endcase
default: o = 64'd0;
default: o = {DWIDTH{1'b0}};
endcase
 
endmodule
/raptor64/trunk/rtl/verilog/Raptor64_addsub.v
54,8 → 54,12
`BCD_SUB: o = bcdsubo;
default: o = 64'd0;
endcase
`ADDI: o = a + imm;
`ADDUI: o = a + imm;
`INB,`INCH,`INH,`INW,`INCU,`INHU,`INBU,
`OUTB,`OUTC,`OUTH,`OUTW,`OUTBC,
`LW,`LH,`LC,`LB,`LHU,`LCU,`LBU,`LEA,`LF,`LFD,`LWR,
`SW,`SH,`SC,`SB,`SF,`SFD,`SWC,
`ADDI,`ADDUI:
o = a + imm;
`SUBI: o = a - imm;
`SUBUI: o = a - imm;
default: o = 64'd0;
/raptor64/trunk/rtl/verilog/Raptor64_dcache_tagram.v
0,0 → 1,48
`timescale 1ns / 1ps
//=============================================================================
// __
// \\__/ o\ (C) 2013 Robert Finch
// \ __ / All rights reserved.
// \/_// robfinch<remove>@opencores.org
// ||
//
// Raptor64_dcache_tagram.v
//
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//
//=============================================================================
//
module Raptor64_dcache_tagram(wclk, we, adr, d, rclk, ea, tago);
input wclk;
input we;
input [8:0] adr;
input [49:0] d;
input rclk;
input [8:0] ea;
output [49:0] tago;
 
reg [49:0] ram [0:511];
reg [8:0] radr;
 
always @(posedge wclk)
if (we) ram[adr] <= d;
 
always @(posedge rclk)
radr <= ea;
 
assign tago = ram[radr];
 
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.