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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 204 to Rev 205
    Reverse comparison

Rev 204 → Rev 205

/trunk/or1200/rtl/verilog/frz_logic.v
71,7 → 71,8
clk, rst,
 
// Internal i/f
multicycle, except_flushpipe, lsu_stall, if_stall, dclsu_unstall, branch_stall, force_dslot_fetch, pipeline_freeze
multicycle, except_flushpipe, lsu_stall, if_stall, dclsu_unstall, branch_stall, force_dslot_fetch,
if_freeze, id_freeze, ex_freeze, wb_freeze
);
 
//
86,7 → 87,10
input dclsu_unstall;
input branch_stall;
input force_dslot_fetch;
output pipeline_freeze;
output if_freeze;
output id_freeze;
output ex_freeze;
output wb_freeze;
 
//
// Internal wires and regs
100,7 → 104,10
//
// Pipeline freeze
//
assign pipeline_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze) & ~except_flushpipe;
assign if_freeze = id_freeze;
assign id_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze | force_dslot_fetch) & ~except_flushpipe;
assign ex_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze) & ~except_flushpipe;
assign wb_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze) & ~except_flushpipe;
 
//
// Freeze FSM1
135,7 → 142,7
else
case (state2) // synopsys full_case parallel_case
`NO_FREEZE :
if (done_once && pipeline_freeze)
if (done_once && ex_freeze)
done_once <= #1 1'b1;
else if (multicycle) begin
state2 <= #1 `FREEZE_BYMULTICYCLE;
/trunk/or1200/rtl/verilog/dc_tag.v
62,10 → 62,10
clk, rst,
 
// Internal i/f
addr, en, we, datain, dataout
addr, en, we, datain, tag_v, tag
);
 
parameter dw = 19;
parameter dw = 20;
parameter aw = 9;
 
//
77,7 → 77,8
input en;
input we;
input [dw-1:0] datain;
output [dw-1:0] dataout;
output tag_v;
output [dw-2:0] tag;
 
`ifdef OR1200_NO_DC
 
84,7 → 85,8
//
// Data cache not implemented
//
assign dataout = {dw{1'b0}};
assign tag = {dw{1'b0}};
assign tag_v = 1'b0;
 
`else
 
