Line 42... |
Line 42... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.6 2002/03/14 00:30:24 lampret
|
|
// Added alternative for critical path in DU.
|
|
//
|
// Revision 1.5 2002/02/11 04:33:17 lampret
|
// Revision 1.5 2002/02/11 04:33:17 lampret
|
// Speed optimizations (removed duplicate _cyc_ and _stb_). Fixed D/IMMU cache-inhibit attr.
|
// Speed optimizations (removed duplicate _cyc_ and _stb_). Fixed D/IMMU cache-inhibit attr.
|
//
|
//
|
// Revision 1.4 2002/01/28 01:16:00 lampret
|
// Revision 1.4 2002/01/28 01:16:00 lampret
|
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways.
|
// Changed 'void' nop-ops instead of insn[0] to use insn[16]. Debug unit stalls the tick timer. Prepared new flag generation for add and and insns. Blocked DC/IC while they are turned off. Fixed I/D MMU SPRs layout except WAYs. TODO: smart IC invalidate, l.j 2 and TLB ways.
|
Line 92... |
Line 95... |
//
|
//
|
|
|
module or1200_du(
|
module or1200_du(
|
// RISC Internal Interface
|
// RISC Internal Interface
|
clk, rst,
|
clk, rst,
|
dcpu_cycstb_i, dcpu_we_i,
|
dcpu_cycstb_i, dcpu_we_i, icpu_cycstb_i,
|
icpu_cycstb_i, ex_freeze, branch_op, ex_insn, du_dsr,
|
ex_freeze, branch_op, ex_insn,
|
du_stall, du_addr, du_dat_i, du_dat_o, du_read, du_write, du_except,
|
spr_dat_npc, rf_dataw,
|
|
du_dsr, du_stall, du_addr, du_dat_i, du_dat_o,
|
|
du_read, du_write, du_except,
|
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
|
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
|
|
|
// External Debug Interface
|
// External Debug Interface
|
dbg_stall_i, dbg_dat_i, dbg_adr_i, dbg_op_i, dbg_ewt_i,
|
dbg_stall_i, dbg_dat_i, dbg_adr_i, dbg_op_i, dbg_ewt_i,
|
dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o, dbg_dat_o
|
dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o, dbg_dat_o
|
Line 120... |
Line 125... |
input dcpu_we_i; // LSU status
|
input dcpu_we_i; // LSU status
|
input [`OR1200_FETCHOP_WIDTH-1:0] icpu_cycstb_i; // IFETCH unit status
|
input [`OR1200_FETCHOP_WIDTH-1:0] icpu_cycstb_i; // IFETCH unit status
|
input ex_freeze; // EX stage freeze
|
input ex_freeze; // EX stage freeze
|
input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; // Branch op
|
input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op; // Branch op
|
input [dw-1:0] ex_insn; // EX insn
|
input [dw-1:0] ex_insn; // EX insn
|
|
input [31:0] spr_dat_npc; // Next PC (for trace)
|
|
input [31:0] rf_dataw; // ALU result (for trace)
|
output [`OR1200_DU_DSR_WIDTH-1:0] du_dsr; // DSR
|
output [`OR1200_DU_DSR_WIDTH-1:0] du_dsr; // DSR
|
output du_stall; // Debug Unit Stall
|
output du_stall; // Debug Unit Stall
|
output [aw-1:0] du_addr; // Debug Unit Address
|
output [aw-1:0] du_addr; // Debug Unit Address
|
input [dw-1:0] du_dat_i; // Debug Unit Data In
|
input [dw-1:0] du_dat_i; // Debug Unit Data In
|
output [dw-1:0] du_dat_o; // Debug Unit Data Out
|
output [dw-1:0] du_dat_o; // Debug Unit Data Out
|
Line 154... |
Line 161... |
//
|
//
|
// Some connections go directly from the CPU through DU to Debug I/F
|
// Some connections go directly from the CPU through DU to Debug I/F
|
//
|
//
|
`ifdef OR1200_DU_STATUS_UNIMPLEMENTED
|
`ifdef OR1200_DU_STATUS_UNIMPLEMENTED
|
assign dbg_lss_o = 4'b0000;
|
assign dbg_lss_o = 4'b0000;
|
|
|
|
reg [1:0] dbg_is_o;
|
|
//
|
|
// Show insn activity (temp, must be removed)
|
|
//
|
|
always @(posedge clk or posedge rst)
|
|
if (rst)
|
|
dbg_is_o <= #1 2'b00;
|
|
else if (!ex_freeze &
|
|
~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]))
|
|
dbg_is_o <= #1 ~dbg_is_o;
|
|
`ifdef UNUSED
|
assign dbg_is_o = 2'b00;
|
assign dbg_is_o = 2'b00;
|
|
`endif
|
`else
|
`else
|
assign dbg_lss_o = dcpu_cycstb_i ? {dcpu_we_i, 3'b000} : 4'b0000;
|
assign dbg_lss_o = dcpu_cycstb_i ? {dcpu_we_i, 3'b000} : 4'b0000;
|
assign dbg_is_o = {1'b0, icpu_cycstb_i};
|
assign dbg_is_o = {1'b0, icpu_cycstb_i};
|
`endif
|
`endif
|
assign dbg_wp_o = 11'b000_0000_0000;
|
assign dbg_wp_o = 11'b000_0000_0000;
|
Line 218... |
Line 238... |
reg dbg_bp_r;
|
reg dbg_bp_r;
|
`ifdef OR1200_DU_READREGS
|
`ifdef OR1200_DU_READREGS
|
reg [31:0] spr_dat_o;
|
reg [31:0] spr_dat_o;
|
`endif
|
`endif
|
reg [13:0] except_stop; // Exceptions that stop because of DSR
|
reg [13:0] except_stop; // Exceptions that stop because of DSR
|
|
`ifdef OR1200_DU_TB_IMPLEMENTED
|
|
wire tb_enw;
|
|
reg [7:0] tb_wadr;
|
|
reg [31:0] tb_timstmp;
|
|
`endif
|
|
wire [31:0] tbia_dat_o;
|
|
wire [31:0] tbim_dat_o;
|
|
wire [31:0] tbar_dat_o;
|
|
wire [31:0] tbts_dat_o;
|
|
|
//
|
//
|
// DU registers address decoder
|
// DU registers address decoder
|
//
|
//
|
`ifdef OR1200_DU_DMR1
|
`ifdef OR1200_DU_DMR1
|
assign dmr1_sel = (spr_cs && (spr_addr[`OR1200_SPR_OFS_BITS] == `OR1200_DU_OFS_DMR1));
|
assign dmr1_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_OFS_DMR1));
|
`endif
|
`endif
|
`ifdef OR1200_DU_DSR
|
`ifdef OR1200_DU_DSR
|
assign dsr_sel = (spr_cs && (spr_addr[`OR1200_SPR_OFS_BITS] == `OR1200_DU_OFS_DSR));
|
assign dsr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_OFS_DSR));
|
`endif
|
`endif
|
`ifdef OR1200_DU_DRR
|
`ifdef OR1200_DU_DRR
|
assign drr_sel = (spr_cs && (spr_addr[`OR1200_SPR_OFS_BITS] == `OR1200_DU_OFS_DRR));
|
assign drr_sel = (spr_cs && (spr_addr[`OR1200_DUOFS_BITS] == `OR1200_DU_OFS_DRR));
|
`endif
|
`endif
|
|
|
//
|
//
|
// Decode started exception
|
// Decode started exception
|
//
|
//
|
Line 351... |
Line 380... |
|
|
//
|
//
|
// Read DU registers
|
// Read DU registers
|
//
|
//
|
`ifdef OR1200_DU_READREGS
|
`ifdef OR1200_DU_READREGS
|
always @(spr_addr or dsr or drr or dmr1 or dmr2)
|
always @(spr_addr or dsr or drr or dmr1 or dmr2 or
|
case (spr_addr[`OR1200_SPR_OFS_BITS])
|
tbia_dat_o or tbim_dat_o or tbar_dat_o or tb_wadr)
|
|
casex (spr_addr[`OR1200_DUOFS_BITS]) // synopsys parallel_case
|
`ifdef OR1200_DU_DMR1
|
`ifdef OR1200_DU_DMR1
|
`OR1200_DU_OFS_DMR1:
|
`OR1200_DU_OFS_DMR1:
|
spr_dat_o = {8'b0, dmr1, 22'b0};
|
spr_dat_o = {8'b0, dmr1, 22'b0};
|
`endif
|
`endif
|
`ifdef OR1200_DU_DMR2
|
`ifdef OR1200_DU_DMR2
|
Line 369... |
Line 399... |
`endif
|
`endif
|
`ifdef OR1200_DU_DRR
|
`ifdef OR1200_DU_DRR
|
`OR1200_DU_OFS_DRR:
|
`OR1200_DU_OFS_DRR:
|
spr_dat_o = {18'b0, drr};
|
spr_dat_o = {18'b0, drr};
|
`endif
|
`endif
|
|
`ifdef OR1200_DU_TB_IMPLEMENTED
|
|
`OR1200_DU_OFS_TBADR:
|
|
spr_dat_o = {24'h000000, tb_wadr};
|
|
`OR1200_DU_OFS_TBIA:
|
|
spr_dat_o = tbia_dat_o;
|
|
`OR1200_DU_OFS_TBIM:
|
|
spr_dat_o = tbim_dat_o;
|
|
`OR1200_DU_OFS_TBAR:
|
|
spr_dat_o = tbar_dat_o;
|
|
`OR1200_DU_OFS_TBTS:
|
|
spr_dat_o = tbts_dat_o;
|
|
`endif
|
default:
|
default:
|
spr_dat_o = 32'h0000_0000;
|
spr_dat_o = 32'h0000_0000;
|
endcase
|
endcase
|
`endif
|
`endif
|
|
|
//
|
//
|
// DSR alias
|
// DSR alias
|
//
|
//
|
assign du_dsr = dsr;
|
assign du_dsr = dsr;
|
|
|
|
`ifdef OR1200_DU_TB_IMPLEMENTED
|
|
//
|
|
// Simple trace buffer
|
|
// (right now hardcoded for Xilinx Virtex FPGAs)
|
|
//
|
|
// Stores last 256 instruction addresses, instruction
|
|
// machine words and ALU results
|
|
//
|
|
|
|
//
|
|
// Trace buffer write enable
|
|
//
|
|
assign tb_enw = ~ex_freeze & ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]);
|
|
|
|
//
|
|
// Trace buffer write address pointer
|
|
//
|
|
always @(posedge clk or posedge rst)
|
|
if (rst)
|
|
tb_wadr <= #1 8'h00;
|
|
else if (tb_enw)
|
|
tb_wadr <= #1 tb_wadr + 8'd1;
|
|
|
|
//
|
|
// Free running counter (time stamp)
|
|
//
|
|
always @(posedge clk or posedge rst)
|
|
if (rst)
|
|
tb_timstmp <= #1 32'h00000000;
|
|
else if (!dbg_bp_r)
|
|
tb_timstmp <= #1 tb_timstmp + 32'd1;
|
|
|
|
//
|
|
// Trace buffer RAMs
|
|
//
|
|
RAMB4_S16_S16 tbia_ramb4_s16_0(
|
|
.CLKA(clk),
|
|
.RSTA(rst),
|
|
.ADDRA(tb_wadr),
|
|
.DIA(spr_dat_npc[15:0]),
|
|
.ENA(1'b1),
|
|
.WEA(tb_enw),
|
|
.DOA(),
|
|
|
|
.CLKB(clk),
|
|
.RSTB(rst),
|
|
.ADDRB(spr_addr[7:0]),
|
|
.DIB(16'h0000),
|
|
.ENB(1'b1),
|
|
.WEB(1'b0),
|
|
.DOB(tbia_dat_o[15:0])
|
|
);
|
|
|
|
RAMB4_S16_S16 tbia_ramb4_s16_1(
|
|
.CLKA(clk),
|
|
.RSTA(rst),
|
|
.ADDRA(tb_wadr),
|
|
.DIA(spr_dat_npc[31:16]),
|
|
.ENA(1'b1),
|
|
.WEA(tb_enw),
|
|
.DOA(),
|
|
|
|
.CLKB(clk),
|
|
.RSTB(rst),
|
|
.ADDRB(spr_addr[7:0]),
|
|
.DIB(16'h0000),
|
|
.ENB(1'b1),
|
|
.WEB(1'b0),
|
|
.DOB(tbia_dat_o[31:16])
|
|
);
|
|
|
|
RAMB4_S16_S16 tbim_ramb4_s16_0(
|
|
.CLKA(clk),
|
|
.RSTA(rst),
|
|
.ADDRA(tb_wadr),
|
|
.DIA(ex_insn[15:0]),
|
|
.ENA(1'b1),
|
|
.WEA(tb_enw),
|
|
.DOA(),
|
|
|
|
.CLKB(clk),
|
|
.RSTB(rst),
|
|
.ADDRB(spr_addr[7:0]),
|
|
.DIB(16'h0000),
|
|
.ENB(1'b1),
|
|
.WEB(1'b0),
|
|
.DOB(tbim_dat_o[15:0])
|
|
);
|
|
|
|
RAMB4_S16_S16 tbim_ramb4_s16_1(
|
|
.CLKA(clk),
|
|
.RSTA(rst),
|
|
.ADDRA(tb_wadr),
|
|
.DIA(ex_insn[31:16]),
|
|
.ENA(1'b1),
|
|
.WEA(tb_enw),
|
|
.DOA(),
|
|
|
|
.CLKB(clk),
|
|
.RSTB(rst),
|
|
.ADDRB(spr_addr[7:0]),
|
|
.DIB(16'h0000),
|
|
.ENB(1'b1),
|
|
.WEB(1'b0),
|
|
.DOB(tbim_dat_o[31:16])
|
|
);
|
|
|
|
RAMB4_S16_S16 tbar_ramb4_s16_0(
|
|
.CLKA(clk),
|
|
.RSTA(rst),
|
|
.ADDRA(tb_wadr),
|
|
.DIA(rf_dataw[15:0]),
|
|
.ENA(1'b1),
|
|
.WEA(tb_enw),
|
|
.DOA(),
|
|
|
|
.CLKB(clk),
|
|
.RSTB(rst),
|
|
.ADDRB(spr_addr[7:0]),
|
|
.DIB(16'h0000),
|
|
.ENB(1'b1),
|
|
.WEB(1'b0),
|
|
.DOB(tbar_dat_o[15:0])
|
|
);
|
|
|
|
RAMB4_S16_S16 tbar_ramb4_s16_1(
|
|
.CLKA(clk),
|
|
.RSTA(rst),
|
|
.ADDRA(tb_wadr),
|
|
.DIA(rf_dataw[31:16]),
|
|
.ENA(1'b1),
|
|
.WEA(tb_enw),
|
|
.DOA(),
|
|
|
|
.CLKB(clk),
|
|
.RSTB(rst),
|
|
.ADDRB(spr_addr[7:0]),
|
|
.DIB(16'h0000),
|
|
.ENB(1'b1),
|
|
.WEB(1'b0),
|
|
.DOB(tbar_dat_o[31:16])
|
|
);
|
|
|
|
RAMB4_S16_S16 tbts_ramb4_s16_0(
|
|
.CLKA(clk),
|
|
.RSTA(rst),
|
|
.ADDRA(tb_wadr),
|
|
.DIA(tb_timstmp[15:0]),
|
|
.ENA(1'b1),
|
|
.WEA(tb_enw),
|
|
.DOA(),
|
|
|
|
.CLKB(clk),
|
|
.RSTB(rst),
|
|
.ADDRB(spr_addr[7:0]),
|
|
.DIB(16'h0000),
|
|
.ENB(1'b1),
|
|
.WEB(1'b0),
|
|
.DOB(tbts_dat_o[15:0])
|
|
);
|
|
|
|
RAMB4_S16_S16 tbts_ramb4_s16_1(
|
|
.CLKA(clk),
|
|
.RSTA(rst),
|
|
.ADDRA(tb_wadr),
|
|
.DIA(tb_timstmp[31:16]),
|
|
.ENA(1'b1),
|
|
.WEA(tb_enw),
|
|
.DOA(),
|
|
|
|
.CLKB(clk),
|
|
.RSTB(rst),
|
|
.ADDRB(spr_addr[7:0]),
|
|
.DIB(16'h0000),
|
|
.ENB(1'b1),
|
|
.WEB(1'b0),
|
|
.DOB(tbts_dat_o[31:16])
|
|
);
|
|
|
`else
|
`else
|
|
assign tbia_dat_o = 32'h0000_0000;
|
|
assign tbim_dat_o = 32'h0000_0000;
|
|
assign tbar_dat_o = 32'h0000_0000;
|
|
assign tbts_dat_o = 32'h0000_0000;
|
|
|
|
`endif // OR1200_DU_TB_IMPLEMENTED
|
|
|
|
`else // OR1200_DU_IMPLEMENTED
|
|
|
//
|
//
|
// When DU is not implemented, drive all outputs as would when DU is disabled
|
// When DU is not implemented, drive all outputs as would when DU is disabled
|
//
|
//
|
assign dbg_bp_o = 1'b0;
|
assign dbg_bp_o = 1'b0;
|