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 |