91,7 → 93,7
//
// Instantiation of TAG RAM block
//
generic_spram_512x19 dc_tag0(
generic_spram_512x20 dc_tag0(
.clk(clk),
.rst(rst),
.ce(en),
99,7 → 101,7
.oe(1'b1),
.addr(addr),
.di(datain),
.do(dataout)
.do({tag_v, tag})
);
 
`endif
/trunk/or1200/rtl/verilog/or1200.v
75,8 → 75,9
dwb_clk_i, dwb_rst_i, dwb_ack_i, dwb_err_i, dwb_rty_i, dwb_dat_i,
dwb_cyc_o, dwb_adr_o, dwb_stb_o, dwb_we_o, dwb_sel_o, dwb_dat_o,
 
// Trace
tp_dir_in, tp_sel, tp_in, tp_out,
// External Debug Interface
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,
// Power Management
pm_clksd, pm_cpustall, pm_dc_gate, pm_ic_gate, pm_dmmu_gate,
133,6 → 134,20
output [dw-1:0] dwb_dat_o; // output data bus
 
//
// External Debug Interface
//
input dbg_stall_i; // External Stall Input
input [dw-1:0] dbg_dat_i; // External Data Input
input [aw-1:0] dbg_adr_i; // External Address Input
input [2:0] dbg_op_i; // External Operation Select Input
input dbg_ewt_i; // External Watchpoint Trigger Input
output [3:0] dbg_lss_o; // External Load/Store Unit Status
output [1:0] dbg_is_o; // External Insn Fetch Status
output [10:0] dbg_wp_o; // Watchpoints Outputs
output dbg_bp_o; // Breakpoint Output
output [dw-1:0] dbg_dat_o; // External Data Output
 
//
// Power Management
//
input pm_cpustall;
146,6 → 161,7
output pm_wakeup;
output pm_lvolt;
 
 
//
// Internal wires and regs
//
246,14 → 262,6
wire tt_int;
 
//
// CPU and external Trace port
//
input tp_dir_in;
input [1:0] tp_sel;
input [dw-1:0] tp_in;
output [dw-1:0] tp_out;
 
//
// Trace port and caches/MMUs
//
wire [`TP2W_WIDTH-1:0] tp2w;
365,15 → 373,18
.icfetch_stall(icfetch_stall),
.ic_en(ic_en),
 
// SPR access
.spr_cs(spr_cs[`SPR_GROUP_IC]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
 
// These connect IC to BIU
.icbiu_rdy(icbiu_rdy),
.icbiu_datain(icbiu_from_biu),
.icbiu_addr(icbiu_addr),
.icbiu_read(icbiu_read),
.icbiu_sel(icbiu_sel),
 
// These connect IC to SPRS
.spr_dat_i(spr_dat_cpu)
.icbiu_sel(icbiu_sel)
);
 
//
391,10 → 402,10
.ic_en(ic_en),
 
// Connection CPU to external Trace port
.tp_dir_in(tp_dir_in),
.tp_sel(tp_sel),
.tp_in(tp_in),
.tp_out(tp_out),
.tp_dir_in(1'b0),
.tp_sel(2'b00),
.tp_in(32'h00000000),
.tp_out(),
 
// Connection IMMU and CPU internally
.immu_en(immu_en),
482,6 → 493,12
.dclsu_unstall(dclsu_unstall),
.dc_en(dc_en),
 
// SPR access
.spr_cs(spr_cs[`SPR_GROUP_DC]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
 
// These connect DC to BIU
.dcbiu_rdy(dcbiu_rdy),
.dcbiu_datain(dcbiu_from_biu),
496,6 → 513,44
);
 
//
// Instantiation of Debug Unit
//
du du(
// RISC Internal Interface
.clk(clk),
.rst(rst),
.dclsu_lsuop(dclsu_lsuop),
.icfetch_op(icfetch_op),
 
// DU's access to SPR unit
.du_stall(),
.du_addr(),
.du_dat_i(32'h00000000),
.du_dat_o(),
.du_read(),
.du_write(),
 
// Access to DU's SPRs
.spr_cs(spr_cs[`SPR_GROUP_DU]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
.spr_dat_o(),
 
// External Debug Interface
.dbg_stall_i(dbg_stall_i),
.dbg_dat_i(dbg_dat_i),
.dbg_adr_i(dbg_adr_i),
.dbg_op_i(dbg_op_i),
.dbg_ewt_i(dbg_ewt_i),
.dbg_lss_o(dbg_lss_o),
.dbg_is_o(dbg_is_o),
.dbg_wp_o(dbg_wp_o),
.dbg_bp_o(dbg_bp_o),
.dbg_dat_o(dbg_dat_o)
);
 
//
// Programmable interrupt controller
//
pic pic(
/trunk/or1200/rtl/verilog/ic.v
67,8 → 67,11
clk, rst, clkdiv_by_2,
 
// Internal i/f to fetcher
ic_en, icfetch_dataout, icfetch_addr, icfetch_op, icfetch_stall, spr_dat_i,
ic_en, icfetch_dataout, icfetch_addr, icfetch_op, icfetch_stall,
 
// SPRs
spr_cs, spr_write, spr_addr, spr_dat_i,
 
// External i/f to BIU
icbiu_rdy, icbiu_addr, icbiu_read, icbiu_datain, icbiu_sel
);
103,11 → 106,19
input [31:0] icfetch_addr;
input [`FETCHOP_WIDTH-1:0] icfetch_op;
output icfetch_stall;
input [dw-1:0] spr_dat_i;
 
//
// SPR access
//
input spr_cs;
input spr_write;
input [31:0] spr_addr;
input [31:0] spr_dat_i;
 
//
// Internal wires and regs
//
wire tag_v;
wire [18:0] tag;
wire [dw-1:0] to_icram;
wire [dw-1:0] from_icram;
128,12 → 139,20
wire [`FETCHOP_WIDTH-1:0] icfsm_op;
wire icfsm_read;
reg [1:0] bypass_wait;
wire [`ICINDXH:4] ictag_addr;
wire ictag_en;
wire ictag_v;
wire ic_inv;
 
//
// Simple assignments
//
assign ic_inv = spr_cs & spr_write;
assign icbiu_addr = ic_addr;
assign ictag_we = refill;
assign ictag_we = refill | ic_inv;
assign ictag_addr = ic_inv ? spr_dat_i[`ICINDXH:4] : ic_addr[`ICINDXH:4];
assign ictag_en = ic_inv | ic_en;
assign ictag_v = ~ic_inv;
 
//
// Bypass of IC when it is disabled
187,7 → 206,7
// Tag comparison
//
always @(tag or saved_addr) begin
if (tag == saved_addr[31:`ICTAGL])
if ((tag == saved_addr[31:`ICTAGL]) && tag_v)
hit <= #1 1'b1;
else
hit <= #1 1'b0;
254,11 → 273,12
ic_tag ic_tag(
.clk(clk),
.rst(rst),
.addr(ic_addr[`ICINDXH:4]),
.en(ic_en),
.addr(ictag_addr[`ICINDXH:4]),
.en(ictag_en),
.we(ictag_we),
.datain(ic_addr[31:`ICTAGL]),
.dataout(tag)
.datain({ic_addr[31:`ICTAGL], ictag_v}),
.tag_v(tag_v),
.tag(tag)
);
 
endmodule
/trunk/or1200/rtl/verilog/id.v
60,7 → 60,7
clk, rst,
 
// Internal i/f
pipeline_freeze, except_flushpipe, if_insn, branch_op,
id_freeze, ex_freeze, wb_freeze, except_flushpipe, if_insn, branch_op,
rf_addra, rf_addrb, alu_op, shrot_op, comp_op, rf_addrw, rfwb_op,
wb_insn, simm, branch_addrofs, lsu_addrofs, sel_a, sel_b, lsu_op,
multicycle, spr_addrimm, wbforw_valid, sig_syscall,
72,7 → 72,9
//
input clk;
input rst;
input pipeline_freeze;
input id_freeze;
input ex_freeze;
input wb_freeze;
input except_flushpipe;
input [31:0] if_insn;
output [`BRANCHOP_WIDTH-1:0] branch_op;
178,7 → 180,9
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
spr_addrimm <= #1 16'h0000;
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze)
spr_addrimm <= #1 16'h0000;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
// l.mtspr
`OR32_MTSPR:
299,7 → 303,9
always @(posedge clk or posedge rst) begin
if (rst)
rf_addrw <= #1 5'd0;
else if (!pipeline_freeze)
else if (!ex_freeze & id_freeze)
rf_addrw <= #1 5'd00;
else if (!ex_freeze)
case (pre_branch_op) // synopsys parallel_case full_case
`BRANCHOP_JR, `BRANCHOP_BAL:
rf_addrw <= #1 5'd09; // link register r9
314,7 → 320,7
always @(posedge clk or posedge rst) begin
if (rst)
wb_rfaddrw <= #1 5'd0;
else if (!pipeline_freeze)
else if (!wb_freeze)
wb_rfaddrw <= #1 rf_addrw;
end
 
326,7 → 332,7
id_insn[31:26] <= #1 `OR32_NOP;
id_insn[25:0] <= #1 26'd0;
end
else if (!pipeline_freeze) begin
else if (!id_freeze) begin
id_insn <= #1 if_insn;
`ifdef OR1200_VERBOSE
// synopsys translate_off
344,7 → 350,9
ex_insn[31:26] <= #1 `OR32_NOP;
ex_insn[25:0] <= #1 26'd0;
end
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze)
ex_insn <= #1 {`OR32_NOP, 26'h000_4444};
else if (!ex_freeze) begin
ex_insn <= #1 id_insn;
`ifdef OR1200_VERBOSE
// synopsys translate_off
362,7 → 370,7
wb_insn[31:26] <= #1 `OR32_NOP;
wb_insn[25:0] <= #1 26'd0;
end
else if (!pipeline_freeze) begin
else if (!wb_freeze) begin
wb_insn <= #1 ex_insn;
end
end
373,7 → 381,7
always @(posedge clk or posedge rst) begin
if (rst)
sel_imm <= #1 1'b0;
else if (!pipeline_freeze) begin
else if (!id_freeze) begin
case (if_insn[31:26]) // synopsys full_case parallel_case
 
// j.jalr
441,7 → 449,9
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
alu_op <= #1 `ALUOP_NOP;
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze)
alu_op <= #1 `ALUOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
// l.j
589,7 → 599,9
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
shrot_op <= #1 `SHROTOP_NOP;
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze)
shrot_op <= #1 `SHROTOP_NOP;
else if (!ex_freeze) begin
shrot_op <= #1 id_insn[`SHROTOP_POS];
end
end
600,7 → 612,9
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
rfwb_op <= #1 `RFWBOP_NOP;
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze)
rfwb_op <= #1 `RFWBOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
 
// j.jal
690,7 → 704,7
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
pre_branch_op <= #1 `BRANCHOP_NOP;
else if (!pipeline_freeze) begin
else if (!id_freeze) begin
case (if_insn[31:26]) // synopsys full_case parallel_case
// l.j
735,7 → 749,9
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
branch_op <= #1 `BRANCHOP_NOP;
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze)
branch_op <= #1 `BRANCHOP_NOP;
else if (!ex_freeze) begin
branch_op <= #1 pre_branch_op;
end
end
746,7 → 762,9
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
lsu_op <= #1 `LSUOP_NOP;
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze)
lsu_op <= #1 `LSUOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
// l.lwz
795,7 → 813,9
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
comp_op <= #1 4'd0;
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze)
comp_op <= #1 4'd0;
else if (!ex_freeze) begin
comp_op <= #1 id_insn[24:21];
end
end
806,7 → 826,7
always @(posedge clk or posedge rst) begin
if (rst)
sig_syscall <= #1 1'b0;
else if (!pipeline_freeze) begin
else if (!wb_freeze) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
if (wb_insn[31:24] == {`OR32_XSYNC, 2'b00})
/trunk/or1200/rtl/verilog/operandmuxes.v
62,7 → 62,7
clk, rst,
 
// Internal i/f
pipeline_freeze, rf_dataa, rf_datab, ex_forw, wb_forw,
ex_freeze, rf_dataa, rf_datab, ex_forw, wb_forw,
simm, sel_a, sel_b, operand_a, operand_b, muxed_b
);
 
73,7 → 73,7
//
input clk;
input rst;
input pipeline_freeze;
input ex_freeze;
input [width-1:0] rf_dataa;
input [width-1:0] rf_datab;
input [width-1:0] ex_forw;
99,7 → 99,7
always @(posedge clk or posedge rst) begin
if (rst)
operand_a <= #1 32'd0;
else if (!pipeline_freeze)
else if (!ex_freeze)
operand_a <= #1 muxed_a;
end
 
109,7 → 109,7
always @(posedge clk or posedge rst) begin
if (rst)
operand_b <= #1 32'd0;
else if (!pipeline_freeze)
else if (!ex_freeze)
operand_b <= #1 muxed_b;
end
 
/trunk/or1200/rtl/verilog/defines.v
61,24 → 61,27
//
//
 
`define XILINX_RAMB4
`define XILINX_RAM32X1D
//`define ARTISAN_SSP
//`define XILINX_RAMB4
//`define XILINX_RAM32X1D
`define ARTISAN_SSP
//`define ARTISAN_SDP
//`define ARTISAN_STP
 
// Dump VCD
//`define VCD_DUMP
`define VCD_DUMP
 
// Verbose
`define OR1200_VERBOSE
 
//
// Data cache not implemented
//
`define OR1200_NO_DC
//`define OR1200_NO_DC
 
//
// Insn cache not implemented
//
`define OR1200_NO_IC
//`define OR1200_NO_IC
 
//
// Register OR1200 outputs
411,14 → 414,17
// SPRS
`define SPR_GROUP_BITS 31:27
`define SPR_GROUP_WIDTH 5
`define SPR_GROUP_SYS 5'd0
`define SPR_GROUP_PM 5'd8
`define SPR_GROUP_PIC 5'd9
`define SPR_GROUP_TT 5'd10
`define SPR_GROUP_IMMU 5'd28
`define SPR_GROUP_SYS 5'd00
`define SPR_GROUP_IMMU 5'd01
`define SPR_GROUP_DMMU 5'd02
`define SPR_GROUP_DC 5'd03
`define SPR_GROUP_IC 5'd04
`define SPR_GROUP_DU 5'd06
`define SPR_GROUP_PM 5'd08
`define SPR_GROUP_PIC 5'd09
`define SPR_GROUP_TT 5'd10
`define SPR_GROUP_MODA 5'd29
`define SPR_GROUP_MODD 5'd30
`define SPR_GROUP_DMMU 5'd31
 
`define SPR_CFGR 3'd0
`define SPR_SR 7'd16
463,6 → 469,26
// `define PM_UNUSED_ZERO
 
//
// Debug Unit
//
 
// Define it if you want DU implemented
//`define DU_IMPLEMENTED
 
// Define if DU registers can be read/written at any address inside DU group
`define DU_PARTIAL_DECODING
 
// Define if reading DU regs is allowed
`define DU_READREGS
 
// Define if unused DU registers bits should be zero
// `define DU_UNUSED_ZERO
 
// DU operation commands
`define DU_OP_READSPR 3'd4
`define DU_OP_WRITESPR 3'd5
 
//
// Programmable Interrupt Controller
//
 
/trunk/or1200/rtl/verilog/ic_tag.v
62,10 → 62,10
clk, rst,
 
// Internal i/f
addr, en, we, datain, dataout
addr, en, we, datain, tag_v, tag
);
 
parameter dw = 19;
parameter dw = 20;
parameter aw = 9;
 
//
85,7 → 85,8
input en;
input we;
input [dw-1:0] datain;
output [dw-1:0] dataout;
output tag_v;
output [dw-2:0] tag;
 
`ifdef OR1200_NO_IC
 
92,14 → 93,14
//
// Insn cache not implemented
//
assign dataout = {dw{1'b0}};
 
assign tag = {dw{1'b0}};
assign tag_v = 1'b0;
`else
 
//
// Instantiation of TAG RAM block
//
generic_spram_512x19 ic_tag0(
generic_spram_512x20 ic_tag0(
.clk(clk),
.rst(rst),
.ce(en),
107,7 → 108,7
.oe(1'b1),
.addr(addr),
.di(datain),
.do(dataout)
.do({tag, tag_v})
);
 
`endif
/trunk/or1200/rtl/verilog/dc.v
77,6 → 77,9
// Internal i/f
dc_en, dclsu_addr, dclsu_lsuop, dclsu_datain, dclsu_dataout, dclsu_stall, dclsu_unstall,
 
// SPRs
spr_cs, spr_write, spr_addr, spr_dat_i,
 
// Trace
tp2w
);
117,6 → 120,14
output dclsu_unstall;
 
//
// SPR access
//
input spr_cs;
input spr_write;
input [31:0] spr_addr;
input [31:0] spr_dat_i;
 
//
// Trace
//
input [`TP2W_WIDTH-1:0] tp2w;
124,6 → 135,7
//
// Internal wires and regs
//
wire tag_v;
wire [18:0] tag;
wire [dw-1:0] to_dcram;
wire [dw-1:0] from_dcram;
149,13 → 161,21
wire queue;
wire cntrbusy;
wire dcbiu_valid;
wire [12:4] dctag_addr;
wire dctag_en;
wire dctag_v;
wire dc_inv;
 
//
// Simple assignments
//
assign dcbiu_addr = dc_addr;
assign dctag_we = refill;
assign dclsu_unstall = dcbiu_rdy;
assign dc_inv = spr_cs & spr_write;
assign dctag_we = refill | dc_inv;
assign dctag_addr = dc_inv ? spr_dat_i[12:4] : dc_addr[12:4];
assign dctag_en = dc_inv | dc_en;
assign dctag_v = ~dc_inv;
 
//
// Data to BIU is from DCRAM when DC is enabled or from LSU when
234,7 → 254,7
// Tag comparison
//
always @(tag or saved_addr) begin
if (tag == saved_addr[31:13])
if ((tag == saved_addr[31:13]) && tag_v)
hit <= #1 1'b1;
else
hit <= #1 1'b0;
312,11 → 332,12
dc_tag dc_tag(
.clk(clk),
.rst(rst),
.addr(dc_addr[12:4]),
.en(dc_en),
.addr(dctag_addr),
.en(dctag_en),
.we(dctag_we),
.datain(dc_addr[31:13]),
.dataout(tag)
.datain({dc_addr[31:13], dctag_v}),
.tag_v(tag_v),
.tag(tag)
);
 
//
/trunk/or1200/rtl/verilog/cpu.v
181,7 → 181,10
wire [`COMPOP_WIDTH-1:0] comp_op;
wire [`BRANCHOP_WIDTH-1:0] branch_op;
wire [`LSUOP_WIDTH-1:0] lsu_op;
wire pipeline_freeze;
wire if_freeze;
wire id_freeze;
wire ex_freeze;
wire wb_freeze;
wire [`SEL_WIDTH-1:0] sel_a;
wire [`SEL_WIDTH-1:0] sel_b;
wire [`RFWBOP_WIDTH-1:0] rfwb_op;
272,7 → 275,9
.sig_immufault(immuexcept_fault),
.sig_intlow(int_low),
.branch_taken(branch_taken),
.pipeline_freeze(pipeline_freeze),
.id_freeze(id_freeze),
.ex_freeze(ex_freeze),
.wb_freeze(wb_freeze),
.if_stall(if_stall),
.if_pc(if_pc),
.lr_sav(lr_sav),
306,7 → 311,7
.ic_fetchop(ic_fetchop),
.tp_insn(tp_insn),
.tp_wr_insn(tp_wr_insn),
.pipeline_freeze(pipeline_freeze),
.if_freeze(id_freeze),
.if_insn(insn),
.if_pc(if_pc),
.branch_op(branch_op),
329,7 → 334,9
id id(
.clk(clk),
.rst(rst),
.pipeline_freeze(pipeline_freeze),
.id_freeze(id_freeze),
.ex_freeze(ex_freeze),
.wb_freeze(wb_freeze),
.except_flushpipe(except_flushpipe),
.if_insn(insn),
.branch_op(branch_op),
360,7 → 367,7
wbmux wbmux(
.clk(clk),
.rst(rst),
.pipeline_freeze(pipeline_freeze),
.wb_freeze(wb_freeze),
.rfwb_op(rfwb_op),
.muxin_a(alu_dataout),
.muxin_b(lsu_dataout),
379,7 → 386,7
.rst(rst),
.addrw(rf_addrw),
.dataw(rf_dataw),
.pipeline_freeze(pipeline_freeze),
.id_freeze(id_freeze),
.we(rfwb_op[0]),
.addra(rf_addra),
.dataa(rf_dataa),
398,7 → 405,7
operandmuxes operandmuxes(
.clk(clk),
.rst(rst),
.pipeline_freeze(pipeline_freeze),
.ex_freeze(ex_freeze),
.rf_dataa(rf_dataa),
.rf_datab(rf_datab),
.ex_forw(rf_dataw),
494,7 → 501,10
.dclsu_unstall(dclsu_unstall),
.branch_stall(branch_stall),
.force_dslot_fetch(force_dslot_fetch),
.pipeline_freeze(pipeline_freeze)
.if_freeze(if_freeze),
.id_freeze(id_freeze),
.ex_freeze(ex_freeze),
.wb_freeze(wb_freeze)
);
 
//
/trunk/or1200/rtl/verilog/except.v
73,7 → 73,7
 
// Internal i/f
sig_dtlbmiss, sig_dmmufault, sig_inthigh, sig_syscall, sig_itlbmiss,
sig_immufault, sig_intlow, branch_taken, pipeline_freeze, if_stall,
sig_immufault, sig_intlow, branch_taken, id_freeze, ex_freeze, wb_freeze, if_stall,
if_pc, lr_sav, except_flushpipe, except_type, except_start,
except_started, wb_pc, datain, epcr_we, eear_we, esr_we, epcr, eear,
esr, sr, lsu_addr
92,7 → 92,9
input sig_immufault;
input sig_intlow;
input branch_taken;
input pipeline_freeze;
input id_freeze;
input ex_freeze;
input wb_freeze;
input if_stall;
input [31:0] if_pc;
output [31:2] lr_sav;
142,27 → 144,46
//
always @(posedge clk or posedge rst) begin
if (rst) begin
id_pc <= #1 32'd0;
id_exceptflags <= #1 3'b0;
end
else if (!id_freeze) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: id_pc <= %h", $time, if_pc);
// synopsys translate_on
`endif
id_pc <= #1 if_pc;
id_exceptflags <= #1 { sig_itlbmiss, sig_immufault, sig_intlow & sr[`SR_EXR]};
end
end
 
//
// PC and Exception flags pipelines
//
always @(posedge clk or posedge rst) begin
if (rst) begin
ex_dslot <= #1 1'b0;
id_pc <= #1 32'd0;
ex_pc <= #1 32'd0;
wb_pc <= #1 32'd0;
id_exceptflags <= #1 3'b0;
ex_exceptflags <= #1 3'b0;
delayed1_ex_dslot <= #1 1'b0;
delayed2_ex_dslot <= #1 1'b0;
end
else if (!pipeline_freeze) begin
else if (!ex_freeze & id_freeze) begin
ex_dslot <= #1 1'b0;
ex_pc <= #1 id_pc;
ex_exceptflags <= #1 3'b000;
delayed1_ex_dslot <= #1 ex_dslot;
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
end
else if (!ex_freeze) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: id_pc <= %h", $time, if_pc);
$display("%t: ex_pc <= %h", $time, id_pc);
// synopsys translate_on
`endif
ex_dslot <= #1 branch_taken;
id_pc <= #1 if_pc;
ex_pc <= #1 id_pc;
wb_pc <= #1 ex_pc;
id_exceptflags <= #1 { sig_itlbmiss, sig_immufault, sig_intlow & sr[`SR_EXR]};
ex_exceptflags <= #1 id_exceptflags;
delayed1_ex_dslot <= #1 ex_dslot;
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
169,13 → 190,26
end
end
 
 
//
// PC and Exception flags pipelines
//
always @(posedge clk or posedge rst) begin
if (rst) begin
wb_pc <= #1 32'd0;
end
else if (!wb_freeze) begin
wb_pc <= #1 ex_pc;
end
end
 
//
// We have started execution of exception handler:
// 1. Asserted for 3 clock cycles
// 2. Don't execute any instruction that is still in pipeline and is not part of exception handler
//
assign except_flushpipe = (sr[`SR_EXR] && (sig_dtlbmiss || sig_dmmufault || sig_inthigh || sig_syscall || ex_exceptflags)
|| extend_flush) ? 1'b1 : 1'b0;
assign except_flushpipe = (sr[`SR_EXR] & (sig_dtlbmiss | sig_dmmufault | sig_inthigh | sig_syscall | ex_exceptflags)
| extend_flush);
 
//
// Exception FSM that sequences execution of exception handler
260,7 → 294,7
esr <= #1 datain;
end
`EXCEPTFSM_FLU1:
if (!if_stall && !pipeline_freeze)
if (!if_stall && !id_freeze)
begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
/trunk/or1200/rtl/verilog/ifetch.v
62,7 → 62,7
ic_insn, ic_addr, ic_stall, ic_fetchop, tp_insn, tp_wr_insn,
 
// Internal i/f
pipeline_freeze, if_insn, if_pc, branch_op, except_type,
if_freeze, if_insn, if_pc, branch_op, except_type,
branch_addrofs, lr_restor, flag, taken, binsn_addr, except_start,
epcr, force_dslot_fetch, if_stall, branch_stall
);
90,7 → 90,7
//
// Internal i/f
//
input pipeline_freeze;
input if_freeze;
output [31:0] if_insn;
output [31:0] if_pc;
input [`BRANCHOP_WIDTH-1:0] branch_op;
252,7 → 252,7
always @(posedge clk or posedge rst) begin
if (rst)
pcreg <= #1 30'd64;
else if (!pipeline_freeze && !ic_stall) begin
else if (!if_freeze && !ic_stall) begin
pcreg <= #1 ic_addr[31:2];
`ifdef OR1200_VERBOSE
// synopsys translate_off
269,7 → 269,7
if (rst) begin
if_saved <= #1 33'b0;
end
else if (pipeline_freeze && !if_saved[32] && !ic_stall) begin // && !taken
else if (if_freeze && !if_saved[32] && !ic_stall) begin // && !taken
if_saved <= #1 {1'b1, ic_tp_insn};
`ifdef OR1200_VERBOSE
// synopsys translate_off
277,7 → 277,7
// synopsys translate_on
`endif
end
else if (!pipeline_freeze) begin
else if (!if_freeze) begin
if_saved[32] <= #1 1'b0;
if_saved[31:0] <= #1 32'h1500eeee;
`ifdef OR1200_VERBOSE
294,10 → 294,10
if (rst) begin
pc_saved <= #1 32'b0;
end
else if (pipeline_freeze && !if_saved[32] && !ic_stall) begin // && !taken
else if (if_freeze && !if_saved[32] && !ic_stall) begin // && !taken
pc_saved <= #1 ic_addr;
end
else if (!pipeline_freeze) begin
else if (!if_freeze) begin
pc_saved <= #1 32'h00000000;
end
 
/trunk/or1200/rtl/verilog/wbmux.v
62,7 → 62,7
clk, rst,
 
// Internal i/f
pipeline_freeze, rfwb_op,
wb_freeze, rfwb_op,
muxin_a, muxin_b, muxin_c, muxin_d,
muxout, muxreg, muxreg_valid
);
82,7 → 82,7
//
// Internal i/f
//
input pipeline_freeze;
input wb_freeze;
input [`RFWBOP_WIDTH-1:0] rfwb_op;
input [width-1:0] muxin_a;
input [width-1:0] muxin_b;
107,7 → 107,7
muxreg <= #1 32'd0;
muxreg_valid <= #1 1'b0;
end
else if (!pipeline_freeze) begin
else if (!wb_freeze) begin
muxreg <= #1 muxout;
muxreg_valid <= #1 rfwb_op[0];
end
/trunk/or1200/rtl/verilog/rf.v
68,7 → 68,7
addrw, dataw, we,
 
// Read i/f
pipeline_freeze, addra, addrb, dataa, datab,
id_freeze, addra, addrb, dataa, datab,
 
// Debug
rfa_tqa, rfb_tqa, rfa_tmuxed, rfb_tmuxed, tp1w
97,7 → 97,7
//
// Read i/f
//
input pipeline_freeze;
input id_freeze;
input [aw-1:0] addra;
input [aw-1:0] addrb;
output [dw-1:0] dataa;
149,11 → 149,11
if (rst) begin
dataa_saved <= #1 33'b0;
end
else if (pipeline_freeze & !dataa_saved[32]) begin
else if (id_freeze & !dataa_saved[32]) begin
dataa_saved <= #1 {1'b1, from_rfa};
end
else if (!pipeline_freeze)
dataa_saved[32] <= #1 1'b0;
else if (!id_freeze)
dataa_saved <= #1 33'b0;
 
//
// Stores operand from RF_B into temp reg when pipeline is frozen
162,11 → 162,11
if (rst) begin
datab_saved <= #1 33'b0;
end
else if (pipeline_freeze & !datab_saved[32]) begin
else if (id_freeze & !datab_saved[32]) begin
datab_saved <= #1 {1'b1, from_rfb};
end
else if (!pipeline_freeze)
datab_saved[32] <= #1 1'b0;
else if (!id_freeze)
datab_saved <= #1 33'b0;
 
//
// Instantiation of register file two-port RAM A
/trunk/or1200/rtl/verilog/du.v
0,0 → 1,228
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Debug Unit ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Basic OR1200 debug unit. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// 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 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source 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 Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
//
// Debug unit
//
 
module du(
// RISC Internal Interface
clk, rst,
du_stall, du_addr, du_dat_i, du_dat_o, du_read, du_write,
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
dclsu_lsuop, icfetch_op,
 
// External Debug Interface
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
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// RISC Internal Interface
//
input clk; // Clock
input rst; // Reset
output du_stall; // Debug Unit Stall
output [aw-1:0] du_addr; // Debug Unit Address
input [dw-1:0] du_dat_i; // Debug Unit Data In
output [dw-1:0] du_dat_o; // Debug Unit Data Out
output du_read; // Debug Unit Read Enable
output du_write; // Debug Unit Write Enable
input spr_cs; // SPR Chip Select
input spr_write; // SPR Read/Write
input [aw-1:0] spr_addr; // SPR Address
input [dw-1:0] spr_dat_i; // SPR Data Input
output [dw-1:0] spr_dat_o; // SPR Data Output
input [`LSUOP_WIDTH-1:0] dclsu_lsuop; // LSU status
input [`FETCHOP_WIDTH-1:0] icfetch_op; // IFETCH unit status
 
//
// External Debug Interface
//
input dbg_stall_i; // External Stall Input
input [dw-1:0] dbg_dat_i; // External Data Input
input [aw-1:0] dbg_adr_i; // External Address Input
input [2:0] dbg_op_i; // External Operation Select Input
input dbg_ewt_i; // External Watchpoint Trigger Input
output [3:0] dbg_lss_o; // External Load/Store Unit Status
output [1:0] dbg_is_o; // External Insn Fetch Status
output [10:0] dbg_wp_o; // Watchpoints Outputs
output dbg_bp_o; // Breakpoint Output
output [dw-1:0] dbg_dat_o; // External Data Output
 
//
// Some connections go directly from the CPU through DU to Debug I/F
//
assign dbg_lss_o = dclsu_lsuop;
assign dbg_is_o = icfetch_op;
 
//
// Some connections go directly from Debug I/F through DU to the CPU
//
assign du_stall = dbg_stall_i;
 
`ifdef DU_IMPLEMENTED
 
//
// Power Management Register bits
//
reg [3:0] sdf; // Slow-down factor
reg dme; // Doze Mode Enable
reg sme; // Sleep Mode Enable
reg dcge; // Dynamic Clock Gating Enable
 
//
// Internal wires
//
wire pmr_sel; // PMR select
wire pmr_we; // PMR write
 
//
// PMR address decoder (partial decoder)
//
`ifdef DU_PARTIAL_DECODING
assign pmr_sel = (spr_addr[`SPRGRP_BITS] == `SPRGRP_PM) ? 1'b1 : 1'b0;
`else
assign pmr_sel = ((spr_addr[`SPRGRP_BITS] == `SPRGRP_PM) &&
(spr_addr[`SPROFS_BITS] == `PM_OFS_PMR)) ? 1'b1 : 1'b0;
`endif
 
//
// Write to PMR and also PMR[DME]/PMR[SME] reset when
// pic_wakeup is asserted
//
always @(posedge clk or posedge rst)
if (rst)
{dcge, sme, dme, sdf} <= 7'b0;
else if (pmr_sel && pmr_we) begin
sdf <= #1 spr_dat_i[`PM_PMR_SDF];
dme <= #1 spr_dat_i[`PM_PMR_DME];
sme <= #1 spr_dat_i[`PM_PMR_SME];
dcge <= #1 spr_dat_i[`PM_PMR_DCGE];
end
else if (pic_wakeup) begin
dme <= #1 1'b0;
sme <= #1 1'b0;
end
 
//
// Read PMR
//
`ifdef DU_READREGS
assign spr_dat_o[`PM_PMR_SDF] = sdf;
assign spr_dat_o[`PM_PMR_DME] = dme;
assign spr_dat_o[`PM_PMR_SME] = sme;
assign spr_dat_o[`PM_PMR_DCGE] = dcge;
`ifdef DU_UNUSED_ZERO
assign spr_dat_o[`PM_PMR_UNUSED] = 25'b0;
`endif
`endif
 
//
// Generate pm_clksd
//
assign pm_clksd = sdf;
 
//
// Statically generate all clock gate outputs
// TODO: add dynamic clock gating feature
//
assign pm_cpu_gate = (dme | sme) & ~pic_wakeup;
assign pm_dc_gate = pm_cpu_gate;
assign pm_ic_gate = pm_cpu_gate;
assign pm_dmmu_gate = pm_cpu_gate;
assign pm_immu_gate = pm_cpu_gate;
assign pm_tt_gate = sme & ~pic_wakeup;
 
//
// Assert pm_wakeup when pic_wakeup is asserted
//
assign pm_wakeup = pic_wakeup;
 
//
// Assert pm_lvolt when pm_cpu_gate or pm_cpustall are asserted
//
assign pm_lvolt = pm_cpu_gate | pm_cpustall;
 
`else
 
//
// When DU is not implemented, drive all outputs as would when DU is disabled
//
assign dbg_wp_o = 11'b000_0000_0000;
assign dbg_bp_o = 1'b0;
assign dbg_dat_o = du_dat_i;
assign du_addr = dbg_adr_i;
assign du_dat_o = dbg_dat_i;
assign du_read = (dbg_op_i == `DU_OP_READSPR);
assign du_write = (dbg_op_i == `DU_OP_WRITESPR);
 
//
// Read PMR
//
`ifdef DU_READREGS
assign spr_dat_o = 32'b0;
`ifdef DU_UNUSED_ZERO
`endif
`endif
 
`endif
 
endmodule

powered by: WebSVN 2.1.0

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