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

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/or1200
    from Rev 10 to Rev 141
    Reverse comparison

Rev 10 → Rev 141

/rtl/verilog/or1200_du.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_du.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.12 2005/10/19 11:37:56 jcastillo
// Added support for RAMB16 Xilinx4/Spartan3 primitives
//
// Revision 1.11 2005/01/07 09:35:08 andreje
// du_hwbkpt disabled when debug unit not implemented
//
128,8 → 135,8
dcpu_dat_dc, icpu_cycstb_i,
ex_freeze, branch_op, ex_insn, id_pc,
spr_dat_npc, rf_dataw,
du_dsr, du_stall, du_addr, du_dat_i, du_dat_o,
du_read, du_write, du_except, du_hwbkpt,
du_dsr, du_dmr1, du_stall, du_addr, du_dat_i, du_dat_o,
du_read, du_write, du_except_stop, du_hwbkpt,
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
 
// External Debug Interface
162,6 → 169,7
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 [24: 0] du_dmr1;
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
168,7 → 176,7
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 [12:0] du_except; // Exception masked by DSR
input [12:0] du_except_stop; // Exception masked by DSR
output du_hwbkpt; // Cause trap exception (HW Breakpoints)
input spr_cs; // SPR Chip Select
input spr_write; // SPR Read/Write
191,6 → 199,8
input [dw-1:0] dbg_dat_i; // External Data Input
output [dw-1:0] dbg_dat_o; // External Data Output
output dbg_ack_o; // External Data Acknowledge (not WB compatible)
reg [dw-1:0] dbg_dat_o; // External Data Output
reg dbg_ack_o; // External Data Acknowledge (not WB compatible)
 
 
//
206,8 → 216,7
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]))
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;
217,7 → 226,6
assign dbg_is_o = {1'b0, icpu_cycstb_i};
`endif
assign dbg_wp_o = 11'b000_0000_0000;
assign dbg_dat_o = du_dat_i;
 
//
// Some connections go directly from Debug I/F through DU to the CPU
228,16 → 236,27
assign du_read = dbg_stb_i && !dbg_we_i;
assign du_write = dbg_stb_i && dbg_we_i;
 
reg dbg_ack;
//
// Generate acknowledge -- just delay stb signal
//
reg dbg_ack_o;
always @(posedge clk or posedge rst)
if (rst)
always @(posedge clk or posedge rst) begin
if (rst) begin
dbg_ack <= #1 1'b0;
dbg_ack_o <= #1 1'b0;
else
dbg_ack_o <= #1 dbg_stb_i;
end
else begin
dbg_ack <= #1 dbg_stb_i; // valid when du_dat_i
dbg_ack_o <= #1 dbg_ack & dbg_stb_i; // valid when dbg_dat_o
end
end
 
//
// Register data output
//
always @(posedge clk)
dbg_dat_o <= #1 du_dat_i;
 
`ifdef OR1200_DU_IMPLEMENTED
 
//
248,6 → 267,7
`else
wire [24:0] dmr1; // DMR1 not implemented
`endif
assign du_dmr1 = dmr1;
 
//
// Debug Mode Register 2
496,6 → 516,7
reg [10:0] wp;
`endif
wire du_hwbkpt;
reg du_hwbkpt_hold;
`ifdef OR1200_DU_READREGS
reg [31:0] spr_dat_o;
`endif
583,11 → 604,12
//
// Decode started exception
//
always @(du_except) begin
always @(du_except_stop) begin
except_stop = 14'b0000_0000_0000;
casex (du_except)
13'b1_xxxx_xxxx_xxxx:
casex (du_except_stop)
13'b1_xxxx_xxxx_xxxx: begin
except_stop[`OR1200_DU_DRR_TTE] = 1'b1;
end
13'b0_1xxx_xxxx_xxxx: begin
except_stop[`OR1200_DU_DRR_IE] = 1'b1;
end
594,13 → 616,15
13'b0_01xx_xxxx_xxxx: begin
except_stop[`OR1200_DU_DRR_IME] = 1'b1;
end
13'b0_001x_xxxx_xxxx:
13'b0_001x_xxxx_xxxx: begin
except_stop[`OR1200_DU_DRR_IPFE] = 1'b1;
end
13'b0_0001_xxxx_xxxx: begin
except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1;
end
13'b0_0000_1xxx_xxxx:
13'b0_0000_1xxx_xxxx: begin
except_stop[`OR1200_DU_DRR_IIE] = 1'b1;
end
13'b0_0000_01xx_xxxx: begin
except_stop[`OR1200_DU_DRR_AE] = 1'b1;
end
607,10 → 631,12
13'b0_0000_001x_xxxx: begin
except_stop[`OR1200_DU_DRR_DME] = 1'b1;
end
13'b0_0000_0001_xxxx:
13'b0_0000_0001_xxxx: begin
except_stop[`OR1200_DU_DRR_DPFE] = 1'b1;
13'b0_0000_0000_1xxx:
end
13'b0_0000_0000_1xxx: begin
except_stop[`OR1200_DU_DRR_BUSEE] = 1'b1;
end
13'b0_0000_0000_01xx: begin
except_stop[`OR1200_DU_DRR_RE] = 1'b1;
end
617,8 → 643,9
13'b0_0000_0000_001x: begin
except_stop[`OR1200_DU_DRR_TE] = 1'b1;
end
13'b0_0000_0000_0001:
13'b0_0000_0000_0001: begin
except_stop[`OR1200_DU_DRR_SCE] = 1'b1;
end
default:
except_stop = 14'b0000_0000_0000;
endcase
641,7 → 668,7
| ~((ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16]) & dmr1[`OR1200_DU_DMR1_ST]
`endif
`ifdef OR1200_DU_DMR1_BT
| (branch_op != `OR1200_BRANCHOP_NOP) & dmr1[`OR1200_DU_DMR1_BT]
| (branch_op != `OR1200_BRANCHOP_NOP) & (branch_op != `OR1200_BRANCHOP_RFE) & dmr1[`OR1200_DU_DMR1_BT]
`endif
;
else
1105,23 → 1132,23
4'b1_000,
4'b1_111: match0 = 1'b0;
4'b1_001: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) ==
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} ==
{(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
4'b1_010: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) <
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} <
{(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
4'b1_011: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) <=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} <=
{(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
4'b1_100: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) >
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} >
{(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
4'b1_101: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) >=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} >=
{(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
4'b1_110: match0 =
((match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]) !=
(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]));
({(match_cond0_ct[31] ^ dcr0[`OR1200_DU_DCR_SC]), match_cond0_ct[30:0]} !=
{(dvr0[31] ^ dcr0[`OR1200_DU_DCR_SC]), dvr0[30:0]});
endcase
 
//
1169,23 → 1196,23
4'b1_000,
4'b1_111: match1 = 1'b0;
4'b1_001: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) ==
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} ==
{(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
4'b1_010: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) <
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} <
{(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
4'b1_011: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) <=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} <=
{(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
4'b1_100: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) >
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} >
{(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
4'b1_101: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) >=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} >=
{(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
4'b1_110: match1 =
((match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]) !=
(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]));
({(match_cond1_ct[31] ^ dcr1[`OR1200_DU_DCR_SC]), match_cond1_ct[30:0]} !=
{(dvr1[31] ^ dcr1[`OR1200_DU_DCR_SC]), dvr1[30:0]});
endcase
 
//
1233,23 → 1260,23
4'b1_000,
4'b1_111: match2 = 1'b0;
4'b1_001: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) ==
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} ==
{(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
4'b1_010: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) <
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} <
{(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
4'b1_011: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) <=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} <=
{(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
4'b1_100: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) >
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} >
{(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
4'b1_101: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) >=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} >=
{(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
4'b1_110: match2 =
((match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]) !=
(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]));
({(match_cond2_ct[31] ^ dcr2[`OR1200_DU_DCR_SC]), match_cond2_ct[30:0]} !=
{(dvr2[31] ^ dcr2[`OR1200_DU_DCR_SC]), dvr2[30:0]});
endcase
 
//
1297,23 → 1324,23
4'b1_000,
4'b1_111: match3 = 1'b0;
4'b1_001: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) ==
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} ==
{(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
4'b1_010: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) <
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} <
{(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
4'b1_011: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) <=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} <=
{(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
4'b1_100: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) >
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} >
{(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
4'b1_101: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) >=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} >=
{(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
4'b1_110: match3 =
((match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]) !=
(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]));
({(match_cond3_ct[31] ^ dcr3[`OR1200_DU_DCR_SC]), match_cond3_ct[30:0]} !=
{(dvr3[31] ^ dcr3[`OR1200_DU_DCR_SC]), dvr3[30:0]});
endcase
 
//
1361,23 → 1388,23
4'b1_000,
4'b1_111: match4 = 1'b0;
4'b1_001: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) ==
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} ==
{(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
4'b1_010: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) <
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} <
{(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
4'b1_011: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) <=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} <=
{(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
4'b1_100: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) >
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} >
{(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
4'b1_101: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) >=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} >=
{(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
4'b1_110: match4 =
((match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]) !=
(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]));
({(match_cond4_ct[31] ^ dcr4[`OR1200_DU_DCR_SC]), match_cond4_ct[30:0]} !=
{(dvr4[31] ^ dcr4[`OR1200_DU_DCR_SC]), dvr4[30:0]});
endcase
 
//
1425,23 → 1452,23
4'b1_000,
4'b1_111: match5 = 1'b0;
4'b1_001: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) ==
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} ==
{(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
4'b1_010: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) <
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} <
{(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
4'b1_011: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) <=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} <=
{(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
4'b1_100: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) >
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} >
{(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
4'b1_101: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) >=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} >=
{(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
4'b1_110: match5 =
((match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]) !=
(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]));
({(match_cond5_ct[31] ^ dcr5[`OR1200_DU_DCR_SC]), match_cond5_ct[30:0]} !=
{(dvr5[31] ^ dcr5[`OR1200_DU_DCR_SC]), dvr5[30:0]});
endcase
 
//
1489,23 → 1516,23
4'b1_000,
4'b1_111: match6 = 1'b0;
4'b1_001: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) ==
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} ==
{(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
4'b1_010: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) <
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} <
{(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
4'b1_011: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) <=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} <=
{(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
4'b1_100: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) >
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} >
{(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
4'b1_101: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) >=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} >=
{(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
4'b1_110: match6 =
((match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]) !=
(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]));
({(match_cond6_ct[31] ^ dcr6[`OR1200_DU_DCR_SC]), match_cond6_ct[30:0]} !=
{(dvr6[31] ^ dcr6[`OR1200_DU_DCR_SC]), dvr6[30:0]});
endcase
 
//
1553,23 → 1580,23
4'b1_000,
4'b1_111: match7 = 1'b0;
4'b1_001: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) ==
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} ==
{(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
4'b1_010: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) <
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} <
{(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
4'b1_011: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) <=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} <=
{(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
4'b1_100: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) >
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} >
{(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
4'b1_101: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) >=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} >=
{(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
4'b1_110: match7 =
((match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]) !=
(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]));
({(match_cond7_ct[31] ^ dcr7[`OR1200_DU_DCR_SC]), match_cond7_ct[30:0]} !=
{(dvr7[31] ^ dcr7[`OR1200_DU_DCR_SC]), dvr7[30:0]});
endcase
 
//
1660,11 → 1687,20
// Watchpoints can cause trap exception
//
`ifdef OR1200_DU_HWBKPTS
assign du_hwbkpt = |(wp & dmr2[`OR1200_DU_DMR2_WGB]);
assign du_hwbkpt = |(wp & dmr2[`OR1200_DU_DMR2_WGB]) | du_hwbkpt_hold | (dbg_bp_r & ~dsr[`OR1200_DU_DSR_TE]);
`else
assign du_hwbkpt = 1'b0;
`endif
 
// Hold du_hwbkpt if ex_freeze is active in order to cause trap exception
always @(posedge clk or posedge rst)
if (rst)
du_hwbkpt_hold <= #1 1'b0;
else if (du_hwbkpt & ex_freeze)
du_hwbkpt_hold <= #1 1'b1;
else if (!ex_freeze)
du_hwbkpt_hold <= #1 1'b0;
 
`ifdef OR1200_DU_TB_IMPLEMENTED
//
// Simple trace buffer
1703,7 → 1739,7
 
or1200_dpram_256x32 tbia_ram(
.clk_a(clk),
.rst_a(rst),
.rst_a(1'b0),
.addr_a(spr_addr[7:0]),
.ce_a(1'b1),
.oe_a(1'b1),
1710,7 → 1746,7
.do_a(tbia_dat_o),
 
.clk_b(clk),
.rst_b(rst),
.rst_b(1'b0),
.addr_b(tb_wadr),
.di_b(spr_dat_npc),
.ce_b(1'b1),
1720,7 → 1756,7
 
or1200_dpram_256x32 tbim_ram(
.clk_a(clk),
.rst_a(rst),
.rst_a(1'b0),
.addr_a(spr_addr[7:0]),
.ce_a(1'b1),
.oe_a(1'b1),
1727,7 → 1763,7
.do_a(tbim_dat_o),
.clk_b(clk),
.rst_b(rst),
.rst_b(1'b0),
.addr_b(tb_wadr),
.di_b(ex_insn),
.ce_b(1'b1),
1736,7 → 1772,7
 
or1200_dpram_256x32 tbar_ram(
.clk_a(clk),
.rst_a(rst),
.rst_a(1'b0),
.addr_a(spr_addr[7:0]),
.ce_a(1'b1),
.oe_a(1'b1),
1743,7 → 1779,7
.do_a(tbar_dat_o),
.clk_b(clk),
.rst_b(rst),
.rst_b(1'b0),
.addr_b(tb_wadr),
.di_b(rf_dataw),
.ce_b(1'b1),
1752,7 → 1788,7
 
or1200_dpram_256x32 tbts_ram(
.clk_a(clk),
.rst_a(rst),
.rst_a(1'b0),
.addr_a(spr_addr[7:0]),
.ce_a(1'b1),
.oe_a(1'b1),
1759,7 → 1795,7
.do_a(tbts_dat_o),
 
.clk_b(clk),
.rst_b(rst),
.rst_b(1'b0),
.addr_b(tb_wadr),
.di_b(tb_timstmp),
.ce_b(1'b1),
1782,6 → 1818,7
//
assign dbg_bp_o = 1'b0;
assign du_dsr = {`OR1200_DU_DSR_WIDTH{1'b0}};
assign du_dmr1 = {25{1'b0}};
assign du_hwbkpt = 1'b0;
 
//
/rtl/verilog/or1200_pm.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_pm.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
// Revision 1.8 2001/10/21 17:57:16 lampret
// Removed params from generic_XX.v. Added translate_off/on in sprs.v and id.v. Removed spr_addr from dc.v and ic.v. Fixed CR+LF.
//
/rtl/verilog/or1200_ic_top.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_ic_top.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.9 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.7.4.2 2003/12/09 11:46:48 simons
// Mbist nameing changed, Artisan ram instance signal names fixed, some synthesis waning fixed.
//
/rtl/verilog/or1200_defines.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_defines.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Defines added, bugs fixed.
//
// Revision 1.45 2006/04/09 01:32:29 lampret
// See OR1200_MAC_SHIFTBY in or1200_defines.v for explanation of the change. Since now no more 28 bits shift for l.macrc insns however for backward compatbility it is possible to set arbitry number of shifts.
//
// Revision 1.44 2005/10/19 11:37:56 jcastillo
// Added support for RAMB16 Xilinx4/Spartan3 primitives
//
325,6 → 332,7
//`define OR1200_XILINX_RAMB4
//`define OR1200_XILINX_RAM32X1D
//`define OR1200_USE_RAM16X1D_FOR_RAM32X1D
`define OR1200_ACTEL
 
//
// Do not implement Data cache
334,17 → 342,17
//
// Do not implement Insn cache
//
`define OR1200_NO_IC
//`define OR1200_NO_IC
 
//
// Do not implement Data MMU
//
`define OR1200_NO_DMMU
//`define OR1200_NO_DMMU
 
//
// Do not implement Insn MMU
//
`define OR1200_NO_IMMU
//`define OR1200_NO_IMMU
 
//
// Select between ASIC and generic multiplier
359,8 → 367,8
// (consider available FPGA memory resources)
//
//`define OR1200_IC_1W_512B
`define OR1200_IC_1W_4KB
//`define OR1200_IC_1W_8KB
//`define OR1200_IC_1W_4KB
`define OR1200_IC_1W_8KB
`define OR1200_DC_1W_4KB
//`define OR1200_DC_1W_8KB
 
424,7 → 432,7
//
// To remove *wb_cab_o ports undefine this macro.
//
`define OR1200_WB_CAB
//`define OR1200_WB_CAB
 
//
// WISHBONE B3 compatible interface
436,9 → 444,14
// To enable *wb_cti_o/*wb_bte_o ports,
// define this macro.
//
//`define OR1200_WB_B3
`define OR1200_WB_B3
 
//
// LOG all WISHBONE accesses
//
`define OR1200_LOG_WB_ACCESS
 
//
// Enable additional synthesis directives if using
// _Synopsys_ synthesis tool
//
483,18 → 496,29
// If you don't use them, then disable implementation
// to save area.
//
`define OR1200_IMPL_ADDC
//`define OR1200_IMPL_ADDC
 
//
// Implement l.sub instruction
//
// By default implementation of l.sub instructions
// is enabled to be compliant with the simulator.
// If you don't use carry bit, then disable
// implementation to save area.
//
`define OR1200_IMPL_SUB
 
//
// Implement carry bit SR[CY]
//
//
// By default implementation of SR[CY] is enabled
// to be compliant with the simulator. However
// SR[CY] is explicitly only used by l.addc/l.addic
// instructions and if these two insns are not
// to be compliant with the simulator. However SR[CY]
// is explicitly only used by l.addc/l.addic/l.sub
// instructions and if these three insns are not
// implemented there is not much point having SR[CY].
//
`define OR1200_IMPL_CY
//`define OR1200_IMPL_CY
 
//
// Implement optional l.div/l.divu instructions
537,7 → 561,7
//
// By default multiplier is implemented
//
`define OR1200_MULT_IMPLEMENTED
//`define OR1200_MULT_IMPLEMENTED
 
//
// Implement multiply-and-accumulate
546,7 → 570,7
// implement MAC, multiplier needs to be
// implemented.
//
`define OR1200_MAC_IMPLEMENTED
//`define OR1200_MAC_IMPLEMENTED
 
//
// Low power, slower multiplier
571,7 → 595,7
// For WB:RISC 1:4, 1:2 or 1:1, enable both defines and use
// clmode to set ratio
//
`define OR1200_CLKDIV_2_SUPPORTED
//`define OR1200_CLKDIV_2_SUPPORTED
//`define OR1200_CLKDIV_4_SUPPORTED
 
//
581,10 → 605,15
//`define OR1200_RFRAM_TWOPORT
//
// Memory macro dual port (see or1200_dpram_32x32.v)
//`define OR1200_RFRAM_DUALPORT
`define OR1200_RFRAM_DUALPORT
 
//
// Generic (flip-flop based) register file (see or1200_rfram_generic.v)
`define OR1200_RFRAM_GENERIC
//`define OR1200_RFRAM_GENERIC
// Generic register file supports - 16 registers
`ifdef OR1200_RFRAM_GENERIC
// `define OR1200_RFRAM_16REG
`endif
 
//
// Type of mem2reg aligner to implement.
620,15 → 649,15
`define OR1200_ALUOP_COMP 4'd13
`define OR1200_ALUOP_MTSR 4'd14
`define OR1200_ALUOP_MFSR 4'd15
`define OR1200_ALUOP_CMOV 4'd14
`define OR1200_ALUOP_FF1 4'd15
`define OR1200_ALUOP_CMOV 4'd14
`define OR1200_ALUOP_FF1 4'd15
//
// MACOPs
//
`define OR1200_MACOP_WIDTH 2
`define OR1200_MACOP_NOP 2'b00
`define OR1200_MACOP_MAC 2'b01
`define OR1200_MACOP_MSB 2'b10
`define OR1200_MACOP_WIDTH 3
`define OR1200_MACOP_NOP 3'b000
`define OR1200_MACOP_MAC 3'b001
`define OR1200_MACOP_MSB 3'b010
 
//
// Shift/rotate ops
678,12 → 707,18
`define OR1200_LSUOP_LHS 4'b0101
`define OR1200_LSUOP_LWZ 4'b0110
`define OR1200_LSUOP_LWS 4'b0111
`define OR1200_LSUOP_LD 4'b0001
`define OR1200_LSUOP_SD 4'b1000
`define OR1200_LSUOP_SB 4'b1010
`define OR1200_LSUOP_SH 4'b1100
`define OR1200_LSUOP_SW 4'b1110
`define OR1200_LSUOP_LD 4'b0001
`define OR1200_LSUOP_SD 4'b1000
`define OR1200_LSUOP_SB 4'b1010
`define OR1200_LSUOP_SH 4'b1100
`define OR1200_LSUOP_SW 4'b1110
 
// Number of bits of load/store EA precalculated in ID stage
// for balancing ID and EX stages.
//
// Valid range: 2,3,...,30,31
`define OR1200_LSUEA_PRECALC 2
 
// FETCHOPs
`define OR1200_FETCHOP_WIDTH 1
`define OR1200_FETCHOP_NOP 1'b0
812,9 → 847,9
//
// Sum of these two defines needs to be 28
//
`define OR1200_EXCEPT_EPH0_P 20'h00000
`define OR1200_EXCEPT_EPH1_P 20'hF0000
`define OR1200_EXCEPT_V 8'h00
`define OR1200_EXCEPT_EPH0_P 20'h00000
`define OR1200_EXCEPT_EPH1_P 20'hF0000
`define OR1200_EXCEPT_V 8'h00
 
//
// N part width
892,7 → 927,7
//
// SR bits
//
`define OR1200_SR_WIDTH 16
`define OR1200_SR_WIDTH 17
`define OR1200_SR_SM 0
`define OR1200_SR_TEE 1
`define OR1200_SR_IEE 2
909,6 → 944,7
`define OR1200_SR_DSX 13 // Unused
`define OR1200_SR_EPH 14
`define OR1200_SR_FO 15
`define OR1200_SR_TED 16
`define OR1200_SR_CID 31:28 // Unimplemented
 
//
930,7 → 966,7
//
 
// Define it if you want PM implemented
`define OR1200_PM_IMPLEMENTED
//`define OR1200_PM_IMPLEMENTED
 
// Bit positions inside PMR (don't change)
`define OR1200_PM_PMR_SDF 3:0
974,11 → 1010,15
//`define OR1200_DU_HWBKPTS
 
// Number of DVR/DCR pairs if HW breakpoints enabled
// Comment / uncomment DU_DVRn / DU_DCRn pairs bellow according to this number !
// DU_DVR0..DU_DVR7 should be uncommented for 8 DU_DVRDCR_PAIRS
`define OR1200_DU_DVRDCR_PAIRS 8
 
// Define if you want trace buffer
// (for now only available for Xilinx Virtex FPGAs)
//`define OR1200_DU_TB_IMPLEMENTED
 
 
//
// Address offsets of DU registers inside DU group
//
1105,7 → 1145,7
`define OR1200_PIC_IMPLEMENTED
 
// Define number of interrupt inputs (2-31)
`define OR1200_PIC_INTS 20
`define OR1200_PIC_INTS 31
 
// Address offsets of PIC registers inside PIC group
`define OR1200_PIC_OFS_PICMR 2'd0
1433,7 → 1473,7
// memory in the system). IC/DC are sitting behind QMEM so the
// whole design timing might be worse with QMEM implemented.
//
`define OR1200_QMEM_IMPLEMENTED
//`define OR1200_QMEM_IMPLEMENTED
 
//
// Base address and mask of QMEM
1449,9 → 1489,9
// at higher addresses in reserved space.
//
`define OR1200_QMEM_IADDR 32'h0080_0000
`define OR1200_QMEM_IMASK 32'hfff0_0000 // Max QMEM size 1MB
`define OR1200_QMEM_DADDR 32'h0080_0000
`define OR1200_QMEM_DMASK 32'hfff0_0000 // Max QMEM size 1MB
`define OR1200_QMEM_IMASK 32'hfff0_0000 // Max QMEM size 1MB
`define OR1200_QMEM_DADDR 32'h0080_0000
`define OR1200_QMEM_DMASK 32'hfff0_0000 // Max QMEM size 1MB
 
//
// QMEM interface byte-select capability
1555,17 → 1595,17
`define OR1200_UPR_DUP 1'b0
`endif
`define OR1200_UPR_PCUP 1'b0 // Performance counters not present
`ifdef OR1200_DU_IMPLEMENTED
`ifdef OR1200_PM_IMPLEMENTED
`define OR1200_UPR_PMP 1'b1
`else
`define OR1200_UPR_PMP 1'b0
`endif
`ifdef OR1200_DU_IMPLEMENTED
`ifdef OR1200_PIC_IMPLEMENTED
`define OR1200_UPR_PICP 1'b1
`else
`define OR1200_UPR_PICP 1'b0
`endif
`ifdef OR1200_DU_IMPLEMENTED
`ifdef OR1200_TT_IMPLEMENTED
`define OR1200_UPR_TTP 1'b1
`else
`define OR1200_UPR_TTP 1'b0
1575,7 → 1615,7
 
// CPUCFGR fields
`define OR1200_CPUCFGR_NSGF_BITS 3:0
`define OR1200_CPUCFGR_HGF_BITS 4
`define OR1200_CPUCFGR_HGF_BITS 4
`define OR1200_CPUCFGR_OB32S_BITS 5
`define OR1200_CPUCFGR_OB64S_BITS 6
`define OR1200_CPUCFGR_OF32S_BITS 7
1584,8 → 1624,12
`define OR1200_CPUCFGR_RES1_BITS 31:10
 
// CPUCFGR values
`define OR1200_CPUCFGR_NSGF 4'h0
`define OR1200_CPUCFGR_HGF 1'b0
`define OR1200_CPUCFGR_NSGF 4'h0
`ifdef OR1200_RFRAM_16REG
`define OR1200_CPUCFGR_HGF 1'b1
`else
`define OR1200_CPUCFGR_HGF 1'b0
`endif
`define OR1200_CPUCFGR_OB32S 1'b1
`define OR1200_CPUCFGR_OB64S 1'b0
`define OR1200_CPUCFGR_OF32S 1'b0
1674,11 → 1718,11
`define OR1200_DCCFGR_NCS 4'h0 // Irrelevant
`define OR1200_DCCFGR_CBS 1'b0 // Irrelevant
`define OR1200_DCCFGR_CWS 1'b0 // Irrelevant
`define OR1200_DCCFGR_CCRI 1'b1 // Irrelevant
`define OR1200_DCCFGR_CBIRI 1'b1 // Irrelevant
`define OR1200_DCCFGR_CCRI 1'b0 // Irrelevant
`define OR1200_DCCFGR_CBIRI 1'b0 // Irrelevant
`define OR1200_DCCFGR_CBPRI 1'b0 // Irrelevant
`define OR1200_DCCFGR_CBLRI 1'b0 // Irrelevant
`define OR1200_DCCFGR_CBFRI 1'b1 // Irrelevant
`define OR1200_DCCFGR_CBFRI 1'b0 // Irrelevant
`define OR1200_DCCFGR_CBWBRI 1'b0 // Irrelevant
`define OR1200_DCCFGR_RES1 17'h00000
`else
1736,13 → 1780,13
`endif
 
// DCFGR fields
`define OR1200_DCFGR_NDP_BITS 2:0
`define OR1200_DCFGR_WPCI_BITS 3
`define OR1200_DCFGR_RES1_BITS 31:4
`define OR1200_DCFGR_NDP_BITS 3:0
`define OR1200_DCFGR_WPCI_BITS 4
`define OR1200_DCFGR_RES1_BITS 31:5
 
// DCFGR values
`ifdef OR1200_DU_HWBKPTS
`define OR1200_DCFGR_NDP 3'h`OR1200_DU_DVRDCR_PAIRS // # of DVR/DCR pairs
`define OR1200_DCFGR_NDP 4'h`OR1200_DU_DVRDCR_PAIRS // # of DVR/DCR pairs
`ifdef OR1200_DU_DWCR0
`define OR1200_DCFGR_WPCI 1'b1
`else
1749,8 → 1793,17
`define OR1200_DCFGR_WPCI 1'b0 // WP counters not impl.
`endif
`else
`define OR1200_DCFGR_NDP 3'h0 // Zero DVR/DCR pairs
`define OR1200_DCFGR_NDP 4'h0 // Zero DVR/DCR pairs
`define OR1200_DCFGR_WPCI 1'b0 // WP counters not impl.
`endif
`define OR1200_DCFGR_RES1 28'h0000000
 
///////////////////////////////////////////////////////////////////////////////
// Boot Address Selection //
///////////////////////////////////////////////////////////////////////////////
// Boot from ROM at 0xf0000100
`define OR1200_BOOT_PCREG_DEFAULT 30'h3c00003f
`define OR1200_BOOT_ADR 32'hf0000100
// Boot from 0x100
// `define OR1200_BOOT_PCREG_DEFAULT 30'h0000003f
// `define OR1200_BOOT_ADR 32'h00000100
/rtl/verilog/or1200_iwb_biu.v
48,7 → 48,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_iwb_biu.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// This module is obsolete.
//
// Revision 1.2 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.1 2003/12/05 00:12:08 lampret
// New wb_biu for iwb interface.
//
107,410 → 114,10
// synopsys translate_on
`include "or1200_defines.v"
 
module or1200_iwb_biu(
// RISC clock, reset and clock control
clk, rst, clmode,
module or1200_iwb_biu();
 
// WISHBONE interface
wb_clk_i, wb_rst_i, wb_ack_i, wb_err_i, wb_rty_i, wb_dat_i,
wb_cyc_o, wb_adr_o, wb_stb_o, wb_we_o, wb_sel_o, wb_dat_o,
`ifdef OR1200_WB_CAB
wb_cab_o,
`endif
`ifdef OR1200_WB_B3
wb_cti_o, wb_bte_o,
`endif
// THIS MODULE IS OBSOLETE !!!
// COMPLETELY REWRITTEN or1200_wb_biu.v IS USED INSTEAD !!!
 
// Internal RISC bus
biu_dat_i, biu_adr_i, biu_cyc_i, biu_stb_i, biu_we_i, biu_sel_i, biu_cab_i,
biu_dat_o, biu_ack_o, biu_err_o
);
 
parameter dw = `OR1200_OPERAND_WIDTH;
parameter aw = `OR1200_OPERAND_WIDTH;
 
//
// RISC clock, reset and clock control
//
input clk; // RISC clock
input rst; // RISC reset
input [1:0] clmode; // 00 WB=RISC, 01 WB=RISC/2, 10 N/A, 11 WB=RISC/4
 
//
// WISHBONE interface
//
input wb_clk_i; // clock input
input wb_rst_i; // reset input
input wb_ack_i; // normal termination
input wb_err_i; // termination w/ error
input wb_rty_i; // termination w/ retry
input [dw-1:0] wb_dat_i; // input data bus
output wb_cyc_o; // cycle valid output
output [aw-1:0] wb_adr_o; // address bus outputs
output wb_stb_o; // strobe output
output wb_we_o; // indicates write transfer
output [3:0] wb_sel_o; // byte select outputs
output [dw-1:0] wb_dat_o; // output data bus
`ifdef OR1200_WB_CAB
output wb_cab_o; // consecutive address burst
`endif
`ifdef OR1200_WB_B3
output [2:0] wb_cti_o; // cycle type identifier
output [1:0] wb_bte_o; // burst type extension
`endif
 
//
// Internal RISC interface
//
input [dw-1:0] biu_dat_i; // input data bus
input [aw-1:0] biu_adr_i; // address bus
input biu_cyc_i; // WB cycle
input biu_stb_i; // WB strobe
input biu_we_i; // WB write enable
input biu_cab_i; // CAB input
input [3:0] biu_sel_i; // byte selects
output [31:0] biu_dat_o; // output data bus
output biu_ack_o; // ack output
output biu_err_o; // err output
 
//
// Registers
//
reg [1:0] valid_div; // Used for synchronization
`ifdef OR1200_REGISTERED_OUTPUTS
reg [aw-1:0] wb_adr_o; // address bus outputs
reg wb_cyc_o; // cycle output
reg wb_stb_o; // strobe output
reg wb_we_o; // indicates write transfer
reg [3:0] wb_sel_o; // byte select outputs
`ifdef OR1200_WB_CAB
reg wb_cab_o; // CAB output
`endif
`ifdef OR1200_WB_B3
reg [1:0] burst_len; // burst counter
reg [2:0] wb_cti_o; // cycle type identifier
`endif
reg [dw-1:0] wb_dat_o; // output data bus
`endif
`ifdef OR1200_REGISTERED_INPUTS
reg long_ack_o; // normal termination
reg long_err_o; // error termination
reg [dw-1:0] biu_dat_o; // output data bus
`else
wire long_ack_o; // normal termination
wire long_err_o; // error termination
`endif
wire aborted; // Graceful abort
reg aborted_r; // Graceful abort
wire retry; // Retry
`ifdef OR1200_WB_RETRY
reg [`OR1200_WB_RETRY-1:0] retry_cntr; // Retry counter
`endif
reg previous_complete;
wire same_addr;
wire repeated_access;
reg repeated_access_ack;
reg [dw-1:0] wb_dat_r; // saved previous data read
 
//
// WISHBONE I/F <-> Internal RISC I/F conversion
//
 
//
// Address bus
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_adr_o <= #1 {aw{1'b0}};
else if ((biu_cyc_i & biu_stb_i) & ~wb_ack_i & ~aborted & ~(wb_stb_o & ~wb_ack_i) | biu_cab_i & (previous_complete | biu_ack_o))
wb_adr_o <= #1 biu_adr_i;
`else
assign wb_adr_o = biu_adr_i;
`endif
 
//
// Same access as previous one, store previous read data
//
assign same_addr = wb_adr_o == biu_adr_i;
assign repeated_access = same_addr & previous_complete;
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_dat_r <= #1 32'h0000_0000;
else if (wb_ack_i)
wb_dat_r <= #1 wb_dat_i;
 
always @(posedge clk or posedge rst)
if (rst)
repeated_access_ack <= #1 1'b0;
else if (repeated_access & biu_cyc_i & biu_stb_i)
repeated_access_ack <= #1 1'b1;
else
repeated_access_ack <= #1 1'b0;
 
//
// Previous access completed
//
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
previous_complete <= #1 1'b1;
else if (wb_ack_i & biu_cyc_i & biu_stb_i)
previous_complete <= #1 1'b1;
else if ((biu_cyc_i & biu_stb_i) & ~wb_ack_i & ~aborted & ~(wb_stb_o & ~wb_ack_i))
previous_complete <= #1 1'b0;
 
//
// Input data bus
//
`ifdef OR1200_REGISTERED_INPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
biu_dat_o <= #1 32'h0000_0000;
else if (wb_ack_i)
biu_dat_o <= #1 wb_dat_i;
`else
assign biu_dat_o = repeated_access_ack ? wb_dat_r : wb_dat_i;
`endif
 
//
// Output data bus
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_dat_o <= #1 {dw{1'b0}};
else if ((biu_cyc_i & biu_stb_i) & ~wb_ack_i & ~aborted)
wb_dat_o <= #1 biu_dat_i;
`else
assign wb_dat_o = biu_dat_i;
`endif
 
//
// Valid_div counts RISC clock cycles by modulo 4
// and is used to synchronize external WB i/f to
// RISC clock
//
always @(posedge clk or posedge rst)
if (rst)
valid_div <= #1 2'b0;
else
valid_div <= #1 valid_div + 1'd1;
 
//
// biu_ack_o is one RISC clock cycle long long_ack_o.
// long_ack_o is one, two or four RISC clock cycles long because
// WISHBONE can work at 1, 1/2 or 1/4 RISC clock.
//
assign biu_ack_o = (repeated_access_ack | long_ack_o) & ~aborted_r
`ifdef OR1200_CLKDIV_2_SUPPORTED
& (valid_div[0] | ~clmode[0])
`ifdef OR1200_CLKDIV_4_SUPPORTED
& (valid_div[1] | ~clmode[1])
`endif
`endif
;
 
//
// Acknowledgment of the data to the RISC
//
// long_ack_o
//
`ifdef OR1200_REGISTERED_INPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
long_ack_o <= #1 1'b0;
else
long_ack_o <= #1 wb_ack_i & ~aborted;
`else
assign long_ack_o = wb_ack_i;
`endif
 
//
// biu_err_o is one RISC clock cycle long long_err_o.
// long_err_o is one, two or four RISC clock cycles long because
// WISHBONE can work at 1, 1/2 or 1/4 RISC clock.
//
assign biu_err_o = long_err_o
`ifdef OR1200_CLKDIV_2_SUPPORTED
& (valid_div[0] | ~clmode[0])
`ifdef OR1200_CLKDIV_4_SUPPORTED
& (valid_div[1] | ~clmode[1])
`endif
`endif
;
 
//
// Error termination
//
// long_err_o
//
`ifdef OR1200_REGISTERED_INPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
long_err_o <= #1 1'b0;
else
long_err_o <= #1 wb_err_i & ~aborted;
`else
assign long_err_o = wb_err_i & ~aborted_r;
`endif
 
//
// Retry counter
//
// Assert 'retry' when 'wb_rty_i' is sampled high and keep it high
// until retry counter doesn't expire
//
`ifdef OR1200_WB_RETRY
assign retry = wb_rty_i | (|retry_cntr);
`else
assign retry = 1'b0;
`endif
`ifdef OR1200_WB_RETRY
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
retry_cntr <= #1 1'b0;
else if (wb_rty_i)
retry_cntr <= #1 {`OR1200_WB_RETRY{1'b1}};
else if (retry_cntr)
retry_cntr <= #1 retry_cntr - 7'd1;
`endif
 
//
// Graceful completion of aborted transfers
//
// Assert 'aborted' when 1) current transfer is in progress (wb_stb_o; which
// we know is only asserted together with wb_cyc_o) 2) and in next WB clock cycle
// wb_stb_o would be deasserted (biu_cyc_i and biu_stb_i are low) 3) and
// there is no termination of current transfer in this WB clock cycle (wb_ack_i
// and wb_err_i are low).
// 'aborted_r' is registered 'aborted' and extended until this "aborted" transfer
// is properly terminated with wb_ack_i/wb_err_i.
//
assign aborted = wb_stb_o & ~(biu_cyc_i & biu_stb_i) & ~(wb_ack_i | wb_err_i);
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
aborted_r <= #1 1'b0;
else if (wb_ack_i | wb_err_i)
aborted_r <= #1 1'b0;
else if (aborted)
aborted_r <= #1 1'b1;
 
//
// WB cyc_o
//
// Either 1) normal transfer initiated by biu_cyc_i (and biu_cab_i if
// bursts are enabled) and possibly suspended by 'retry'
// or 2) extended "aborted" transfer
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_cyc_o <= #1 1'b0;
else
`ifdef OR1200_NO_BURSTS
wb_cyc_o <= #1 biu_cyc_i & ~wb_ack_i & ~retry & ~repeated_access | aborted & ~wb_ack_i;
`else
wb_cyc_o <= #1 biu_cyc_i & ~wb_ack_i & ~retry & ~repeated_access | biu_cab_i | aborted & ~wb_ack_i;
`endif
`else
`ifdef OR1200_NO_BURSTS
assign wb_cyc_o = biu_cyc_i & ~retry;
`else
assign wb_cyc_o = biu_cyc_i | biu_cab_i & ~retry;
`endif
`endif
 
//
// WB stb_o
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_stb_o <= #1 1'b0;
else
wb_stb_o <= #1 (biu_cyc_i & biu_stb_i) & ~wb_ack_i & ~retry & ~repeated_access | aborted & ~wb_ack_i;
`else
assign wb_stb_o = biu_cyc_i & biu_stb_i;
`endif
 
//
// WB we_o
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_we_o <= #1 1'b0;
else
wb_we_o <= #1 biu_cyc_i & biu_stb_i & biu_we_i | aborted & wb_we_o;
`else
assign wb_we_o = biu_cyc_i & biu_stb_i & biu_we_i;
`endif
 
//
// WB sel_o
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_sel_o <= #1 4'b0000;
else
wb_sel_o <= #1 biu_sel_i;
`else
assign wb_sel_o = biu_sel_i;
`endif
 
`ifdef OR1200_WB_CAB
//
// WB cab_o
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_cab_o <= #1 1'b0;
else
wb_cab_o <= #1 biu_cab_i;
`else
assign wb_cab_o = biu_cab_i;
`endif
`endif
 
`ifdef OR1200_WB_B3
//
// Count burst beats
//
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
burst_len <= #1 2'b00;
else if (biu_cab_i && burst_len && wb_ack_i)
burst_len <= #1 burst_len - 1'b1;
else if (~biu_cab_i)
burst_len <= #1 2'b11;
 
//
// WB cti_o
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_cti_o <= #1 3'b000; // classic cycle
`ifdef OR1200_NO_BURSTS
else
wb_cti_o <= #1 3'b111; // end-of-burst
`else
else if (biu_cab_i && burst_len[1])
wb_cti_o <= #1 3'b010; // incrementing burst cycle
else if (biu_cab_i && wb_ack_i)
wb_cti_o <= #1 3'b111; // end-of-burst
`endif // OR1200_NO_BURSTS
`else
Unsupported !!!;
`endif
 
//
// WB bte_o
//
assign wb_bte_o = 2'b01; // 4-beat wrap burst
 
`endif // OR1200_WB_B3
 
endmodule
/rtl/verilog/or1200_freeze.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_freeze.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.8 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.7 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
116,7 → 123,7
multicycle, flushpipe, extend_flush, lsu_stall, if_stall,
lsu_unstall, du_stall, mac_stall,
force_dslot_fetch, abort_ex,
genpc_freeze, if_freeze, id_freeze, ex_freeze, wb_freeze,
genpc_freeze, if_freeze, id_freeze, ex_freeze, wb_freeze, saving_if_insn,
icpu_ack_i, icpu_err_i
);
 
140,6 → 147,7
output id_freeze;
output ex_freeze;
output wb_freeze;
input saving_if_insn;
input icpu_ack_i;
input icpu_err_i;
 
164,7 → 172,8
// This way NOP is asserted from stage ID into EX stage.
//
//assign genpc_freeze = du_stall | flushpipe_r | lsu_stall;
assign genpc_freeze = du_stall | flushpipe_r;
//assign genpc_freeze = du_stall | flushpipe_r;
assign genpc_freeze = (du_stall & !saving_if_insn) | flushpipe_r;
assign if_freeze = id_freeze | extend_flush;
//assign id_freeze = (lsu_stall | (~lsu_unstall & if_stall) | multicycle_freeze | force_dslot_fetch) & ~flushpipe | du_stall;
assign id_freeze = (lsu_stall | (~lsu_unstall & if_stall) | multicycle_freeze | force_dslot_fetch) | du_stall | mac_stall;
/rtl/verilog/or1200_alu.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_alu.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Defines added, flags are corrected.
//
// Revision 1.15 2005/01/07 09:23:39 andreje
// l.ff1 and l.cmov instructions added
//
// Revision 1.14 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
167,6 → 174,9
`endif
wire [width-1:0] result_and;
wire cy_sum;
`ifdef OR1200_IMPL_SUB
wire cy_sub;
`endif
reg cyforw;
 
//
178,9 → 188,12
assign a_eq_b = (comp_a == comp_b);
assign a_lt_b = (comp_a < comp_b);
`endif
`ifdef OR1200_IMPL_SUB
assign cy_sub = a < b;
`endif
assign {cy_sum, result_sum} = a + b;
`ifdef OR1200_IMPL_ADDC
assign {cy_csum, result_csum} = a + b + {32'd0, carry};
assign {cy_csum, result_csum} = a + b + {`OR1200_OPERAND_WIDTH'd0, carry};
`endif
assign result_and = a & b;
 
199,15 → 212,19
//
// Central part of the ALU
//
always @(alu_op or a or b or result_sum or result_and or macrc_op or shifted_rotated or mult_mac_result) begin
always @(alu_op or a or b or result_sum or result_and or macrc_op or shifted_rotated or mult_mac_result or flag or result_cust5 or carry
`ifdef OR1200_IMPL_ADDC
or result_csum
`endif
) begin
`ifdef OR1200_CASE_DEFAULT
casex (alu_op) // synopsys parallel_case
`else
casex (alu_op) // synopsys full_case parallel_case
`endif
`OR1200_ALUOP_FF1: begin
result = a[0] ? 1 : a[1] ? 2 : a[2] ? 3 : a[3] ? 4 : a[4] ? 5 : a[5] ? 6 : a[6] ? 7 : a[7] ? 8 : a[8] ? 9 : a[9] ? 10 : a[10] ? 11 : a[11] ? 12 : a[12] ? 13 : a[13] ? 14 : a[14] ? 15 : a[15] ? 16 : a[16] ? 17 : a[17] ? 18 : a[18] ? 19 : a[19] ? 20 : a[20] ? 21 : a[21] ? 22 : a[22] ? 23 : a[23] ? 24 : a[24] ? 25 : a[25] ? 26 : a[26] ? 27 : a[27] ? 28 : a[28] ? 29 : a[29] ? 30 : a[30] ? 31 : a[31] ? 32 : 0;
end
`OR1200_ALUOP_FF1: begin
result = a[0] ? 1 : a[1] ? 2 : a[2] ? 3 : a[3] ? 4 : a[4] ? 5 : a[5] ? 6 : a[6] ? 7 : a[7] ? 8 : a[8] ? 9 : a[9] ? 10 : a[10] ? 11 : a[11] ? 12 : a[12] ? 13 : a[13] ? 14 : a[14] ? 15 : a[15] ? 16 : a[16] ? 17 : a[17] ? 18 : a[18] ? 19 : a[19] ? 20 : a[20] ? 21 : a[21] ? 22 : a[22] ? 23 : a[23] ? 24 : a[24] ? 25 : a[25] ? 26 : a[26] ? 27 : a[27] ? 28 : a[28] ? 29 : a[29] ? 30 : a[30] ? 31 : a[31] ? 32 : 0;
end
`OR1200_ALUOP_CUST5 : begin
result = result_cust5;
end
222,9 → 239,11
result = result_csum;
end
`endif
`ifdef OR1200_IMPL_SUB
`OR1200_ALUOP_SUB : begin
result = a - b;
end
`endif
`OR1200_ALUOP_XOR : begin
result = a ^ b;
end
251,18 → 270,17
result = mult_mac_result;
end
`endif
`OR1200_ALUOP_CMOV: begin
result = flag ? a : b;
end
`OR1200_ALUOP_CMOV: begin
result = flag ? a : b;
end
 
`ifdef OR1200_CASE_DEFAULT
default: begin
default: begin
`else
`OR1200_ALUOP_COMP, `OR1200_ALUOP_AND:
begin
`OR1200_ALUOP_COMP, `OR1200_ALUOP_AND: begin
`endif
result=result_and;
end
result=result_and;
end
endcase
end
 
297,7 → 315,11
//
// Generate flag and flag write enable
//
always @(alu_op or result_sum or result_and or flagcomp) begin
always @(alu_op or result_sum or result_and or flagcomp
`ifdef OR1200_IMPL_ADDC
or result_csum
`endif
) begin
casex (alu_op) // synopsys parallel_case
`ifdef OR1200_ADDITIONAL_FLAG_MODIFIERS
`OR1200_ALUOP_ADD : begin
320,7 → 342,7
flag_we = 1'b1;
end
default: begin
flagforw = 1'b0;
flagforw = flagcomp;
flag_we = 1'b0;
end
endcase
330,10 → 352,15
// Generate SR[CY] write enable
//
always @(alu_op or cy_sum
`ifdef OR1200_IMPL_CY
`ifdef OR1200_IMPL_ADDC
or cy_csum
`endif
) begin
`ifdef OR1200_IMPL_SUB
or cy_sub
`endif
`endif
) begin
casex (alu_op) // synopsys parallel_case
`ifdef OR1200_IMPL_CY
`OR1200_ALUOP_ADD : begin
346,7 → 373,13
cy_we = 1'b1;
end
`endif
`ifdef OR1200_IMPL_SUB
`OR1200_ALUOP_SUB: begin
cyforw = cy_sub;
cy_we = 1'b1;
end
`endif
`endif
default: begin
cyforw = 1'b0;
cy_we = 1'b0;
/rtl/verilog/or1200_cfgr.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_cfgr.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.4 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.3 2002/03/29 15:16:54 lampret
// Some of the warnings fixed.
//
198,7 → 204,7
//
always @(spr_addr)
`ifdef OR1200_SYS_FULL_DECODE
if (!spr_addr[31:4])
if (spr_addr[31:4] == 28'h0)
`endif
case(spr_addr[3:0])
`OR1200_SPRGRP_SYS_VR: begin
/rtl/verilog/or1200_dc_tag.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_dc_tag.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Coding style changed.
//
// Revision 1.5 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.4 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
132,27 → 139,34
// Instantiation of TAG RAM block
//
`ifdef OR1200_DC_1W_4KB
or1200_spram_256x21 dc_tag0(
or1200_spram #
(
.aw(8),
.dw(21)
)
`endif
`ifdef OR1200_DC_1W_8KB
or1200_spram_512x20 dc_tag0(
or1200_spram #
(
.aw(9),
.dw(20)
)
`endif
dc_tag0
(
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
// RAM BIST
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.clk(clk),
.rst(rst),
.ce(en),
.we(we),
.oe(1'b1),
.addr(addr),
.di(datain),
.doq({tag, tag_v})
);
 
.clk(clk),
.ce(en),
.we(we),
.addr(addr),
.di(datain),
.doq({tag, tag_v})
);
`endif
 
endmodule
endmodule // or1200_dc_tag
/rtl/verilog/or1200_qmem_top.v
46,7 → 46,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_qmem_top.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Coding style changed.
//
// Revision 1.3 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.2 2004/04/05 08:40:26 lampret
// Merged branch_qmem into main tree.
//
90,8 → 97,8
qmemimmu_adr_i,
qmemimmu_cycstb_i,
qmemimmu_ci_i,
qmemicpu_sel_i,
qmemicpu_tag_i,
qmemicpu_sel_i,
qmemicpu_tag_i,
qmemicpu_dat_o,
qmemicpu_ack_o,
qmemimmu_rty_o,
101,7 → 108,7
// QMEM and IC
icqmem_adr_o,
icqmem_cycstb_o,
icqmem_ci_o,
icqmem_ci_o,
icqmem_sel_o,
icqmem_tag_o,
icqmem_dat_i,
114,10 → 121,10
qmemdmmu_adr_i,
qmemdmmu_cycstb_i,
qmemdmmu_ci_i,
qmemdcpu_we_i,
qmemdcpu_sel_i,
qmemdcpu_tag_i,
qmemdcpu_dat_i,
qmemdcpu_we_i,
qmemdcpu_sel_i,
qmemdcpu_tag_i,
qmemdcpu_dat_i,
qmemdcpu_dat_o,
qmemdcpu_ack_o,
qmemdcpu_rty_o,
125,9 → 132,18
qmemdmmu_tag_o,
 
// QMEM and DC
dcqmem_adr_o, dcqmem_cycstb_o, dcqmem_ci_o,
dcqmem_we_o, dcqmem_sel_o, dcqmem_tag_o, dcqmem_dat_o,
dcqmem_dat_i, dcqmem_ack_i, dcqmem_rty_i, dcqmem_err_i, dcqmem_tag_i
dcqmem_adr_o,
dcqmem_cycstb_o,
dcqmem_ci_o,
dcqmem_we_o,
dcqmem_sel_o,
dcqmem_tag_o,
dcqmem_dat_o,
dcqmem_dat_i,
dcqmem_ack_i,
dcqmem_rty_i,
dcqmem_err_i,
dcqmem_tag_i
 
);
 
158,8 → 174,8
input [31:0] qmemimmu_adr_i;
input qmemimmu_cycstb_i;
input qmemimmu_ci_i;
input [3:0] qmemicpu_sel_i;
input [3:0] qmemicpu_tag_i;
input [3:0] qmemicpu_sel_i;
input [3:0] qmemicpu_tag_i;
output [31:0] qmemicpu_dat_o;
output qmemicpu_ack_o;
output qmemimmu_rty_o;
187,9 → 203,9
input qmemdmmu_cycstb_i;
input qmemdmmu_ci_i;
input qmemdcpu_we_i;
input [3:0] qmemdcpu_sel_i;
input [3:0] qmemdcpu_tag_i;
input [31:0] qmemdcpu_dat_i;
input [3:0] qmemdcpu_sel_i;
input [3:0] qmemdcpu_tag_i;
input [31:0] qmemdcpu_dat_i;
output [31:0] qmemdcpu_dat_o;
output qmemdcpu_ack_o;
output qmemdcpu_rty_o;
/rtl/verilog/or1200_amultp2_32x32.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_amultp2_32x32.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.2 2003/04/07 01:23:31 lampret
// Added another pipe stage to match gmult. One day second pipe in amult and gmult might be removed to get better performance.
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
/rtl/verilog/or1200_dc_ram.v
44,7 → 44,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_dc_ram.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Coding style changed.
//
// Revision 1.6 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.5 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
134,25 → 141,34
// Instantiation of RAM block
//
`ifdef OR1200_DC_1W_4KB
or1200_spram_1024x32_bw dc_ram(
or1200_spram_32_bw #
(
.aw(10),
.dw(32)
)
`endif
`ifdef OR1200_DC_1W_8KB
or1200_spram_2048x32_bw dc_ram(
or1200_spram_32_bw #
(
.aw(11),
.dw(32)
)
`endif
dc_ram
(
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
// RAM BIST
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.clk(clk),
.rst(rst),
.ce(en),
.we(we),
.oe(1'b1),
.addr(addr),
.di(datain),
.doq(dataout)
);
.clk(clk),
.ce(en),
.we(we),
.addr(addr),
.di(datain),
.doq(dataout)
);
`endif
endmodule
 
endmodule // or1200_dc_ram
/rtl/verilog/or1200_cpu.v
44,7 → 44,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_cpu.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// Structure reordered and bugs fixed.
//
// Revision 1.16 2005/01/07 09:28:37 andreje
// flag for l.cmov instruction added
//
// Revision 1.15 2004/05/09 19:49:04 lampret
// Added some l.cust5 custom instructions as example
//
159,17 → 166,22
immu_en,
 
// Debug unit
ex_insn, ex_freeze, id_pc, branch_op,
spr_dat_npc, rf_dataw,
du_stall, du_addr, du_dat_du, du_read, du_write, du_dsr, du_hwbkpt,
du_except, du_dat_cpu,
id_void, id_insn, ex_void,
ex_insn, ex_freeze, wb_insn, wb_freeze, id_pc, ex_pc, wb_pc, branch_op,
spr_dat_npc, rf_dataw, ex_flushpipe,
du_stall, du_addr, du_dat_du, du_read, du_write, du_except_stop, du_except_trig,
du_dsr, du_dmr1, du_hwbkpt, du_hwbkpt_ls_r, du_dat_cpu, du_lsu_store_dat, du_lsu_load_dat,
abort_mvspr, abort_ex,
// Data interface
dc_en,
dcpu_adr_o, dcpu_cycstb_o, dcpu_we_o, dcpu_sel_o, dcpu_tag_o, dcpu_dat_o,
dcpu_dat_i, dcpu_ack_i, dcpu_rty_i, dcpu_err_i, dcpu_tag_i,
dmmu_en,
sb_en, dmmu_en,
 
// SR Interface
boot_adr_sel_i,
 
// Interrupt & tick exceptions
sig_int, sig_tick,
 
214,9 → 226,17
//
// Debug interface
//
output id_void;
output [31:0] id_insn;
output ex_void;
output [31:0] ex_insn;
output ex_freeze;
output [31:0] wb_insn;
output wb_freeze;
output [31:0] id_pc;
output [31:0] ex_pc;
output [31:0] wb_pc;
output ex_flushpipe;
output [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
 
input du_stall;
225,10 → 245,15
input du_read;
input du_write;
input [`OR1200_DU_DSR_WIDTH-1:0] du_dsr;
input [24:0] du_dmr1;
input du_hwbkpt;
output [12:0] du_except;
input du_hwbkpt_ls_r;
output [12:0] du_except_trig;
output [12:0] du_except_stop;
output [dw-1:0] du_dat_cpu;
output [dw-1:0] rf_dataw;
output [dw-1:0] du_lsu_store_dat;
output [dw-1:0] du_lsu_load_dat;
 
//
// Data (DC) interface
249,9 → 274,17
//
// Data (DMMU) interface
//
output sb_en;
output dmmu_en;
output abort_ex;
output abort_mvspr;
 
//
// SR Interface
//
input boot_adr_sel_i;
 
//
// SPR interface
//
output supv;
277,20 → 310,22
// Internal wires
//
wire [31:0] if_insn;
wire saving_if_insn;
wire [31:0] if_pc;
wire [31:2] lr_sav;
wire [aw-1:0] rf_addrw;
wire [aw-1:0] rf_addra;
wire [aw-1:0] rf_addrb;
wire rf_rda;
wire rf_rdb;
wire [dw-1:0] simm;
wire [dw-1:2] branch_addrofs;
wire [dw-1:0] id_simm;
wire [dw-1:2] id_branch_addrtarget;
wire [dw-1:2] ex_branch_addrtarget;
wire [`OR1200_ALUOP_WIDTH-1:0] alu_op;
wire [`OR1200_SHROTOP_WIDTH-1:0] shrot_op;
wire [`OR1200_COMPOP_WIDTH-1:0] comp_op;
wire [`OR1200_BRANCHOP_WIDTH-1:0] pre_branch_op;
wire [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
wire [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
wire [`OR1200_LSUOP_WIDTH-1:0] id_lsu_op;
wire genpc_freeze;
wire if_freeze;
wire id_freeze;
302,6 → 337,7
wire [dw-1:0] rf_dataw;
wire [dw-1:0] rf_dataa;
wire [dw-1:0] rf_datab;
wire [dw-1:0] muxed_a;
wire [dw-1:0] muxed_b;
wire [dw-1:0] wb_forw;
wire wbforw_valid;
310,20 → 346,25
wire [dw-1:0] alu_dataout;
wire [dw-1:0] lsu_dataout;
wire [dw-1:0] sprs_dataout;
wire [31:0] lsu_addrofs;
wire [31:0] ex_simm;
wire [`OR1200_MULTICYCLE_WIDTH-1:0] multicycle;
wire [`OR1200_EXCEPT_WIDTH-1:0] except_type;
wire [4:0] cust5_op;
wire [5:0] cust5_limm;
wire flushpipe;
wire if_flushpipe;
wire id_flushpipe;
wire ex_flushpipe;
wire wb_flushpipe;
wire extend_flush;
wire branch_taken;
wire ex_branch_taken;
wire flag;
wire flagforw;
wire flag_we;
wire flag_we_alu;
wire carry;
wire cyforw;
wire cy_we;
wire cy_we_alu;
wire cy_we_rf;
wire lsu_stall;
wire epcr_we;
wire eear_we;
335,10 → 376,10
wire sr_we;
wire [`OR1200_SR_WIDTH-1:0] to_sr;
wire [`OR1200_SR_WIDTH-1:0] sr;
wire except_flushpipe;
wire except_start;
wire except_started;
wire [31:0] wb_insn;
wire [15:0] spr_addrimm;
wire sig_syscall;
wire sig_trap;
wire [31:0] spr_dat_cfgr;
349,12 → 390,16
wire force_dslot_fetch;
wire no_more_dslot;
wire ex_void;
wire ex_spr_read;
wire ex_spr_write;
wire if_stall;
wire id_macrc_op;
wire ex_macrc_op;
wire [`OR1200_MACOP_WIDTH-1:0] id_mac_op;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op;
wire [31:0] mult_mac_result;
wire mac_stall;
wire [12:0] except_trig;
wire [12:0] except_stop;
wire genpc_refetch;
wire rfe;
368,31 → 413,60
wire except_ibuserr;
wire except_dbuserr;
wire abort_ex;
wire abort_mvspr;
 
//
// Send exceptions to Debug Unit
//
assign du_except = except_stop;
assign du_except_trig = except_trig;
assign du_except_stop = except_stop;
assign du_lsu_store_dat = operand_b;
assign du_lsu_load_dat = lsu_dataout;
 
//
// Data cache enable
//
`ifdef OR1200_NO_DC
assign dc_en = 1'b0;
`else
assign dc_en = sr[`OR1200_SR_DCE];
`endif
 
//
// Instruction cache enable
//
`ifdef OR1200_NO_IC
assign ic_en = 1'b0;
`else
assign ic_en = sr[`OR1200_SR_ICE];
`endif
 
//
// SB enable
//
`ifdef OR1200_SB_IMPLEMENTED
//assign sb_en = sr[`OR1200_SR_SBE]; // SBE not defined -- jb
`else
assign sb_en = 1'b0;
`endif
 
//
// DMMU enable
//
`ifdef OR1200_NO_DMMU
assign dmmu_en = 1'b0;
`else
assign dmmu_en = sr[`OR1200_SR_DME];
`endif
 
//
// IMMU enable
//
assign immu_en = sr[`OR1200_SR_IME];
`ifdef OR1200_NO_IMMU
assign immu_en = 1'b0;
`else
assign immu_en = sr[`OR1200_SR_IME] & ~except_started;
`endif
 
//
// SUPV bit
400,6 → 474,11
assign supv = sr[`OR1200_SR_SM];
 
//
// FLAG write enable
//
assign flag_we = flag_we_alu && ~abort_mvspr;
 
//
// Instantiation of instruction fetch block
//
or1200_genpc or1200_genpc(
412,21 → 491,23
.icpu_rty_i(icpu_rty_i),
.icpu_adr_i(icpu_adr_i),
 
.pre_branch_op(pre_branch_op),
.branch_op(branch_op),
.except_type(except_type),
.except_start(except_start),
.except_prefix(sr[`OR1200_SR_EPH]),
.branch_addrofs(branch_addrofs),
.lr_restor(operand_b),
.id_branch_addrtarget(id_branch_addrtarget),
.ex_branch_addrtarget(ex_branch_addrtarget),
.muxed_b(muxed_b),
.operand_b(operand_b),
.flag(flag),
.taken(branch_taken),
.binsn_addr(lr_sav),
.flagforw(flagforw),
.ex_branch_taken(ex_branch_taken),
.epcr(epcr),
.spr_dat_i(spr_dat_cpu),
.spr_pc_we(pc_we),
.genpc_refetch(genpc_refetch),
.genpc_freeze(genpc_freeze),
.genpc_stop_prefetch(1'b0),
.no_more_dslot(no_more_dslot)
);
 
445,7 → 526,8
.if_freeze(if_freeze),
.if_insn(if_insn),
.if_pc(if_pc),
.flushpipe(flushpipe),
.saving_if_insn(saving_if_insn),
.if_flushpipe(if_flushpipe),
.if_stall(if_stall),
.no_more_dslot(no_more_dslot),
.genpc_refetch(genpc_refetch),
464,11 → 546,19
.id_freeze(id_freeze),
.ex_freeze(ex_freeze),
.wb_freeze(wb_freeze),
.flushpipe(flushpipe),
.if_flushpipe(if_flushpipe),
.id_flushpipe(id_flushpipe),
.ex_flushpipe(ex_flushpipe),
.wb_flushpipe(wb_flushpipe),
.extend_flush(extend_flush),
.except_flushpipe(except_flushpipe),
.abort_mvspr(abort_mvspr),
.if_insn(if_insn),
.id_insn(id_insn),
.ex_insn(ex_insn),
.branch_op(branch_op),
.branch_taken(branch_taken),
.id_branch_op(pre_branch_op),
.ex_branch_op(branch_op),
.ex_branch_taken(ex_branch_taken),
.rf_addra(rf_addra),
.rf_addrb(rf_addrb),
.rf_rda(rf_rda),
479,23 → 569,30
.comp_op(comp_op),
.rf_addrw(rf_addrw),
.rfwb_op(rfwb_op),
.pc_we(pc_we),
.wb_insn(wb_insn),
.simm(simm),
.branch_addrofs(branch_addrofs),
.lsu_addrofs(lsu_addrofs),
.id_simm(id_simm),
.id_branch_addrtarget(id_branch_addrtarget),
.ex_branch_addrtarget(ex_branch_addrtarget),
.ex_simm(ex_simm),
.sel_a(sel_a),
.sel_b(sel_b),
.lsu_op(lsu_op),
.id_lsu_op(id_lsu_op),
.cust5_op(cust5_op),
.cust5_limm(cust5_limm),
.id_pc(id_pc),
.ex_pc(ex_pc),
.multicycle(multicycle),
.spr_addrimm(spr_addrimm),
.wbforw_valid(wbforw_valid),
.sig_syscall(sig_syscall),
.sig_trap(sig_trap),
.force_dslot_fetch(force_dslot_fetch),
.no_more_dslot(no_more_dslot),
.id_void(id_void),
.ex_void(ex_void),
.ex_spr_read(ex_spr_read),
.ex_spr_write(ex_spr_write),
.id_mac_op(id_mac_op),
.id_macrc_op(id_macrc_op),
.ex_macrc_op(ex_macrc_op),
.rfe(rfe),
509,6 → 606,8
or1200_rf or1200_rf(
.clk(clk),
.rst(rst),
.cy_we_i(cy_we_alu),
.cy_we_o(cy_we_rf),
.supv(sr[`OR1200_SR_SM]),
.wb_freeze(wb_freeze),
.addrw(rf_addrw),
515,7 → 614,7
.dataw(rf_dataw),
.id_freeze(id_freeze),
.we(rfwb_op[0]),
.flushpipe(flushpipe),
.flushpipe(wb_flushpipe),
.addra(rf_addra),
.rda(rf_rda),
.dataa(rf_dataa),
541,11 → 640,12
.rf_datab(rf_datab),
.ex_forw(rf_dataw),
.wb_forw(wb_forw),
.simm(simm),
.simm(id_simm),
.sel_a(sel_a),
.sel_b(sel_b),
.operand_a(operand_a),
.operand_b(operand_b),
.muxed_a(muxed_a),
.muxed_b(muxed_b)
);
 
564,10 → 664,10
.cust5_limm(cust5_limm),
.result(alu_dataout),
.flagforw(flagforw),
.flag_we(flag_we),
.flag_we(flag_we_alu),
.cyforw(cyforw),
.cy_we(cy_we),
.flag(flag),
.cy_we(cy_we_alu),
.flag(flag),
.carry(carry)
);
 
600,14 → 700,15
.clk(clk),
.rst(rst),
.addrbase(operand_a),
.addrofs(spr_addrimm),
.addrofs(ex_simm[15:0]),
.dat_i(operand_b),
.alu_op(alu_op),
.ex_spr_read(ex_spr_read),
.ex_spr_write(ex_spr_write),
.flagforw(flagforw),
.flag_we(flag_we),
.flag(flag),
.cyforw(cyforw),
.cy_we(cy_we),
.cy_we(cy_we_rf),
.carry(carry),
.to_wbmux(sprs_dataout),
 
616,7 → 717,7
.du_read(du_read),
.du_write(du_write),
.du_dat_cpu(du_dat_cpu),
 
.boot_adr_sel_i(boot_adr_sel_i),
.spr_addr(spr_addr),
.spr_dat_pic(spr_dat_pic),
.spr_dat_tt(spr_dat_tt),
652,18 → 753,25
// Instantiation of load/store unit
//
or1200_lsu or1200_lsu(
.addrbase(operand_a),
.addrofs(lsu_addrofs),
.lsu_op(lsu_op),
.clk(clk),
.rst(rst),
.id_addrbase(muxed_a),
.id_addrofs(id_simm),
.ex_addrbase(operand_a),
.ex_addrofs(ex_simm),
.id_lsu_op(id_lsu_op),
.lsu_datain(operand_b),
.lsu_dataout(lsu_dataout),
.lsu_stall(lsu_stall),
.lsu_unstall(lsu_unstall),
.du_stall(du_stall),
.du_stall(du_stall),
.except_align(except_align),
.except_dtlbmiss(except_dtlbmiss),
.except_dmmufault(except_dmmufault),
.except_dbuserr(except_dbuserr),
.id_freeze(id_freeze),
.ex_freeze(ex_freeze),
.flushpipe(ex_flushpipe),
 
.dcpu_adr_o(dcpu_adr_o),
.dcpu_cycstb_o(dcpu_cycstb_o),
689,7 → 797,7
.muxin_a(alu_dataout),
.muxin_b(lsu_dataout),
.muxin_c(sprs_dataout),
.muxin_d({lr_sav, 2'b0}),
.muxin_d(ex_pc),
.muxout(rf_dataw),
.muxreg(wb_forw),
.muxreg_valid(wbforw_valid)
702,7 → 810,7
.clk(clk),
.rst(rst),
.multicycle(multicycle),
.flushpipe(flushpipe),
.flushpipe(wb_flushpipe),
.extend_flush(extend_flush),
.lsu_stall(lsu_stall),
.if_stall(if_stall),
711,6 → 819,7
.abort_ex(abort_ex),
.du_stall(du_stall),
.mac_stall(mac_stall),
.saving_if_insn(saving_if_insn),
.genpc_freeze(genpc_freeze),
.if_freeze(if_freeze),
.id_freeze(id_freeze),
739,7 → 848,7
.sig_itlbmiss(except_itlbmiss),
.sig_immufault(except_immufault),
.sig_tick(sig_tick),
.branch_taken(branch_taken),
.ex_branch_taken(ex_branch_taken),
.icpu_ack_i(icpu_ack_i),
.icpu_err_i(icpu_err_i),
.dcpu_ack_i(dcpu_ack_i),
751,19 → 860,28
.if_stall(if_stall),
.if_pc(if_pc),
.id_pc(id_pc),
.lr_sav(lr_sav),
.flushpipe(flushpipe),
.ex_pc(ex_pc),
.wb_pc(wb_pc),
.id_flushpipe(id_flushpipe),
.ex_flushpipe(ex_flushpipe),
.extend_flush(extend_flush),
.except_flushpipe(except_flushpipe),
.abort_mvspr(abort_mvspr),
.except_type(except_type),
.except_start(except_start),
.except_started(except_started),
.except_stop(except_stop),
.except_trig(except_trig),
.ex_void(ex_void),
.spr_dat_ppc(spr_dat_ppc),
.spr_dat_npc(spr_dat_npc),
 
.datain(operand_b),
.datain(spr_dat_cpu),
.branch_op(branch_op),
.du_dsr(du_dsr),
.du_dmr1(du_dmr1),
.du_hwbkpt(du_hwbkpt),
.du_hwbkpt_ls_r(du_hwbkpt_ls_r),
.epcr_we(epcr_we),
.eear_we(eear_we),
.esr_we(esr_we),
/rtl/verilog/or1200_immu_top.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_immu_top.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// Structure reordered and bugs fixed.
//
// Revision 1.15 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.14 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
126,6 → 133,9
ic_en, immu_en, supv, icpu_adr_i, icpu_cycstb_i,
icpu_adr_o, icpu_tag_o, icpu_rty_o, icpu_err_o,
 
// SR Interface
boot_adr_sel_i,
 
// SPR access
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
 
165,6 → 175,11
output icpu_err_o;
 
//
// SR Interface
//
input boot_adr_sel_i;
 
//
// SPR access
//
input spr_cs;
207,12 → 222,16
wire fault;
wire miss;
wire page_cross;
reg [31:0] icpu_adr_o;
reg [31:0] icpu_adr_default;
wire [31:0] icpu_adr_boot;
reg icpu_adr_select;
reg [31:0] icpu_adr_o;
reg [31:`OR1200_IMMU_PS] icpu_vpn_r;
`ifdef OR1200_NO_IMMU
`else
reg itlb_en_r;
reg dis_spr_access;
reg dis_spr_access_frst_clk;
reg dis_spr_access_scnd_clk;
`endif
 
//
233,10 → 252,29
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge rst or posedge clk)
if (rst)
icpu_adr_o <= #1 32'h0000_0100;
// default value
if (rst) begin
icpu_adr_default <= #1 32'h0000_0100;
icpu_adr_select <= #1 1'b1; // select async. value due to reset state
end
// selected value (different from default) is written into FF after reset state
else if (icpu_adr_select) begin
icpu_adr_default <= #1 icpu_adr_boot; // dynamic value can only be assigned to FF out of reset!
icpu_adr_select <= #1 1'b0; // select FF value
end
else begin
icpu_adr_default <= #1 icpu_adr_i;
end
 
// select async. value for boot address after reset - PC jumps to the address selected after boot!
//assign icpu_adr_boot = {(boot_adr_sel_i ? `OR1200_EXCEPT_EPH1_P : `OR1200_EXCEPT_EPH0_P), 12'h100} ;
assign icpu_adr_boot = `OR1200_BOOT_ADR; // jb
 
always @(icpu_adr_boot or icpu_adr_default or icpu_adr_select)
if (icpu_adr_select)
icpu_adr_o = icpu_adr_boot ; // async. value is selected due to reset state
else
icpu_adr_o <= #1 icpu_adr_i;
icpu_adr_o = icpu_adr_default ; // FF value is selected 2nd clock after reset state
`else
Unsupported !!!
`endif
284,40 → 322,51
// 1300 - 13FF itlbtr w0
// 1300 - 133F itlbtr w0 [63:0]
//
assign itlb_spr_access = spr_cs & ~dis_spr_access;
assign itlb_spr_access = spr_cs & ~dis_spr_access_scnd_clk;
 
//
// Disable ITLB SPR access
//
// This flop is used to mask ITLB miss/fault exception
// during first clock cycle of accessing ITLB SPR. In
// This flops are used to mask ITLB miss/fault exception
// during first & second clock cycles of accessing ITLB SPR. In
// subsequent clock cycles it is assumed that ITLB SPR
// access was accomplished and that normal instruction fetching
// can proceed.
//
// spr_cs sets dis_spr_access and icpu_rty_o clears it.
// spr_cs sets dis_spr_access_frst_clk and icpu_rty_o clears it.
// dis_spr_access_frst_clk sets dis_spr_access_scnd_clk and
// icpu_rty_o clears it.
//
always @(posedge clk or posedge rst)
if (rst)
dis_spr_access <= #1 1'b0;
dis_spr_access_frst_clk <= #1 1'b0;
else if (!icpu_rty_o)
dis_spr_access <= #1 1'b0;
dis_spr_access_frst_clk <= #1 1'b0;
else if (spr_cs)
dis_spr_access <= #1 1'b1;
dis_spr_access_frst_clk <= #1 1'b1;
 
always @(posedge clk or posedge rst)
if (rst)
dis_spr_access_scnd_clk <= #1 1'b0;
else if (!icpu_rty_o)
dis_spr_access_scnd_clk <= #1 1'b0;
else if (dis_spr_access_frst_clk)
dis_spr_access_scnd_clk <= #1 1'b1;
 
//
// Tags:
//
// OR1200_DTAG_TE - TLB miss Exception
// OR1200_DTAG_PE - Page fault Exception
// OR1200_ITAG_TE - TLB miss Exception
// OR1200_ITAG_PE - Page fault Exception
//
assign icpu_tag_o = miss ? `OR1200_DTAG_TE : fault ? `OR1200_DTAG_PE : qmemimmu_tag_i;
assign icpu_tag_o = miss ? `OR1200_ITAG_TE : fault ? `OR1200_ITAG_PE : qmemimmu_tag_i;
 
//
// icpu_rty_o
//
// assign icpu_rty_o = !icpu_err_o & qmemimmu_rty_i;
assign icpu_rty_o = qmemimmu_rty_i | itlb_spr_access & immu_en;
//assign icpu_rty_o = qmemimmu_rty_i | itlb_spr_access & immu_en;
assign icpu_rty_o = qmemimmu_rty_i;
 
//
// icpu_err_o
340,11 → 389,12
assign itlb_done = itlb_en_r & ~page_cross;
 
//
// Cut transfer if something goes wrong with translation. If IC is disabled,
// use delayed signals.
// Cut transfer when access (mtspr/mfspr) to/from ITLB occure or if something goes
// wrong with translation. If IC is disabled, use delayed signals.
//
// assign qmemimmu_cycstb_o = (!ic_en & immu_en) ? ~(miss | fault) & icpu_cycstb_i & ~page_cross : (miss | fault) ? 1'b0 : icpu_cycstb_i & ~page_cross; // DL
assign qmemimmu_cycstb_o = immu_en ? ~(miss | fault) & icpu_cycstb_i & ~page_cross & itlb_done : icpu_cycstb_i & ~page_cross;
//assign qmemimmu_cycstb_o = immu_en ? ~(miss | fault) & icpu_cycstb_i & ~page_cross & itlb_done : icpu_cycstb_i & ~page_cross;
assign qmemimmu_cycstb_o = immu_en ? ~(miss | fault) & icpu_cycstb_i & ~page_cross & itlb_done & ~itlb_spr_access : icpu_cycstb_i & ~page_cross;
 
//
// Cache Inhibit
352,9 → 402,11
// Cache inhibit is not really needed for instruction memory subsystem.
// If we would doq it, we would doq it like this.
// assign qmemimmu_ci_o = immu_en ? itlb_done & itlb_ci : `OR1200_IMMU_CI;
// However this causes a async combinational loop so we stick to
// However this causes an async combinatorial loop so we stick to
// no cache inhibit.
assign qmemimmu_ci_o = `OR1200_IMMU_CI;
//assign qmemimmu_ci_o = `OR1200_IMMU_CI;
// Cache inhibit without an async combinatorial loop
assign qmemimmu_ci_o = immu_en ? itlb_ci : `OR1200_IMMU_CI;
 
 
//
361,13 → 413,23
// Physical address is either translated virtual address or
// simply equal when IMMU is disabled
//
assign qmemimmu_adr_o = itlb_done ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:0]} : {icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:0]}; // DL: immu_en
//assign qmemimmu_adr_o = itlb_done ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:0]} : {icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:0]}; // DL: immu_en
assign qmemimmu_adr_o = immu_en & itlb_done ? {itlb_ppn, icpu_adr_i[`OR1200_IMMU_PS-1:2], 2'h0} : {icpu_vpn_r, icpu_adr_i[`OR1200_IMMU_PS-1:2], 2'h0};
 
reg [31:0] spr_dat_reg;
//
// Output to SPRS unit
//
assign spr_dat_o = spr_cs ? itlb_dat_o : 32'h00000000;
// spr_dat_o is registered on the 1st clock of spr read
// so itlb can continue with process during execution of mfspr.
always @(posedge clk or posedge rst)
if (rst)
spr_dat_reg <= #1 32'h0000_0000;
else if (spr_cs & !dis_spr_access_scnd_clk)
spr_dat_reg <= #1 itlb_dat_o;
 
assign spr_dat_o = itlb_spr_access ? itlb_dat_o : spr_dat_reg;
 
//
// Page fault exception logic
//
/rtl/verilog/or1200_dc_fsm.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_dc_fsm.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.9 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.8 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
117,8 → 124,8
// Internal i/f to top level DC
dc_en, dcqmem_cycstb_i, dcqmem_ci_i, dcqmem_we_i, dcqmem_sel_i,
tagcomp_miss, biudata_valid, biudata_error, start_addr, saved_addr,
dcram_we, biu_read, biu_write, first_hit_ack, first_miss_ack, first_miss_err,
burst, tag_we, dc_addr
dcram_we, biu_read, biu_write, biu_sel, first_hit_ack, first_miss_ack, first_miss_err,
burst, tag_we, tag_valid, dc_addr
);
 
//
139,11 → 146,13
output [3:0] dcram_we;
output biu_read;
output biu_write;
output biu_sel;
output first_hit_ack;
output first_miss_ack;
output first_miss_err;
output burst;
output tag_we;
output tag_valid;
output [31:0] dc_addr;
 
//
156,21 → 165,35
reg store;
reg load;
reg cache_inhibit;
reg cache_miss;
//wire tagcomp_miss_wide;
wire first_store_hit_ack;
 
//
// Generate of DCRAM write enables
//
assign dcram_we = {4{load & biudata_valid & !cache_inhibit}} | {4{first_store_hit_ack}} & dcqmem_sel_i;
assign tag_we = biu_read & biudata_valid & !cache_inhibit;
//assign dcram_we = {4{load & biudata_valid & !cache_inhibit}} | {4{first_store_hit_ack}} & dcqmem_sel_i;
assign dcram_we = {4{load & biudata_valid & !cache_inhibit & !hitmiss_eval}} |
{4{first_store_hit_ack}} & dcqmem_sel_i;
//assign tag_we = biu_read & biudata_valid & !cache_inhibit;
assign tag_we = load & (biudata_valid & (!cache_inhibit | !cache_miss) | biudata_error) & !hitmiss_eval |
store & (biudata_valid & cache_inhibit & !cache_miss | biudata_error) & !hitmiss_eval;
assign tag_valid = biudata_valid & !cache_inhibit;
 
//
// BIU read and write
//
assign biu_read = (hitmiss_eval & tagcomp_miss) | (!hitmiss_eval & load);
assign biu_write = store;
//assign biu_read = (hitmiss_eval & tagcomp_miss) | (!hitmiss_eval & load);
//assign biu_read = ((hitmiss_eval & tagcomp_miss) | (!hitmiss_eval & load)) & (dcqmem_cycstb_i | biudata_valid);
assign biu_read = (state == `OR1200_DCFSM_CLOAD) & (hitmiss_eval ? ((tagcomp_miss | dcqmem_ci_i) & dcqmem_cycstb_i) : (cache_miss & !cache_inhibit & biudata_valid | dcqmem_cycstb_i & !biudata_error)) |
(state == `OR1200_DCFSM_LREFILL3) & !(biudata_valid & !cnt) & !biudata_error;
//assign biu_write = store;
//assign biu_write = store & dcqmem_cycstb_i;
assign biu_write = store & dcqmem_cycstb_i;
assign biu_sel = load;
 
assign dc_addr = (biu_read | biu_write) & !hitmiss_eval ? saved_addr : start_addr;
//assign dc_addr = (biu_read | biu_write) & !hitmiss_eval ? saved_addr : start_addr;
assign dc_addr = (!(load | store) | hitmiss_eval) ? start_addr : saved_addr;
assign saved_addr = saved_addr_r;
 
//
179,8 → 202,11
// Assert for cache miss first word stored/loaded OK
// Assert for cache miss first word stored/loaded with an error
//
assign first_hit_ack = (state == `OR1200_DCFSM_CLOAD) & !tagcomp_miss & !cache_inhibit & !dcqmem_ci_i | first_store_hit_ack;
assign first_store_hit_ack = (state == `OR1200_DCFSM_CSTORE) & !tagcomp_miss & biudata_valid & !cache_inhibit & !dcqmem_ci_i;
//assign tagcomp_miss_wide = tagcomp_miss | (saved_addr != start_addr);
//assign first_hit_ack = (state == `OR1200_DCFSM_CLOAD) & !tagcomp_miss_wide & !cache_inhibit | first_store_hit_ack;
assign first_hit_ack = (state == `OR1200_DCFSM_CLOAD) & hitmiss_eval & !tagcomp_miss & !dcqmem_ci_i | first_store_hit_ack;
//assign first_store_hit_ack = (state == `OR1200_DCFSM_CSTORE) & !tagcomp_miss_wide & biudata_valid & !cache_inhibit;
assign first_store_hit_ack = (state == `OR1200_DCFSM_CSTORE) & !hitmiss_eval & !cache_miss & biudata_valid & !cache_inhibit;
assign first_miss_ack = ((state == `OR1200_DCFSM_CLOAD) | (state == `OR1200_DCFSM_CSTORE)) & biudata_valid;
assign first_miss_err = ((state == `OR1200_DCFSM_CLOAD) | (state == `OR1200_DCFSM_CSTORE)) & biudata_error;
 
187,12 → 213,13
//
// Assert burst when doing reload of complete cache line
//
assign burst = (state == `OR1200_DCFSM_CLOAD) & tagcomp_miss & !cache_inhibit
| (state == `OR1200_DCFSM_LREFILL3)
`ifdef OR1200_DC_STORE_REFILL
| (state == `OR1200_DCFSM_SREFILL4)
`endif
;
//assign burst = (state == `OR1200_DCFSM_CLOAD) & tagcomp_miss & !cache_inhibit
// | (state == `OR1200_DCFSM_LREFILL3)
//`ifdef OR1200_DC_STORE_REFILL
// | (state == `OR1200_DCFSM_SREFILL4)
//`endif
// ;
assign burst = load & (hitmiss_eval ? !dcqmem_ci_i : !cache_inhibit);
 
//
// Main DC FSM
205,119 → 232,94
store <= #1 1'b0;
load <= #1 1'b0;
cnt <= #1 3'b000;
cache_miss <= #1 1'b0;
cache_inhibit <= #1 1'b0;
end
else
case (state) // synopsys parallel_case
`OR1200_DCFSM_IDLE :
if (dc_en & dcqmem_cycstb_i & dcqmem_we_i) begin // store
state <= #1 `OR1200_DCFSM_CSTORE;
saved_addr_r <= #1 start_addr;
hitmiss_eval <= #1 1'b1;
store <= #1 1'b1;
load <= #1 1'b0;
cache_inhibit <= #1 1'b0;
end
else if (dc_en & dcqmem_cycstb_i) begin // load
state <= #1 `OR1200_DCFSM_CLOAD;
saved_addr_r <= #1 start_addr;
hitmiss_eval <= #1 1'b1;
store <= #1 1'b0;
load <= #1 1'b1;
cache_inhibit <= #1 1'b0;
end
else begin // idle
hitmiss_eval <= #1 1'b0;
store <= #1 1'b0;
load <= #1 1'b0;
cache_inhibit <= #1 1'b0;
end
`OR1200_DCFSM_CLOAD: begin // load
if (dcqmem_cycstb_i & dcqmem_ci_i)
cache_inhibit <= #1 1'b1;
if (hitmiss_eval)
saved_addr_r[31:13] <= #1 start_addr[31:13];
if ((hitmiss_eval & !dcqmem_cycstb_i) || // load aborted (usually caused by DMMU)
(biudata_error) || // load terminated with an error
((cache_inhibit | dcqmem_ci_i) & biudata_valid)) begin // load from cache-inhibited area
state <= #1 `OR1200_DCFSM_IDLE;
hitmiss_eval <= #1 1'b0;
load <= #1 1'b0;
cache_inhibit <= #1 1'b0;
end
else if (tagcomp_miss & biudata_valid) begin // load missed, finish current external load and refill
state <= #1 `OR1200_DCFSM_LREFILL3;
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'd1;
hitmiss_eval <= #1 1'b0;
cnt <= #1 `OR1200_DCLS-2;
cache_inhibit <= #1 1'b0;
end
else if (!tagcomp_miss & !dcqmem_ci_i) begin // load hit, finish immediately
state <= #1 `OR1200_DCFSM_IDLE;
hitmiss_eval <= #1 1'b0;
load <= #1 1'b0;
cache_inhibit <= #1 1'b0;
end
else // load in-progress
hitmiss_eval <= #1 1'b0;
end
`OR1200_DCFSM_LREFILL3 : begin
if (biudata_valid && (|cnt)) begin // refill ack, more loads to come
cnt <= #1 cnt - 3'd1;
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'd1;
end
else if (biudata_valid) begin // last load of line refill
state <= #1 `OR1200_DCFSM_IDLE;
load <= #1 1'b0;
end
end
`OR1200_DCFSM_CSTORE: begin // store
if (dcqmem_cycstb_i & dcqmem_ci_i)
cache_inhibit <= #1 1'b1;
if (hitmiss_eval)
saved_addr_r[31:13] <= #1 start_addr[31:13];
if ((hitmiss_eval & !dcqmem_cycstb_i) || // store aborted (usually caused by DMMU)
(biudata_error) || // store terminated with an error
((cache_inhibit | dcqmem_ci_i) & biudata_valid)) begin // store to cache-inhibited area
state <= #1 `OR1200_DCFSM_IDLE;
hitmiss_eval <= #1 1'b0;
store <= #1 1'b0;
cache_inhibit <= #1 1'b0;
end
`OR1200_DCFSM_IDLE : begin
if (dcqmem_we_i & dc_en & dcqmem_cycstb_i) // store
state <= #1 `OR1200_DCFSM_CSTORE;
else if (!dcqmem_we_i & dc_en & dcqmem_cycstb_i) // store
state <= #1 `OR1200_DCFSM_CLOAD;
cache_inhibit <= #1 1'b0; // not dcqmem_ci_i because it is delayed (due to DTLB)
hitmiss_eval <= #1 dc_en & dcqmem_cycstb_i ;
store <= #1 dc_en & dcqmem_cycstb_i & dcqmem_we_i;
load <= #1 dc_en & dcqmem_cycstb_i & !dcqmem_we_i;
end
`OR1200_DCFSM_CLOAD: begin // load
if (!hitmiss_eval && cache_miss && !cache_inhibit && biudata_valid) begin
state <= #1 `OR1200_DCFSM_LREFILL3;
end
else if (!dcqmem_cycstb_i || !hitmiss_eval && (biudata_valid || biudata_error) || hitmiss_eval && !tagcomp_miss && !dcqmem_ci_i) begin
state <= #1 `OR1200_DCFSM_IDLE;
load <= #1 1'b0;
end
hitmiss_eval <= #1 1'b0;
cnt <= #1 `OR1200_DCLS-2;
if (hitmiss_eval) begin
cache_inhibit <= #1 dcqmem_ci_i;
cache_miss <= #1 tagcomp_miss;
end
if (hitmiss_eval)
saved_addr_r <= #1 start_addr;
else if (biudata_valid)
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'b1;
end
`OR1200_DCFSM_LREFILL3 : begin
if (!dc_en || biudata_valid && !cnt || biudata_error) begin // finish/abort
state <= #1 `OR1200_DCFSM_IDLE;
load <= #1 1'b0;
end
if (biudata_valid) begin
cnt <= #1 cnt - 1'b1;
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'b1;
end
end
`OR1200_DCFSM_CSTORE: begin // store
hitmiss_eval <= 1'b0;
if (hitmiss_eval) begin
cache_inhibit <= #1 dcqmem_ci_i;
cache_miss <= #1 tagcomp_miss;
end
if (hitmiss_eval)
saved_addr_r <= #1 start_addr;
`ifdef OR1200_DC_STORE_REFILL
else if (tagcomp_miss & biudata_valid) begin // store missed, finish write-through and doq load refill
state <= #1 `OR1200_DCFSM_SREFILL4;
hitmiss_eval <= #1 1'b0;
store <= #1 1'b0;
load <= #1 1'b1;
cnt <= #1 `OR1200_DCLS-1;
cache_inhibit <= #1 1'b0;
end
else if (biudata_valid)
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'b1;
cnt <= #1 `OR1200_DCLS-1;
if (!hitmiss_eval && cache_miss && !cache_inhibit && biudata_valid) begin
state <= #1 `OR1200_DCFSM_SREFILL4;
store <= #1 1'b0;
load <= #1 1'b1;
end
else
`endif
else if (biudata_valid) begin // store hit, finish write-through
state <= #1 `OR1200_DCFSM_IDLE;
hitmiss_eval <= #1 1'b0;
store <= #1 1'b0;
cache_inhibit <= #1 1'b0;
end
else // store write-through in-progress
hitmiss_eval <= #1 1'b0;
end
if (!dcqmem_cycstb_i || !hitmiss_eval && (biudata_error || biudata_valid)) begin
state <= #1 `OR1200_DCFSM_IDLE;
store <= #1 1'b0;
end
`ifdef OR1200_DC_STORE_REFILL
`OR1200_DCFSM_SREFILL4 : begin
if (biudata_valid && (|cnt)) begin // refill ack, more loads to come
cnt <= #1 cnt - 1'd1;
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'd1;
end
else if (biudata_valid) begin // last load of line refill
state <= #1 `OR1200_DCFSM_IDLE;
load <= #1 1'b0;
end
end
`OR1200_DCFSM_SREFILL4 : begin
if (!dc_en) begin // somebody just turned off DC therefore we abort
cnt <= #1 3'd0; // DC will have to be invalidated before
state <= #1 `OR1200_DCFSM_IDLE; // it can be turned on again
load <= #1 1'b0;
end
else if (biudata_valid && (|cnt)) begin // refill ack, more loads to come
cnt <= #1 cnt - 1'd1;
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'd1;
end
else if (biudata_valid) begin // last load of line refill
state <= #1 `OR1200_DCFSM_IDLE;
load <= #1 1'b0;
end
`endif
default:
state <= #1 `OR1200_DCFSM_IDLE;
endcase
end
 
default:
state <= #1 `OR1200_DCFSM_IDLE;
endcase
end
 
endmodule
/rtl/verilog/or1200_gmultp2_32x32.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_gmultp2_32x32.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.2 2002/07/31 02:04:35 lampret
// MAC now follows software convention (signed multiply instead of unsigned).
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
97,6 → 103,7
//
// Conversion unsigned to signed
//
/* verilator lint_off COMBDLY */
always @(X)
xi <= X;
 
105,7 → 112,7
//
always @(Y)
yi <= Y;
 
/* verilator lint_on COMBDLY */
//
// First multiply stage
//
/rtl/verilog/or1200_dpram_256x32.v
57,6 → 57,10
//
// CVS Revision History
//
// $Log: or1200_dpram_256x32.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// New
//
 
// synopsys translate_off
`include "timescale.v"
/rtl/verilog/or1200_if.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_if.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// Structure reordered and bugs fixed.
//
// Revision 1.5 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.3 2002/03/29 15:16:56 lampret
// Some of the warnings fixed.
//
89,7 → 96,7
icpu_dat_i, icpu_ack_i, icpu_err_i, icpu_adr_i, icpu_tag_i,
 
// Internal i/f
if_freeze, if_insn, if_pc, flushpipe,
if_freeze, if_insn, if_pc, if_flushpipe, saving_if_insn,
if_stall, no_more_dslot, genpc_refetch, rfe,
except_itlbmiss, except_immufault, except_ibuserr
);
119,7 → 126,8
input if_freeze;
output [31:0] if_insn;
output [31:0] if_pc;
input flushpipe;
input if_flushpipe;
output saving_if_insn;
output if_stall;
input no_more_dslot;
output genpc_refetch;
131,21 → 139,38
//
// Internal wires and regs
//
reg [31:0] insn_saved;
reg [31:0] addr_saved;
reg saved;
wire save_insn;
wire if_bypass;
reg if_bypass_reg;
reg [31:0] insn_saved;
reg [31:0] addr_saved;
reg [2:0] err_saved;
reg saved;
 
assign save_insn = (icpu_ack_i | icpu_err_i) & if_freeze & !saved;
assign saving_if_insn = !if_flushpipe & save_insn;
 
//
// IF bypass
//
assign if_bypass = icpu_adr_i[0] ? 1'b0 : if_bypass_reg | if_flushpipe;
 
always @(posedge clk or posedge rst)
if (rst)
if_bypass_reg <= #1 1'b0;
else
if_bypass_reg <= #1 if_bypass;
 
//
// IF stage insn
//
assign if_insn = icpu_err_i | no_more_dslot | rfe ? {`OR1200_OR32_NOP, 26'h041_0000} : saved ? insn_saved : icpu_ack_i ? icpu_dat_i : {`OR1200_OR32_NOP, 26'h061_0000};
assign if_pc = saved ? addr_saved : icpu_adr_i;
// assign if_stall = !icpu_err_i & !icpu_ack_i & !saved & !no_more_dslot;
assign if_insn = no_more_dslot | rfe | if_bypass ? {`OR1200_OR32_NOP, 26'h041_0000} : saved ? insn_saved : icpu_ack_i ? icpu_dat_i : {`OR1200_OR32_NOP, 26'h061_0000};
assign if_pc = saved ? addr_saved : {icpu_adr_i[31:2], 2'h0};
assign if_stall = !icpu_err_i & !icpu_ack_i & !saved;
assign genpc_refetch = saved & icpu_ack_i;
assign except_itlbmiss = icpu_err_i & (icpu_tag_i == `OR1200_ITAG_TE) & !no_more_dslot;
assign except_immufault = icpu_err_i & (icpu_tag_i == `OR1200_ITAG_PE) & !no_more_dslot;
assign except_ibuserr = icpu_err_i & (icpu_tag_i == `OR1200_ITAG_BE) & !no_more_dslot;
assign except_itlbmiss = no_more_dslot ? 1'b0 : saved ? err_saved[0] : icpu_err_i & (icpu_tag_i == `OR1200_ITAG_TE);
assign except_immufault = no_more_dslot ? 1'b0 : saved ? err_saved[1] : icpu_err_i & (icpu_tag_i == `OR1200_ITAG_PE);
assign except_ibuserr = no_more_dslot ? 1'b0 : saved ? err_saved[2] : icpu_err_i & (icpu_tag_i == `OR1200_ITAG_BE);
 
//
// Flag for saved insn/address
153,9 → 178,9
always @(posedge clk or posedge rst)
if (rst)
saved <= #1 1'b0;
else if (flushpipe)
else if (if_flushpipe)
saved <= #1 1'b0;
else if (icpu_ack_i & if_freeze & !saved)
else if (save_insn)
saved <= #1 1'b1;
else if (!if_freeze)
saved <= #1 1'b0;
166,10 → 191,10
always @(posedge clk or posedge rst)
if (rst)
insn_saved <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
else if (flushpipe)
else if (if_flushpipe)
insn_saved <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
else if (icpu_ack_i & if_freeze & !saved)
insn_saved <= #1 icpu_dat_i;
else if (save_insn)
insn_saved <= #1 icpu_err_i ? {`OR1200_OR32_NOP, 26'h041_0000} : icpu_dat_i;
else if (!if_freeze)
insn_saved <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
 
179,11 → 204,28
always @(posedge clk or posedge rst)
if (rst)
addr_saved <= #1 32'h00000000;
else if (flushpipe)
else if (if_flushpipe)
addr_saved <= #1 32'h00000000;
else if (icpu_ack_i & if_freeze & !saved)
addr_saved <= #1 icpu_adr_i;
else if (save_insn)
addr_saved <= #1 {icpu_adr_i[31:2], 2'b00};
else if (!if_freeze)
addr_saved <= #1 icpu_adr_i;
addr_saved <= #1 {icpu_adr_i[31:2], 2'b00};
 
//
// Store fetched instruction's error tags
//
always @(posedge clk or posedge rst)
if (rst)
err_saved <= #1 3'b000;
else if (if_flushpipe)
err_saved <= #1 3'b000;
else if (save_insn) begin
err_saved[0] <= #1 icpu_err_i & (icpu_tag_i == `OR1200_ITAG_TE);
err_saved[1] <= #1 icpu_err_i & (icpu_tag_i == `OR1200_ITAG_PE);
err_saved[2] <= #1 icpu_err_i & (icpu_tag_i == `OR1200_ITAG_BE);
end
else if (!if_freeze)
err_saved <= #1 3'b000;
 
 
endmodule
/rtl/verilog/or1200_mult_mac.v
44,7 → 44,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_mult_mac.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.5 2006/04/09 01:32:29 lampret
// See OR1200_MAC_SHIFTBY in or1200_defines.v for explanation of the change. Since now no more 28 bits shift for l.macrc insns however for backward compatbility it is possible to set arbitry number of shifts.
//
// Revision 1.4 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
310,7 → 317,7
mac_r <= #1 mac_r + mul_prod_r;
else if (mac_op_r3 == `OR1200_MACOP_MSB)
mac_r <= #1 mac_r - mul_prod_r;
else if (macrc_op & !ex_freeze)
else if (macrc_op && !ex_freeze)
mac_r <= #1 64'h0000_0000_0000_0000;
 
//
322,7 → 329,7
if (rst)
mac_stall_r <= #1 1'b0;
else
mac_stall_r <= #1 (|mac_op | (|mac_op_r1) | (|mac_op_r2)) & id_macrc_op
mac_stall_r <= #1 (|mac_op | (|mac_op_r1) | (|mac_op_r2)) & (id_macrc_op | mac_stall_r)
`ifdef OR1200_IMPL_DIV
| (|div_cntr)
`endif
/rtl/verilog/or1200_sb.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_sb.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.2 2002/08/22 02:18:55 lampret
// Store buffer has been tested and it works. BY default it is still disabled until uClinux confirms correct operation on FPGA board.
//
// Revision 1.1 2002/08/18 19:53:08 lampret
// Added store buffer.
//
58,6 → 65,9
// RISC clock, reset
clk, rst,
 
// Internal RISC bus (SB)
sb_en,
 
// Internal RISC bus (DC<->SB)
dcsb_dat_i, dcsb_adr_i, dcsb_cyc_i, dcsb_stb_i, dcsb_we_i, dcsb_sel_i, dcsb_cab_i,
dcsb_dat_o, dcsb_ack_o, dcsb_err_o,
77,6 → 87,11
input rst; // RISC reset
 
//
// Internal RISC bus (SB)
//
input sb_en; // SB enable
 
//
// Internal RISC bus (DC<->SB)
//
input [dw-1:0] dcsb_dat_i; // input data bus
116,6 → 131,7
wire fifo_full;
wire fifo_empty;
wire sel_sb;
reg sb_en_reg;
reg outstanding_store;
reg fifo_wr_ack;
 
137,9 → 153,20
assign sbbiu_stb_o = sel_sb ? outstanding_store : dcsb_stb_i;
assign sbbiu_we_o = sel_sb ? 1'b1 : dcsb_we_i;
assign sbbiu_cab_o = sel_sb ? 1'b0 : dcsb_cab_i;
assign sel_sb = ~fifo_empty | (fifo_empty & outstanding_store); // | fifo_wr;
assign sel_sb = sb_en_reg & (~fifo_empty | (fifo_empty & outstanding_store));
 
//
// SB enable
//
always @(posedge clk or posedge rst)
if (rst)
sb_en_reg <= 1'b0;
else if (sb_en & ~dcsb_cyc_i)
sb_en_reg <= #1 1'b1; // enable SB when there is no dcsb transfer in progress
else if (~sb_en & (~fifo_empty | (fifo_empty & outstanding_store)))
sb_en_reg <= #1 1'b0; // disable SB when there is no pending transfers from SB
 
//
// Store buffer FIFO instantiation
//
or1200_sb_fifo or1200_sb_fifo (
/rtl/verilog/or1200_dpram_32x32.v
62,7 → 62,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_dpram_32x32.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Coding style changed.
//
// Revision 1.10 2005/10/19 11:37:56 jcastillo
// Added support for RAMB16 Xilinx4/Spartan3 primitives
//
// Revision 1.9 2004/06/08 18:15:48 lampret
// Changed behavior of the simulation generic models
//
376,7 → 383,7
//
RAMB4_S16_S16 ramb4_s16_0(
.CLKA(clk_a),
.RSTA(rst_a),
.RSTA(1'b0),
.ADDRA({3'b000, addr_a}),
.DIA(16'h0000),
.ENA(ce_a),
384,7 → 391,7
.DOA(do_a[15:0]),
 
.CLKB(clk_b),
.RSTB(rst_b),
.RSTB(1'b0),
.ADDRB({3'b000, addr_b}),
.DIB(di_b[15:0]),
.ENB(ce_b),
397,7 → 404,7
//
RAMB4_S16_S16 ramb4_s16_1(
.CLKA(clk_a),
.RSTA(rst_a),
.RSTA(1'b0),
.ADDRA({3'b000, addr_a}),
.DIA(16'h0000),
.ENA(ce_a),
405,7 → 412,7
.DOA(do_a[31:16]),
 
.CLKB(clk_b),
.RSTB(rst_b),
.RSTB(1'b0),
.ADDRB({3'b000, addr_b}),
.DIB(di_b[31:16]),
.ENB(ce_b),
427,7 → 434,7
 
RAMB16_S36_S36 ramb16_s36_s36(
.CLKA(clk_a),
.SSRA(rst_a),
.SSRA(1'b0),
.ADDRA({4'b0000, addr_a}),
.DIA(32'h00000000),
.DIPA(4'h0),
437,7 → 444,7
.DOPA(),
 
.CLKB(clk_b),
.SSRB(rst_b),
.SSRB(1'b0),
.ADDRB({4'b0000, addr_b}),
.DIB(di_b),
.DIPB(4'h0),
465,8 → 472,8
.wren_a (we_a),
.inclocken_b (ce_b),
.wren_b (we_b),
.inaclr_a (rst_a),
.inaclr_b (rst_b),
.inaclr_a (1'b0),
.inaclr_b (1'b0),
.inclock_a (clk_a),
.inclock_b (clk_b),
.data_a (di_a),
/rtl/verilog/or1200_sb_fifo.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_sb_fifo.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.3 2002/11/06 13:53:41 simons
// SB mem width fixed.
//
// Revision 1.2 2002/08/22 02:18:55 lampret
// Store buffer has been tested and it works. BY default it is still disabled until uClinux confirms correct operation on FPGA board.
//
/rtl/verilog/or1200_immu_tlb.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_immu_tlb.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed, coding style changed.
//
// Revision 1.9 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.8 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
206,7 → 213,7
// Output to SPRS unit
//
assign spr_dat_o = (!spr_write & !spr_addr[`OR1200_ITLB_TM_ADDR]) ?
{vpn, tlb_index & {`OR1200_ITLB_INDXW{v}}, {`OR1200_ITLB_TAGW-7{1'b0}}, 1'b0, 5'b00000, v} :
{vpn, tlb_index, {`OR1200_ITLB_TAGW-7{1'b0}}, 1'b0, 5'b00000, v} :
(!spr_write & spr_addr[`OR1200_ITLB_TM_ADDR]) ?
{ppn, {`OR1200_IMMU_PS-8{1'b0}}, uxe, sxe, {4{1'b0}}, ci, 1'b0} :
32'h00000000;
256,41 → 263,51
//
// Instantiation of ITLB Match Registers
//
or1200_spram_64x14 itlb_mr_ram(
.clk(clk),
.rst(rst),
or1200_spram #
(
.aw(6),
.dw(14)
)
itlb_mr_ram
(
.clk(clk),
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(itlb_mr_ram_si),
.mbist_so_o(itlb_mr_ram_so),
.mbist_ctrl_i(mbist_ctrl_i),
// RAM BIST
.mbist_si_i(itlb_mr_ram_si),
.mbist_so_o(itlb_mr_ram_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.ce(tlb_mr_en),
.we(tlb_mr_we),
.oe(1'b1),
.addr(tlb_index),
.di(tlb_mr_ram_in),
.doq(tlb_mr_ram_out)
);
.ce(tlb_mr_en),
.we(tlb_mr_we),
//.oe(1'b1),
.addr(tlb_index),
.di(tlb_mr_ram_in),
.doq(tlb_mr_ram_out)
);
 
//
// Instantiation of ITLB Translate Registers
//
or1200_spram_64x22 itlb_tr_ram(
.clk(clk),
.rst(rst),
or1200_spram #
(
.aw(6),
.dw(22)
)
itlb_tr_ram
(
.clk(clk),
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(itlb_tr_ram_si),
.mbist_so_o(itlb_tr_ram_so),
.mbist_ctrl_i(mbist_ctrl_i),
// RAM BIST
.mbist_si_i(itlb_tr_ram_si),
.mbist_so_o(itlb_tr_ram_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.ce(tlb_tr_en),
.we(tlb_tr_we),
.oe(1'b1),
.addr(tlb_index),
.di(tlb_tr_ram_in),
.doq(tlb_tr_ram_out)
);
 
.ce(tlb_tr_en),
.we(tlb_tr_we),
//.oe(1'b1),
.addr(tlb_index),
.di(tlb_tr_ram_in),
.doq(tlb_tr_ram_out)
);
endmodule
/rtl/verilog/or1200_dc_top.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_dc_top.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.8 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.6.4.2 2003/12/09 11:46:48 simons
// Mbist nameing changed, Artisan ram instance signal names fixed, some synthesis waning fixed.
//
194,6 → 201,7
wire [31:0] dc_addr;
wire dcfsm_biu_read;
wire dcfsm_biu_write;
wire dcfsm_biu_sel;
reg tagcomp_miss;
wire [`OR1200_DCINDXH:`OR1200_DCLS] dctag_addr;
wire dctag_en;
204,6 → 212,7
wire dcfsm_first_miss_err;
wire dcfsm_burst;
wire dcfsm_tag_we;
wire dcfsm_tag_valid;
`ifdef OR1200_BIST
//
// RAM BIST
223,7 → 232,8
assign dctag_we = dcfsm_tag_we | dc_inv;
assign dctag_addr = dc_inv ? spr_dat_i[`OR1200_DCINDXH:`OR1200_DCLS] : dc_addr[`OR1200_DCINDXH:`OR1200_DCLS];
assign dctag_en = dc_inv | dc_en;
assign dctag_v = ~dc_inv;
//assign dctag_v = ~dc_inv;
assign dctag_v = dc_inv ? 1'b0 : dcfsm_tag_valid;
 
//
// Data to BIU is from DCRAM when DC is enabled or from LSU when
237,8 → 247,10
assign dcsb_cyc_o = (dc_en) ? dcfsm_biu_read | dcfsm_biu_write : dcqmem_cycstb_i;
assign dcsb_stb_o = (dc_en) ? dcfsm_biu_read | dcfsm_biu_write : dcqmem_cycstb_i;
assign dcsb_we_o = (dc_en) ? dcfsm_biu_write : dcqmem_we_i;
assign dcsb_sel_o = (dc_en & dcfsm_biu_read & !dcfsm_biu_write & !dcqmem_ci_i) ? 4'b1111 : dcqmem_sel_i;
assign dcsb_cab_o = (dc_en) ? dcfsm_burst : 1'b0;
//assign dcsb_sel_o = (dc_en & dcfsm_biu_read & !dcfsm_biu_write & !dcqmem_ci_i) ? 4'b1111 : dcqmem_sel_i;
assign dcsb_sel_o = (dc_en & dcfsm_burst) ? 4'b1111 : dcqmem_sel_i;
//assign dcsb_cab_o = (dc_en) ? dcsb_cyc_o & dcfsm_burst : 1'b0;
assign dcsb_cab_o = dc_en & dcfsm_burst & dcsb_cyc_o;
assign dcqmem_rty_o = ~dcqmem_ack_o;
assign dcqmem_tag_o = dcqmem_err_o ? `OR1200_DTAG_BE : dcqmem_tag_i;
 
256,7 → 268,8
//
// Select between input data generated by LSU or by BIU
//
assign to_dcram = (dcfsm_biu_read) ? dcsb_dat_i : dcqmem_dat_i;
//assign to_dcram = (dcfsm_biu_read) ? dcsb_dat_i : dcqmem_dat_i;
assign to_dcram = (dcfsm_biu_sel) ? dcsb_dat_i : dcqmem_dat_i;
 
//
// Select between data generated by DCRAM or passed by BIU
266,8 → 279,10
//
// Tag comparison
//
always @(tag or saved_addr or tag_v) begin
if ((tag != saved_addr[31:`OR1200_DCTAGL]) || !tag_v)
//always @(tag or saved_addr or tag_v) begin
// if ((tag != saved_addr[31:`OR1200_DCTAGL]) || !tag_v)
always @(tag or dcqmem_adr_i or tag_v) begin
if ((tag != dcqmem_adr_i[31:`OR1200_DCTAGL]) || !tag_v)
tagcomp_miss = 1'b1;
else
tagcomp_miss = 1'b0;
292,11 → 307,13
.dcram_we(dcram_we),
.biu_read(dcfsm_biu_read),
.biu_write(dcfsm_biu_write),
.biu_sel(dcfsm_biu_sel),
.first_hit_ack(dcfsm_first_hit_ack),
.first_miss_ack(dcfsm_first_miss_ack),
.first_miss_err(dcfsm_first_miss_err),
.burst(dcfsm_burst),
.tag_we(dcfsm_tag_we),
.tag_valid(dcfsm_tag_valid),
.dc_addr(dc_addr)
);
 
/rtl/verilog/or1200_operandmuxes.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_operandmuxes.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.2 2002/03/29 15:16:56 lampret
// Some of the warnings fixed.
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
78,7 → 85,7
 
// Internal i/f
id_freeze, ex_freeze, rf_dataa, rf_datab, ex_forw, wb_forw,
simm, sel_a, sel_b, operand_a, operand_b, muxed_b
simm, sel_a, sel_b, operand_a, operand_b, muxed_a, muxed_b
);
 
parameter width = `OR1200_OPERAND_WIDTH;
99,6 → 106,7
input [`OR1200_SEL_WIDTH-1:0] sel_b;
output [width-1:0] operand_a;
output [width-1:0] operand_b;
output [width-1:0] muxed_a;
output [width-1:0] muxed_b;
 
//
/rtl/verilog/or1200_pic.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_pic.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.4 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.3 2002/03/29 15:16:56 lampret
// Some of the warnings fixed.
//
/rtl/verilog/or1200_dmmu_top.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_dmmu_top.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.9 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.7.4.2 2003/12/09 11:46:48 simons
// Mbist nameing changed, Artisan ram instance signal names fixed, some synthesis waning fixed.
//
267,7 → 274,8
//
// Cache Inhibit
//
assign qmemdmmu_ci_o = dmmu_en ? dtlb_done & dtlb_ci : `OR1200_DMMU_CI;
//assign qmemdmmu_ci_o = dmmu_en ? dtlb_done & dtlb_ci : `OR1200_DMMU_CI;
assign qmemdmmu_ci_o = dmmu_en ? dtlb_ci : `OR1200_DMMU_CI;
 
//
// Register dcpu_adr_i's VPN for use when DMMU is not enabled but PPN is expected to come
/rtl/verilog/or1200_ic_tag.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_ic_tag.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Coding style changed.
//
// Revision 1.7 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.6 2004/04/08 11:00:46 simont
// Add support for 512B instruction cache.
//
146,30 → 153,45
// Instantiation of TAG RAM block
//
`ifdef OR1200_IC_1W_512B
or1200_spram_32x24 ic_tag0(
//or1200_spram_32x24 ic_tag0(
or1200_spram #
(
.aw(5),
.dw(24)
)
`endif
`ifdef OR1200_IC_1W_4KB
or1200_spram_256x21 ic_tag0(
//or1200_spram_256x21 ic_tag0(
or1200_spram #
(
.aw(8),
.dw(21)
)
`endif
`ifdef OR1200_IC_1W_8KB
or1200_spram_512x20 ic_tag0(
//or1200_spram_512x20 ic_tag0(
or1200_spram #
(
.aw(9),
.dw(20)
)
`endif
ic_tag0
(
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
// RAM BIST
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.clk(clk),
.rst(rst),
.ce(en),
.we(we),
.oe(1'b1),
.addr(addr),
.di(datain),
.doq({tag, tag_v})
);
 
.clk(clk),
.ce(en),
.we(we),
//.oe(1'b1),
.addr(addr),
.di(datain),
.doq({tag, tag_v})
);
`endif
 
endmodule
/rtl/verilog/or1200_except.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_except.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// Structure reordered and bugs fixed.
//
// Revision 1.17 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.16 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
157,11 → 164,14
// Internal i/f
sig_ibuserr, sig_dbuserr, sig_illegal, sig_align, sig_range, sig_dtlbmiss, sig_dmmufault,
sig_int, sig_syscall, sig_trap, sig_itlbmiss, sig_immufault, sig_tick,
branch_taken, genpc_freeze, id_freeze, ex_freeze, wb_freeze, if_stall,
if_pc, id_pc, lr_sav, flushpipe, extend_flush, except_type, except_start,
except_started, except_stop, ex_void,
ex_branch_taken, genpc_freeze, id_freeze, ex_freeze, wb_freeze, if_stall,
if_pc, id_pc, ex_pc, wb_pc, id_flushpipe, ex_flushpipe, extend_flush, except_flushpipe, except_type, except_start,
except_started, except_stop, except_trig, ex_void, abort_mvspr, branch_op,
spr_dat_ppc, spr_dat_npc, datain, du_dsr, epcr_we, eear_we, esr_we, pc_we, epcr, eear,
du_dmr1, du_hwbkpt, du_hwbkpt_ls_r,
esr, sr_we, to_sr, sr, lsu_addr, abort_ex, icpu_ack_i, icpu_err_i, dcpu_ack_i, dcpu_err_i
);
 
//
182,17 → 192,21
input sig_itlbmiss;
input sig_immufault;
input sig_tick;
input branch_taken;
input ex_branch_taken;
input genpc_freeze;
input id_freeze;
input ex_freeze;
input wb_freeze;
input if_stall;
input [31:0] if_pc;
output [31:0] id_pc;
output [31:2] lr_sav;
input [31:0] datain;
input [31:0] if_pc;
output [31:0] id_pc;
output [31:0] ex_pc;
output [31:0] wb_pc;
input [31:0] datain;
input [`OR1200_DU_DSR_WIDTH-1:0] du_dsr;
input [24:0] du_dmr1;
input du_hwbkpt;
input du_hwbkpt_ls_r;
input epcr_we;
input eear_we;
input esr_we;
204,16 → 218,21
input sr_we;
input [`OR1200_SR_WIDTH-1:0] sr;
input [31:0] lsu_addr;
output flushpipe;
input id_flushpipe;
input ex_flushpipe;
output except_flushpipe;
output extend_flush;
output [`OR1200_EXCEPT_WIDTH-1:0] except_type;
output except_start;
output except_started;
output [12:0] except_stop;
output [12:0] except_stop;
output [12:0] except_trig;
input ex_void;
input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
output [31:0] spr_dat_ppc;
output [31:0] spr_dat_npc;
output abort_ex;
output abort_mvspr;
input icpu_ack_i;
input icpu_err_i;
input dcpu_ack_i;
224,8 → 243,11
//
reg [`OR1200_EXCEPT_WIDTH-1:0] except_type;
reg [31:0] id_pc;
reg id_pc_val;
reg [31:0] ex_pc;
reg ex_pc_val;
reg [31:0] wb_pc;
reg [31:0] dl_pc;
reg [31:0] epcr;
reg [31:0] eear;
reg [`OR1200_SR_WIDTH-1:0] esr;
238,24 → 260,32
reg delayed1_ex_dslot;
reg delayed2_ex_dslot;
wire except_started;
wire [12:0] except_trig;
wire except_flushpipe;
reg [2:0] delayed_iee;
reg [2:0] delayed_tee;
wire int_pending;
wire tick_pending;
reg trace_trap ;
reg ex_freeze_prev;
reg sr_ted_prev;
reg dsr_te_prev;
reg dmr1_st_prev ;
reg dmr1_bt_prev ;
wire dsr_te = ex_freeze_prev ? dsr_te_prev : du_dsr[`OR1200_DU_DSR_TE];
wire sr_ted = ex_freeze_prev ? sr_ted_prev : sr[`OR1200_SR_TED];
wire dmr1_st = ex_freeze_prev ? dmr1_st_prev: du_dmr1[`OR1200_DU_DMR1_ST] ;
wire dmr1_bt = ex_freeze_prev ? dmr1_bt_prev: du_dmr1[`OR1200_DU_DMR1_BT] ;
 
//
// Simple combinatorial logic
//
assign except_started = extend_flush & except_start;
assign lr_sav = ex_pc[31:2];
assign except_start = (except_type != `OR1200_EXCEPT_NONE) & extend_flush;
assign int_pending = sig_int & (sr[`OR1200_SR_IEE] | (sr_we & to_sr[`OR1200_SR_IEE])) & id_pc_val & delayed_iee[2] & ~ex_freeze & ~ex_branch_taken & ~ex_dslot & ~(sr_we & ~to_sr[`OR1200_SR_IEE]);
assign tick_pending = sig_tick & (sr[`OR1200_SR_TEE] | (sr_we & to_sr[`OR1200_SR_TEE])) & id_pc_val & delayed_tee[2] & ~ex_freeze & ~ex_branch_taken & ~ex_dslot & ~(sr_we & ~to_sr[`OR1200_SR_TEE]);
assign abort_ex = sig_dbuserr | sig_dmmufault | sig_dtlbmiss | sig_align | sig_illegal | ((du_hwbkpt | trace_trap) & ex_pc_val & !sr_ted & !dsr_te); // Abort write into RF by load & other instructions
assign abort_mvspr = sig_illegal | ((du_hwbkpt | trace_trap) & ex_pc_val & !sr_ted & !dsr_te) ; // abort spr read/writes
assign spr_dat_ppc = wb_pc;
assign spr_dat_npc = ex_void ? id_pc : ex_pc;
assign except_start = (except_type != `OR1200_EXCEPT_NONE) & extend_flush;
assign int_pending = sig_int & sr[`OR1200_SR_IEE] & delayed_iee[2] & ~ex_freeze & ~branch_taken & ~ex_dslot & ~sr_we;
assign tick_pending = sig_tick & sr[`OR1200_SR_TEE] & ~ex_freeze & ~branch_taken & ~ex_dslot & ~sr_we;
assign abort_ex = sig_dbuserr | sig_dmmufault | sig_dtlbmiss | sig_align | sig_illegal; // Abort write into RF by load & other instructions
 
//
// Order defines exception detection priority
272,9 → 302,18
sig_dmmufault & ~du_dsr[`OR1200_DU_DSR_DPFE],
sig_dbuserr & ~du_dsr[`OR1200_DU_DSR_BUSEE],
sig_range & ~du_dsr[`OR1200_DU_DSR_RE],
sig_trap & ~du_dsr[`OR1200_DU_DSR_TE] & ~ex_freeze,
sig_trap & ~du_dsr[`OR1200_DU_DSR_TE],
sig_syscall & ~du_dsr[`OR1200_DU_DSR_SCE] & ~ex_freeze
};
wire trace_cond = !ex_freeze && !ex_void && (1'b0
`ifdef OR1200_DU_DMR1_ST
|| dmr1_st
`endif
`ifdef OR1200_DU_DMR1_BT
|| ((branch_op != `OR1200_BRANCHOP_NOP) && (branch_op != `OR1200_BRANCHOP_RFE) && dmr1_bt)
`endif
);
 
assign except_stop = {
tick_pending & du_dsr[`OR1200_DU_DSR_TTE],
int_pending & du_dsr[`OR1200_DU_DSR_IE],
287,10 → 326,38
sig_dmmufault & du_dsr[`OR1200_DU_DSR_DPFE],
sig_dbuserr & du_dsr[`OR1200_DU_DSR_BUSEE],
sig_range & du_dsr[`OR1200_DU_DSR_RE],
sig_trap & du_dsr[`OR1200_DU_DSR_TE] & ~ex_freeze,
sig_trap & du_dsr[`OR1200_DU_DSR_TE],
sig_syscall & du_dsr[`OR1200_DU_DSR_SCE] & ~ex_freeze
};
 
always @(posedge clk or posedge rst) begin
if (rst) begin
trace_trap <= #1 1'b0 ;
end
else if (!(trace_trap && !ex_pc_val)) begin
trace_trap <= #1 trace_cond & !dsr_te & !sr_ted ;
end
end
 
always @(posedge clk or posedge rst) begin
if (rst) begin
ex_freeze_prev <= #1 1'b0 ;
sr_ted_prev <= #1 1'b0 ;
dsr_te_prev <= #1 1'b0 ;
dmr1_st_prev <= #1 1'b0 ;
dmr1_bt_prev <= #1 1'b0 ;
end
else begin
ex_freeze_prev <= #1 ex_freeze ;
if (!ex_freeze_prev || ex_void) begin
sr_ted_prev <= #1 sr [`OR1200_SR_TED ] ;
dsr_te_prev <= #1 du_dsr [`OR1200_DU_DSR_TE ] ;
dmr1_st_prev <= #1 du_dmr1[`OR1200_DU_DMR1_ST] ;
dmr1_bt_prev <= #1 du_dmr1[`OR1200_DU_DMR1_BT] ;
end
end
end
 
//
// PC and Exception flags pipelines
//
297,14 → 364,16
always @(posedge clk or posedge rst) begin
if (rst) begin
id_pc <= #1 32'd0;
id_pc_val <= #1 1'b0 ;
id_exceptflags <= #1 3'b000;
end
else if (flushpipe) begin
id_pc <= #1 32'h0000_0000;
else if (id_flushpipe) begin
id_pc_val <= #1 1'b0 ;
id_exceptflags <= #1 3'b000;
end
else if (!id_freeze) begin
id_pc <= #1 if_pc;
id_pc_val <= #1 1'b1 ;
id_exceptflags <= #1 { sig_ibuserr, sig_itlbmiss, sig_immufault };
end
end
348,13 → 417,14
if (rst) begin
ex_dslot <= #1 1'b0;
ex_pc <= #1 32'd0;
ex_pc_val <= #1 1'b0 ;
ex_exceptflags <= #1 3'b000;
delayed1_ex_dslot <= #1 1'b0;
delayed2_ex_dslot <= #1 1'b0;
end
else if (flushpipe) begin
else if (ex_flushpipe) begin
ex_dslot <= #1 1'b0;
ex_pc <= #1 32'h0000_0000;
ex_pc_val <= #1 1'b0 ;
ex_exceptflags <= #1 3'b000;
delayed1_ex_dslot <= #1 1'b0;
delayed2_ex_dslot <= #1 1'b0;
362,13 → 432,15
else if (!ex_freeze & id_freeze) begin
ex_dslot <= #1 1'b0;
ex_pc <= #1 id_pc;
ex_pc_val <= #1 id_pc_val ;
ex_exceptflags <= #1 3'b000;
delayed1_ex_dslot <= #1 ex_dslot;
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
end
else if (!ex_freeze) begin
ex_dslot <= #1 branch_taken;
ex_dslot <= #1 ex_branch_taken;
ex_pc <= #1 id_pc;
ex_pc_val <= #1 id_pc_val ;
ex_exceptflags <= #1 id_exceptflags;
delayed1_ex_dslot <= #1 ex_dslot;
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
381,18 → 453,15
always @(posedge clk or posedge rst) begin
if (rst) begin
wb_pc <= #1 32'd0;
dl_pc <= #1 32'd0;
end
else if (!wb_freeze) begin
wb_pc <= #1 ex_pc;
dl_pc <= #1 wb_pc;
end
end
 
//
// Flush pipeline
//
assign flushpipe = except_flushpipe | pc_we | extend_flush;
 
//
// 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
412,7 → 481,7
extend_flush <= #1 1'b0;
epcr <= #1 32'b0;
eear <= #1 32'b0;
esr <= #1 {1'b1, {`OR1200_SR_WIDTH-2{1'b0}}, 1'b1};
esr <= #1 {2'h1, {`OR1200_SR_WIDTH-3{1'b0}}, 1'b1};
extend_flush_last <= #1 1'b0;
end
else begin
430,35 → 499,27
`ifdef OR1200_EXCEPT_TICK
13'b1_xxxx_xxxx_xxxx: begin
except_type <= #1 `OR1200_EXCEPT_TICK;
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
epcr <= #1 id_pc;
//epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
end
`endif
`ifdef OR1200_EXCEPT_INT
13'b0_1xxx_xxxx_xxxx: begin
except_type <= #1 `OR1200_EXCEPT_INT;
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
epcr <= #1 id_pc;
//epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
end
`endif
`ifdef OR1200_EXCEPT_ITLBMISS
13'b0_01xx_xxxx_xxxx: begin
except_type <= #1 `OR1200_EXCEPT_ITLBMISS;
//
// itlb miss exception and active ex_dslot caused wb_pc to put into eear instead of +4 address of ex_pc (or id_pc since it was equal to ex_pc?)
// eear <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
// mmu-icdc-O2 ex_pc only OK when no ex_dslot eear <= #1 ex_dslot ? ex_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
// mmu-icdc-O2 ex_pc only OK when no ex_dslot epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
eear <= #1 ex_dslot ? ex_pc : ex_pc;
epcr <= #1 ex_dslot ? wb_pc : ex_pc;
// eear <= #1 ex_dslot ? ex_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
// epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
end
`endif
`ifdef OR1200_EXCEPT_IPF
13'b0_001x_xxxx_xxxx: begin
except_type <= #1 `OR1200_EXCEPT_IPF;
//
// ipf exception and active ex_dslot caused wb_pc to put into eear instead of +4 address of ex_pc (or id_pc since it was equal to ex_pc?)
// eear <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
eear <= #1 ex_dslot ? ex_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : delayed2_ex_dslot ? id_pc : id_pc;
end
488,7 → 549,7
13'b0_0000_001x_xxxx: begin
except_type <= #1 `OR1200_EXCEPT_DTLBMISS;
eear <= #1 lsu_addr;
epcr <= #1 ex_dslot ? wb_pc : ex_pc;
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? dl_pc : ex_pc;
end
`endif
`ifdef OR1200_EXCEPT_DPF
495,7 → 556,7
13'b0_0000_0001_xxxx: begin
except_type <= #1 `OR1200_EXCEPT_DPF;
eear <= #1 lsu_addr;
epcr <= #1 ex_dslot ? wb_pc : ex_pc;
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? dl_pc : ex_pc;
end
`endif
`ifdef OR1200_EXCEPT_BUSERR
502,7 → 563,7
13'b0_0000_0000_1xxx: begin // Data Bus Error
except_type <= #1 `OR1200_EXCEPT_BUSERR;
eear <= #1 lsu_addr;
epcr <= #1 ex_dslot ? wb_pc : ex_pc;
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? dl_pc : ex_pc;
end
`endif
`ifdef OR1200_EXCEPT_RANGE
513,7 → 574,7
`endif
`ifdef OR1200_EXCEPT_TRAP 13'b0_0000_0000_001x: begin
except_type <= #1 `OR1200_EXCEPT_TRAP;
epcr <= #1 ex_dslot ? wb_pc : ex_pc;
epcr <= #1 ex_dslot ? wb_pc : delayed1_ex_dslot ? id_pc : ex_pc;
end
`endif
`ifdef OR1200_EXCEPT_SYSCALL
536,7 → 597,7
if (eear_we)
eear <= #1 datain;
if (esr_we)
esr <= #1 {1'b1, datain[`OR1200_SR_WIDTH-2:0]};
esr <= #1 {datain[`OR1200_SR_WIDTH-1], 1'b1, datain[`OR1200_SR_WIDTH-3:0]};
end
`OR1200_EXCEPTFSM_FLU1:
if (icpu_ack_i | icpu_err_i | genpc_freeze)
/rtl/verilog/or1200_ic_ram.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_ic_ram.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Coding style changed.
//
// Revision 1.6 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.5 2004/04/08 11:00:46 simont
// Add support for 512B instruction cache.
//
136,30 → 143,42
// Instantiation of IC RAM block
//
`ifdef OR1200_IC_1W_512B
or1200_spram_128x32 ic_ram0(
or1200_spram #
(
.aw(9),
.dw(32)
)
`endif
`ifdef OR1200_IC_1W_4KB
or1200_spram_1024x32 ic_ram0(
or1200_spram #
(
.aw(10),
.dw(32)
)
`endif
`ifdef OR1200_IC_1W_8KB
or1200_spram_2048x32 ic_ram0(
or1200_spram #
(
.aw(11),
.dw(32)
)
`endif
ic_ram0
(
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
// RAM BIST
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.clk(clk),
.rst(rst),
.ce(en),
.we(we[0]),
.oe(1'b1),
.addr(addr),
.di(datain),
.doq(dataout)
);
 
.clk(clk),
.ce(en),
.we(we[0]),
//.oe(1'b1),
.addr(addr),
.di(datain),
.doq(dataout)
);
`endif
 
endmodule
/rtl/verilog/or1200_genpc.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_genpc.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// Structure reordered and bugs fixed.
//
// Revision 1.10 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.9 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
114,10 → 121,11
icpu_rty_i, icpu_adr_i,
 
// Internal i/f
branch_op, except_type, except_prefix,
branch_addrofs, lr_restor, flag, taken, except_start,
binsn_addr, epcr, spr_dat_i, spr_pc_we, genpc_refetch,
genpc_freeze, genpc_stop_prefetch, no_more_dslot
pre_branch_op, branch_op, except_type, except_prefix,
id_branch_addrtarget, ex_branch_addrtarget, muxed_b, operand_b,
flag, flagforw, ex_branch_taken, except_start,
epcr, spr_dat_i, spr_pc_we, genpc_refetch,
genpc_freeze, no_more_dslot
);
 
//
143,20 → 151,22
//
// Internal i/f
//
input [`OR1200_BRANCHOP_WIDTH-1:0] pre_branch_op;
input [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
input [`OR1200_EXCEPT_WIDTH-1:0] except_type;
input except_prefix;
input [31:2] branch_addrofs;
input [31:0] lr_restor;
input [31:2] id_branch_addrtarget;
input [31:2] ex_branch_addrtarget;
input [31:0] muxed_b;
input [31:0] operand_b;
input flag;
output taken;
input flagforw;
output ex_branch_taken;
input except_start;
input [31:2] binsn_addr;
input [31:0] epcr;
input [31:0] spr_dat_i;
input spr_pc_we;
input genpc_refetch;
input genpc_stop_prefetch;
input genpc_freeze;
input no_more_dslot;
 
163,24 → 173,23
//
// Internal wires and regs
//
reg [31:2] pcreg_default;
wire [31:0] pcreg_boot;
reg pcreg_select;
reg [31:2] pcreg;
reg [31:0] pc;
reg taken; /* Set to in case of jump or taken branch */
reg ex_branch_taken; /* Set to in case of jump or taken branch */
reg genpc_refetch_r;
 
//
// Address of insn to be fecthed
//
assign icpu_adr_o = !no_more_dslot & !except_start & !spr_pc_we & (icpu_rty_i | genpc_refetch) ? icpu_adr_i : pc;
// assign icpu_adr_o = !except_start & !spr_pc_we & (icpu_rty_i | genpc_refetch) ? icpu_adr_i : pc;
assign icpu_adr_o = !no_more_dslot & !except_start & !spr_pc_we & (icpu_rty_i | genpc_refetch) ? icpu_adr_i : {pc[31:2], 1'b0, ex_branch_taken|spr_pc_we};
 
//
// Control access to IC subsystem
//
// assign icpu_cycstb_o = !genpc_freeze & !no_more_dslot;
assign icpu_cycstb_o = !genpc_freeze; // works, except remaining raised cycstb during long load/store
//assign icpu_cycstb_o = !(genpc_freeze | genpc_refetch & genpc_refetch_r);
//assign icpu_cycstb_o = !(genpc_freeze | genpc_stop_prefetch);
assign icpu_cycstb_o = ~(genpc_freeze | (|pre_branch_op && !icpu_rty_i));
assign icpu_sel_o = 4'b1111;
assign icpu_tag_o = `OR1200_ITAG_NI;
 
198,49 → 207,40
//
// Async calculation of new PC value. This value is used for addressing the IC.
//
always @(pcreg or branch_addrofs or binsn_addr or flag or branch_op or except_type
or except_start or lr_restor or epcr or spr_pc_we or spr_dat_i or except_prefix) begin
always @(pcreg or ex_branch_addrtarget or flag or branch_op or except_type
or except_start or operand_b or epcr or spr_pc_we or spr_dat_i or except_prefix) begin
casex ({spr_pc_we, except_start, branch_op}) // synopsys parallel_case
{2'b00, `OR1200_BRANCHOP_NOP}: begin
pc = {pcreg + 30'd1, 2'b0};
taken = 1'b0;
ex_branch_taken = 1'b0;
end
{2'b00, `OR1200_BRANCHOP_J}: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_J: pc <= branch_addrofs %h", $time, branch_addrofs);
$display("%t: BRANCHOP_J: pc <= ex_branch_addrtarget %h", $time, ex_branch_addrtarget);
// synopsys translate_on
`endif
pc = {branch_addrofs, 2'b0};
taken = 1'b1;
pc = {ex_branch_addrtarget, 2'b00};
ex_branch_taken = 1'b1;
end
{2'b00, `OR1200_BRANCHOP_JR}: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_JR: pc <= lr_restor %h", $time, lr_restor);
$display("%t: BRANCHOP_JR: pc <= operand_b %h", $time, operand_b);
// synopsys translate_on
`endif
pc = lr_restor;
taken = 1'b1;
pc = operand_b;
ex_branch_taken = 1'b1;
end
{2'b00, `OR1200_BRANCHOP_BAL}: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BAL: pc %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
// synopsys translate_on
`endif
pc = {binsn_addr + branch_addrofs, 2'b0};
taken = 1'b1;
end
{2'b00, `OR1200_BRANCHOP_BF}:
if (flag) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BF: pc %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
$display("%t: BRANCHOP_BF: pc <= ex_branch_addrtarget %h", $time, ex_branch_addrtarget);
// synopsys translate_on
`endif
pc = {binsn_addr + branch_addrofs, 2'b0};
taken = 1'b1;
pc = {ex_branch_addrtarget, 2'b00};
ex_branch_taken = 1'b1;
end
else begin
`ifdef OR1200_VERBOSE
249,26 → 249,26
// synopsys translate_on
`endif
pc = {pcreg + 30'd1, 2'b0};
taken = 1'b0;
ex_branch_taken = 1'b0;
end
{2'b00, `OR1200_BRANCHOP_BNF}:
if (flag) begin
pc = {pcreg + 30'd1, 2'b0};
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BNF: not taken", $time);
// synopsys translate_on
`endif
taken = 1'b0;
pc = {pcreg + 30'd1, 2'b0};
ex_branch_taken = 1'b0;
end
else begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BNF: pc %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
$display("%t: BRANCHOP_BNF: pc <= ex_branch_addrtarget %h", $time, ex_branch_addrtarget);
// synopsys translate_on
`endif
pc = {binsn_addr + branch_addrofs, 2'b0};
taken = 1'b1;
pc = {ex_branch_addrtarget, 2'b00};
ex_branch_taken = 1'b1;
end
{2'b00, `OR1200_BRANCHOP_RFE}: begin
`ifdef OR1200_VERBOSE
277,7 → 277,7
// synopsys translate_on
`endif
pc = epcr;
taken = 1'b1;
ex_branch_taken = 1'b1;
end
{2'b01, 3'bxxx}: begin
`ifdef OR1200_VERBOSE
286,7 → 286,7
// synopsys translate_on
`endif
pc = {(except_prefix ? `OR1200_EXCEPT_EPH1_P : `OR1200_EXCEPT_EPH0_P), except_type, `OR1200_EXCEPT_V};
taken = 1'b1;
ex_branch_taken = 1'b1;
end
default: begin
`ifdef OR1200_VERBOSE
295,7 → 295,7
// synopsys translate_on
`endif
pc = spr_dat_i;
taken = 1'b0;
ex_branch_taken = 1'b0;
end
endcase
end
304,13 → 304,32
// PC register
//
always @(posedge clk or posedge rst)
if (rst)
// pcreg <= #1 30'd63;
pcreg <= #1 ({(except_prefix ? `OR1200_EXCEPT_EPH1_P : `OR1200_EXCEPT_EPH0_P), `OR1200_EXCEPT_RESET, `OR1200_EXCEPT_V} - 1) >> 2;
else if (spr_pc_we)
pcreg <= #1 spr_dat_i[31:2];
else if (no_more_dslot | except_start | !genpc_freeze & !icpu_rty_i & !genpc_refetch)
// else if (except_start | !genpc_freeze & !icpu_rty_i & !genpc_refetch)
pcreg <= #1 pc[31:2];
// default value
if (rst) begin
//pcreg_default <= #1 30'd63;
pcreg_default <= #1 /*30'd63 */ `OR1200_BOOT_PCREG_DEFAULT; // jb
pcreg_select <= #1 1'b1; // select async. value due to reset state
end
// selected value (different from default) is written into FF after reset state
else if (pcreg_select) begin
pcreg_default <= #1 pcreg_boot[31:2]; // dynamic value can only be assigned to FF out of reset!
pcreg_select <= #1 1'b0; // select FF value
end
else if (spr_pc_we) begin
pcreg_default <= #1 spr_dat_i[31:2];
end
else if (no_more_dslot | except_start | !genpc_freeze & !icpu_rty_i & !genpc_refetch) begin
pcreg_default <= #1 pc[31:2];
end
 
// select async. value for pcreg after reset - PC jumps to the address selected after boot!
//assign pcreg_boot = {(except_prefix ? `OR1200_EXCEPT_EPH1_P : `OR1200_EXCEPT_EPH0_P), `OR1200_EXCEPT_RESET, `OR1200_EXCEPT_V} - 1;
assign pcreg_boot = `OR1200_BOOT_ADR; // changed JB
 
always @(pcreg_boot or pcreg_default or pcreg_select)
if (pcreg_select)
pcreg = pcreg_boot[31:2]; // async. value is selected due to reset state
else
pcreg = pcreg_default ; // FF value is selected 2nd clock after reset state
 
endmodule
/rtl/verilog/or1200_mem2reg.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_mem2reg.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.5 2002/09/03 22:28:21 lampret
// As per Taylor Su suggestion all case blocks are full case by default and optionally (OR1200_CASE_DEFAULT) can be disabled to increase clock frequncy.
//
// Revision 1.4 2002/03/29 15:16:56 lampret
// Some of the warnings fixed.
//
/rtl/verilog/or1200_reg2mem.v
43,7 → 43,13
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_reg2mem.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// No update
//
// Revision 1.2 2002/03/29 15:16:56 lampret
// Some of the warnings fixed.
//
// Revision 1.1 2002/01/03 08:16:15 lampret
// New prefixes for RTL files, prefixed module names. Updated cache controllers and MMUs.
//
/rtl/verilog/or1200_ic_fsm.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_ic_fsm.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed.
//
// Revision 1.10 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.9 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
173,7 → 180,7
// Assert for cache miss first word stored/loaded OK
// Assert for cache miss first word stored/loaded with an error
//
assign first_hit_ack = (state == `OR1200_ICFSM_CFETCH) & hitmiss_eval & !tagcomp_miss & !cache_inhibit & !icqmem_ci_i;
assign first_hit_ack = (state == `OR1200_ICFSM_CFETCH) & hitmiss_eval & !tagcomp_miss & !cache_inhibit;
assign first_miss_ack = (state == `OR1200_ICFSM_CFETCH) & biudata_valid;
assign first_miss_err = (state == `OR1200_ICFSM_CFETCH) & biudata_error;
 
203,7 → 210,7
saved_addr_r <= #1 start_addr;
hitmiss_eval <= #1 1'b1;
load <= #1 1'b1;
cache_inhibit <= #1 1'b0;
cache_inhibit <= #1 icqmem_ci_i;
end
else begin // idle
hitmiss_eval <= #1 1'b0;
231,10 → 238,6
cnt <= #1 `OR1200_ICLS-2;
cache_inhibit <= #1 1'b0;
end
else if (!tagcomp_miss & !icqmem_ci_i) begin // fetch hit, finish immediately
saved_addr_r <= #1 start_addr;
cache_inhibit <= #1 1'b0;
end
else if (!icqmem_cycstb_i) begin // fetch aborted (usually caused by exception)
state <= #1 `OR1200_ICFSM_IDLE;
hitmiss_eval <= #1 1'b0;
241,11 → 244,21
load <= #1 1'b0;
cache_inhibit <= #1 1'b0;
end
else if (!tagcomp_miss & !icqmem_ci_i) begin // fetch hit, finish immediately
saved_addr_r <= #1 start_addr;
cache_inhibit <= #1 1'b0;
end
else // fetch in-progress
hitmiss_eval <= #1 1'b0;
end
`OR1200_ICFSM_LREFILL3 : begin
if (biudata_valid && (|cnt)) begin // refill ack, more fetchs to come
if (!ic_en) begin // abort because IC has just been turned off
state <= #1 `OR1200_ICFSM_IDLE; // invalidate before IC can be turned on
saved_addr_r <= #1 start_addr;
hitmiss_eval <= #1 1'b0;
load <= #1 1'b0;
end
else if (biudata_valid && (|cnt)) begin // refill ack, more fetchs to come
cnt <= #1 cnt - 3'd1;
saved_addr_r[3:2] <= #1 saved_addr_r[3:2] + 1'd1;
end
/rtl/verilog/or1200_lsu.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_lsu.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// Structure reordered and bugs fixed.
//
// Revision 1.5 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
// Revision 1.4 2002/03/29 15:16:56 lampret
// Some of the warnings fixed.
//
82,10 → 89,14
`include "or1200_defines.v"
 
module or1200_lsu(
// Clock and Reset
clk, rst,
 
// Internal i/f
addrbase, addrofs, lsu_op, lsu_datain, lsu_dataout, lsu_stall, lsu_unstall,
du_stall, except_align, except_dtlbmiss, except_dmmufault, except_dbuserr,
id_addrbase, ex_addrbase, id_addrofs, ex_addrofs, id_lsu_op,
lsu_datain, lsu_dataout, lsu_stall, lsu_unstall,
du_stall, except_align, except_dtlbmiss, except_dmmufault, except_dbuserr,
id_freeze, ex_freeze, flushpipe,
 
// External i/f to DC
dcpu_adr_o, dcpu_cycstb_o, dcpu_we_o, dcpu_sel_o, dcpu_tag_o, dcpu_dat_o,
100,11 → 111,19
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// Internal i/f
//
input [31:0] addrbase;
input [31:0] addrofs;
input [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
input [31:0] id_addrbase;
input [31:0] ex_addrbase;
input [31:0] id_addrofs;
input [31:0] ex_addrofs;
input [`OR1200_LSUOP_WIDTH-1:0] id_lsu_op;
input [dw-1:0] lsu_datain;
output [dw-1:0] lsu_dataout;
output lsu_stall;
114,6 → 133,9
output except_dtlbmiss;
output except_dmmufault;
output except_dbuserr;
input id_freeze;
input ex_freeze;
input flushpipe;
 
//
// External i/f to DC
135,13 → 157,58
//
reg [3:0] dcpu_sel_o;
 
reg [`OR1200_LSUOP_WIDTH-1:0] ex_lsu_op;
wire [`OR1200_LSUEA_PRECALC:0] id_precalc_sum;
reg [`OR1200_LSUEA_PRECALC:0] dcpu_adr_r;
reg except_align;
 
//
// ex_lsu_op
//
always @(posedge clk or posedge rst) begin
if (rst)
ex_lsu_op <= #1 `OR1200_LSUOP_NOP;
else if (!ex_freeze & id_freeze | flushpipe)
ex_lsu_op <= #1 `OR1200_LSUOP_NOP;
else if (!ex_freeze)
ex_lsu_op <= #1 id_lsu_op;
end
 
//
// Precalculate part of load/store EA in ID stage
//
assign id_precalc_sum = id_addrbase[`OR1200_LSUEA_PRECALC-1:0] +
id_addrofs[`OR1200_LSUEA_PRECALC-1:0];
 
always @(posedge clk or posedge rst) begin
if (rst)
dcpu_adr_r <= #1 {`OR1200_LSUEA_PRECALC{1'b0}};
else if (!ex_freeze)
dcpu_adr_r <= #1 id_precalc_sum;
end
 
//
// Generate except_align in ID stage
//
always @(posedge clk or posedge rst) begin
if (rst)
except_align <= #1 1'b0;
else if (!ex_freeze & id_freeze | flushpipe)
except_align <= #1 1'b0;
else if (!ex_freeze)
except_align <= #1 ((id_lsu_op == `OR1200_LSUOP_SH) |
(id_lsu_op == `OR1200_LSUOP_LHZ) |
(id_lsu_op == `OR1200_LSUOP_LHS)) & id_precalc_sum[0]
| ((id_lsu_op == `OR1200_LSUOP_SW) |
(id_lsu_op == `OR1200_LSUOP_LWZ) |
(id_lsu_op == `OR1200_LSUOP_LWS)) & |id_precalc_sum[1:0];
end
 
//
// Internal I/F assignments
//
assign lsu_stall = dcpu_rty_i & dcpu_cycstb_o;
assign lsu_unstall = dcpu_ack_i;
assign except_align = ((lsu_op == `OR1200_LSUOP_SH) | (lsu_op == `OR1200_LSUOP_LHZ) | (lsu_op == `OR1200_LSUOP_LHS)) & dcpu_adr_o[0]
| ((lsu_op == `OR1200_LSUOP_SW) | (lsu_op == `OR1200_LSUOP_LWZ) | (lsu_op == `OR1200_LSUOP_LWS)) & |dcpu_adr_o[1:0];
assign except_dtlbmiss = dcpu_err_i & (dcpu_tag_i == `OR1200_DTAG_TE);
assign except_dmmufault = dcpu_err_i & (dcpu_tag_i == `OR1200_DTAG_PE);
assign except_dbuserr = dcpu_err_i & (dcpu_tag_i == `OR1200_DTAG_BE);
149,12 → 216,15
//
// External I/F assignments
//
assign dcpu_adr_o = addrbase + addrofs;
assign dcpu_cycstb_o = du_stall | lsu_unstall | except_align ? 1'b0 : |lsu_op;
assign dcpu_we_o = lsu_op[3];
assign dcpu_adr_o[31:`OR1200_LSUEA_PRECALC] = ex_addrbase[31:`OR1200_LSUEA_PRECALC] +
ex_addrofs[31:`OR1200_LSUEA_PRECALC] +
dcpu_adr_r[`OR1200_LSUEA_PRECALC]; // carry
assign dcpu_adr_o[`OR1200_LSUEA_PRECALC-1:0] = dcpu_adr_r[`OR1200_LSUEA_PRECALC-1:0];
assign dcpu_cycstb_o = du_stall | lsu_unstall | except_align ? 1'b0 : |ex_lsu_op;
assign dcpu_we_o = ex_lsu_op[3];
assign dcpu_tag_o = dcpu_cycstb_o ? `OR1200_DTAG_ND : `OR1200_DTAG_IDLE;
always @(lsu_op or dcpu_adr_o)
casex({lsu_op, dcpu_adr_o[1:0]})
always @(ex_lsu_op or dcpu_adr_o)
casex({ex_lsu_op, dcpu_adr_o[1:0]})
{`OR1200_LSUOP_SB, 2'b00} : dcpu_sel_o = 4'b1000;
{`OR1200_LSUOP_SB, 2'b01} : dcpu_sel_o = 4'b0100;
{`OR1200_LSUOP_SB, 2'b10} : dcpu_sel_o = 4'b0010;
177,7 → 247,7
//
or1200_mem2reg or1200_mem2reg(
.addr(dcpu_adr_o[1:0]),
.lsu_op(lsu_op),
.lsu_op(ex_lsu_op),
.memdata(dcpu_dat_i),
.regdata(lsu_dataout)
);
187,7 → 257,7
//
or1200_reg2mem or1200_reg2mem(
.addr(dcpu_adr_o[1:0]),
.lsu_op(lsu_op),
.lsu_op(ex_lsu_op),
.regdata(lsu_datain),
.memdata(dcpu_dat_o)
);
/rtl/verilog/or1200_dmmu_tlb.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_dmmu_tlb.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed, coding style changed.
//
// Revision 1.7 2004/06/08 18:17:36 lampret
// Non-functional changes. Coding style fixes.
//
// Revision 1.6 2004/04/05 08:29:57 lampret
// Merged branch_qmem into main tree.
//
204,7 → 211,7
// Output to SPRS unit
//
assign spr_dat_o = (spr_cs & !spr_write & !spr_addr[`OR1200_DTLB_TM_ADDR]) ?
{vpn, tlb_index & {`OR1200_DTLB_INDXW{v}}, {`OR1200_DTLB_TAGW-7{1'b0}}, 1'b0, 5'b00000, v} :
{vpn, tlb_index, {`OR1200_DTLB_TAGW-7{1'b0}}, 1'b0, 5'b00000, v} :
(spr_cs & !spr_write & spr_addr[`OR1200_DTLB_TM_ADDR]) ?
{ppn, {`OR1200_DMMU_PS-10{1'b0}}, swe, sre, uwe, ure, {4{1'b0}}, ci, 1'b0} :
32'h00000000;
248,41 → 255,51
//
// Instantiation of DTLB Match Registers
//
or1200_spram_64x14 dtlb_mr_ram(
.clk(clk),
.rst(rst),
//or1200_spram_64x14 dtlb_mr_ram(
or1200_spram #
(
.aw(6),
.dw(14)
)
dtlb_ram
(
.clk(clk),
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(mbist_mr_si),
.mbist_so_o(mbist_mr_so),
.mbist_ctrl_i(mbist_ctrl_i),
// RAM BIST
.mbist_si_i(mbist_mr_si),
.mbist_so_o(mbist_mr_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.ce(tlb_mr_en),
.we(tlb_mr_we),
.oe(1'b1),
.addr(tlb_index),
.di(tlb_mr_ram_in),
.doq(tlb_mr_ram_out)
);
 
//
// Instantiation of DTLB Translate Registers
//
or1200_spram_64x24 dtlb_tr_ram(
.clk(clk),
.rst(rst),
.ce(tlb_mr_en),
.we(tlb_mr_we),
.addr(tlb_index),
.di(tlb_mr_ram_in),
.doq(tlb_mr_ram_out)
);
//
// Instantiation of DTLB Translate Registers
//
//or1200_spram_64x24 dtlb_tr_ram(
or1200_spram #
(
.aw(6),
.dw(24)
)
dtlb_tr_ram
(
.clk(clk),
`ifdef OR1200_BIST
// RAM BIST
.mbist_si_i(mbist_tr_si),
.mbist_so_o(mbist_tr_so),
.mbist_ctrl_i(mbist_ctrl_i),
// RAM BIST
.mbist_si_i(mbist_tr_si),
.mbist_so_o(mbist_tr_so),
.mbist_ctrl_i(mbist_ctrl_i),
`endif
.ce(tlb_tr_en),
.we(tlb_tr_we),
.oe(1'b1),
.addr(tlb_index),
.di(tlb_tr_ram_in),
.doq(tlb_tr_ram_out)
);
 
endmodule
.ce(tlb_tr_en),
.we(tlb_tr_we),
.addr(tlb_index),
.di(tlb_tr_ram_in),
.doq(tlb_tr_ram_out)
);
endmodule // or1200_dmmu_tlb
/rtl/verilog/or1200_rfram_generic.v
42,7 → 42,15
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
// $Log: not supported by cvs2svn $
//
// $Log: or1200_rfram_generic.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Defines added, coding style changed.
//
// Revision 1.3 2004/06/08 18:16:32 lampret
// GPR0 hardwired to zero.
//
// Revision 1.2 2002/09/03 22:28:21 lampret
// As per Taylor Su suggestion all case blocks are full case by default and optionally (OR1200_CASE_DEFAULT) can be disabled to increase clock frequncy.
//
110,10 → 118,39
//
reg [aw-1:0] intaddr_a;
reg [aw-1:0] intaddr_b;
`ifdef OR1200_RFRAM_16REG
reg [16*dw-1:0] mem;
`else
reg [32*dw-1:0] mem;
`endif
reg [dw-1:0] do_a;
reg [dw-1:0] do_b;
 
// Function to access GPRs (for use by Verilator). No need to hide this one
// from the simulator, since it has an input (as required by IEEE 1364-2001).
function [31:0] get_gpr;
// verilator public
input [aw-1:0] gpr_no;
 
get_gpr = { mem[gpr_no*32 + 31], mem[gpr_no*32 + 30],
mem[gpr_no*32 + 29], mem[gpr_no*32 + 28],
mem[gpr_no*32 + 27], mem[gpr_no*32 + 26],
mem[gpr_no*32 + 25], mem[gpr_no*32 + 24],
mem[gpr_no*32 + 23], mem[gpr_no*32 + 22],
mem[gpr_no*32 + 21], mem[gpr_no*32 + 20],
mem[gpr_no*32 + 19], mem[gpr_no*32 + 18],
mem[gpr_no*32 + 17], mem[gpr_no*32 + 16],
mem[gpr_no*32 + 15], mem[gpr_no*32 + 14],
mem[gpr_no*32 + 13], mem[gpr_no*32 + 12],
mem[gpr_no*32 + 11], mem[gpr_no*32 + 10],
mem[gpr_no*32 + 9], mem[gpr_no*32 + 8],
mem[gpr_no*32 + 7], mem[gpr_no*32 + 6],
mem[gpr_no*32 + 5], mem[gpr_no*32 + 4],
mem[gpr_no*32 + 3], mem[gpr_no*32 + 2],
mem[gpr_no*32 + 1], mem[gpr_no*32 + 0] };
endfunction // get_gpr
 
//
// Write port
//
123,7 → 160,6
end
else if (ce_w & we_w)
case (addr_w) // synopsys parallel_case
5'd00: mem[32*0+31:32*0] <= #1 32'h0000_0000;
5'd01: mem[32*1+31:32*1] <= #1 di_w;
5'd02: mem[32*2+31:32*2] <= #1 di_w;
5'd03: mem[32*3+31:32*3] <= #1 di_w;
139,6 → 175,8
5'd13: mem[32*13+31:32*13] <= #1 di_w;
5'd14: mem[32*14+31:32*14] <= #1 di_w;
5'd15: mem[32*15+31:32*15] <= #1 di_w;
`ifdef OR1200_RFRAM_16REG
`else
5'd16: mem[32*16+31:32*16] <= #1 di_w;
5'd17: mem[32*17+31:32*17] <= #1 di_w;
5'd18: mem[32*18+31:32*18] <= #1 di_w;
154,7 → 192,9
5'd28: mem[32*28+31:32*28] <= #1 di_w;
5'd29: mem[32*29+31:32*29] <= #1 di_w;
5'd30: mem[32*30+31:32*30] <= #1 di_w;
default: mem[32*31+31:32*31] <= #1 di_w;
5'd31: mem[32*31+31:32*31] <= #1 di_w;
`endif
default: mem[32*0+31:32*0] <= #1 32'h0000_0000;
endcase
 
//
169,7 → 209,6
 
always @(mem or intaddr_a)
case (intaddr_a) // synopsys parallel_case
5'd00: do_a = 32'h0000_0000;
5'd01: do_a = mem[32*1+31:32*1];
5'd02: do_a = mem[32*2+31:32*2];
5'd03: do_a = mem[32*3+31:32*3];
185,6 → 224,8
5'd13: do_a = mem[32*13+31:32*13];
5'd14: do_a = mem[32*14+31:32*14];
5'd15: do_a = mem[32*15+31:32*15];
`ifdef OR1200_RFRAM_16REG
`else
5'd16: do_a = mem[32*16+31:32*16];
5'd17: do_a = mem[32*17+31:32*17];
5'd18: do_a = mem[32*18+31:32*18];
200,7 → 241,9
5'd28: do_a = mem[32*28+31:32*28];
5'd29: do_a = mem[32*29+31:32*29];
5'd30: do_a = mem[32*30+31:32*30];
default: do_a = mem[32*31+31:32*31];
5'd31: do_a = mem[32*31+31:32*31];
`endif
default: do_a = 32'h0000_0000;
endcase
 
//
215,7 → 258,6
 
always @(mem or intaddr_b)
case (intaddr_b) // synopsys parallel_case
5'd00: do_b = 32'h0000_0000;
5'd01: do_b = mem[32*1+31:32*1];
5'd02: do_b = mem[32*2+31:32*2];
5'd03: do_b = mem[32*3+31:32*3];
231,6 → 273,8
5'd13: do_b = mem[32*13+31:32*13];
5'd14: do_b = mem[32*14+31:32*14];
5'd15: do_b = mem[32*15+31:32*15];
`ifdef OR1200_RFRAM_16REG
`else
5'd16: do_b = mem[32*16+31:32*16];
5'd17: do_b = mem[32*17+31:32*17];
5'd18: do_b = mem[32*18+31:32*18];
246,7 → 290,9
5'd28: do_b = mem[32*28+31:32*28];
5'd29: do_b = mem[32*29+31:32*29];
5'd30: do_b = mem[32*30+31:32*30];
default: do_b = mem[32*31+31:32*31];
5'd31: do_b = mem[32*31+31:32*31];
`endif
default: do_b = 32'h0000_0000;
endcase
 
endmodule
/rtl/verilog/or1200_ctrl.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_ctrl.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Major update:
// Structure reordered and bugs fixed.
//
// Revision 1.13 2005/01/13 11:03:43 phoenix
// revert to the old l.sfxxi behavior
//
// Revision 1.12 2005/01/07 09:31:07 andreje
// sign/zero extension for l.sfxxi instructions corrected
//
128,12 → 135,15
clk, rst,
 
// Internal i/f
id_freeze, ex_freeze, wb_freeze, flushpipe, if_insn, ex_insn, branch_op, branch_taken,
except_flushpipe, extend_flush, if_flushpipe, id_flushpipe, ex_flushpipe, wb_flushpipe,
id_freeze, ex_freeze, wb_freeze, if_insn, id_insn, ex_insn, abort_mvspr,
id_branch_op, ex_branch_op, ex_branch_taken, pc_we,
rf_addra, rf_addrb, rf_rda, rf_rdb, alu_op, mac_op, shrot_op, comp_op, rf_addrw, rfwb_op,
wb_insn, simm, branch_addrofs, lsu_addrofs, sel_a, sel_b, lsu_op,
cust5_op, cust5_limm,
multicycle, spr_addrimm, wbforw_valid, du_hwbkpt, sig_syscall, sig_trap,
force_dslot_fetch, no_more_dslot, ex_void, id_macrc_op, ex_macrc_op, rfe, except_illegal
wb_insn, id_simm, ex_simm, id_branch_addrtarget, ex_branch_addrtarget, sel_a, sel_b, id_lsu_op,
cust5_op, cust5_limm, id_pc, ex_pc, du_hwbkpt,
multicycle, wbforw_valid, sig_syscall, sig_trap,
force_dslot_fetch, no_more_dslot, id_void, ex_void, ex_spr_read, ex_spr_write,
id_mac_op, id_macrc_op, ex_macrc_op, rfe, except_illegal
);
 
//
144,11 → 154,19
input id_freeze;
input ex_freeze;
input wb_freeze;
input flushpipe;
input [31:0] if_insn;
output [31:0] ex_insn;
output [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
input branch_taken;
output if_flushpipe;
output id_flushpipe;
output ex_flushpipe;
output wb_flushpipe;
input extend_flush;
input except_flushpipe;
input abort_mvspr ;
input [31:0] if_insn;
output [31:0] id_insn;
output [31:0] ex_insn;
output [`OR1200_BRANCHOP_WIDTH-1:0] ex_branch_op;
output [`OR1200_BRANCHOP_WIDTH-1:0] id_branch_op;
input ex_branch_taken;
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrw;
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addra;
output [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrb;
158,18 → 176,21
output [`OR1200_MACOP_WIDTH-1:0] mac_op;
output [`OR1200_SHROTOP_WIDTH-1:0] shrot_op;
output [`OR1200_RFWBOP_WIDTH-1:0] rfwb_op;
input pc_we;
output [31:0] wb_insn;
output [31:0] simm;
output [31:2] branch_addrofs;
output [31:0] lsu_addrofs;
output [31:2] id_branch_addrtarget;
output [31:2] ex_branch_addrtarget;
output [`OR1200_SEL_WIDTH-1:0] sel_a;
output [`OR1200_SEL_WIDTH-1:0] sel_b;
output [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
output [`OR1200_LSUOP_WIDTH-1:0] id_lsu_op;
output [`OR1200_COMPOP_WIDTH-1:0] comp_op;
output [`OR1200_MULTICYCLE_WIDTH-1:0] multicycle;
output [4:0] cust5_op;
output [5:0] cust5_limm;
output [15:0] spr_addrimm;
input [31:0] id_pc;
input [31:0] ex_pc;
output [31:0] id_simm;
output [31:0] ex_simm;
input wbforw_valid;
input du_hwbkpt;
output sig_syscall;
176,7 → 197,11
output sig_trap;
output force_dslot_fetch;
output no_more_dslot;
output id_void;
output ex_void;
output ex_spr_read;
output ex_spr_write;
output [`OR1200_MACOP_WIDTH-1:0] id_mac_op;
output id_macrc_op;
output ex_macrc_op;
output rfe;
185,11 → 210,14
//
// Internal wires and regs
//
reg [`OR1200_BRANCHOP_WIDTH-1:0] pre_branch_op;
reg [`OR1200_BRANCHOP_WIDTH-1:0] branch_op;
reg [`OR1200_BRANCHOP_WIDTH-1:0] id_branch_op;
reg [`OR1200_BRANCHOP_WIDTH-1:0] ex_branch_op;
reg [`OR1200_ALUOP_WIDTH-1:0] alu_op;
wire if_maci_op;
`ifdef OR1200_MAC_IMPLEMENTED
reg [`OR1200_MACOP_WIDTH-1:0] mac_op;
reg [`OR1200_MACOP_WIDTH-1:0] ex_mac_op;
reg [`OR1200_MACOP_WIDTH-1:0] id_mac_op;
wire [`OR1200_MACOP_WIDTH-1:0] mac_op;
reg ex_macrc_op;
`else
wire [`OR1200_MACOP_WIDTH-1:0] mac_op;
202,19 → 230,25
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] rf_addrw;
reg [`OR1200_REGFILE_ADDR_WIDTH-1:0] wb_rfaddrw;
reg [`OR1200_RFWBOP_WIDTH-1:0] rfwb_op;
reg [31:0] lsu_addrofs;
reg [`OR1200_SEL_WIDTH-1:0] sel_a;
reg [`OR1200_SEL_WIDTH-1:0] sel_b;
reg sel_imm;
reg [`OR1200_LSUOP_WIDTH-1:0] lsu_op;
reg [`OR1200_LSUOP_WIDTH-1:0] id_lsu_op;
reg [`OR1200_COMPOP_WIDTH-1:0] comp_op;
reg [`OR1200_MULTICYCLE_WIDTH-1:0] multicycle;
reg imm_signextend;
reg [15:0] spr_addrimm;
reg [31:0] id_simm;
reg [31:0] ex_simm;
reg sig_syscall;
reg sig_trap;
reg except_illegal;
wire id_void;
wire ex_void;
wire wb_void;
reg ex_delayslot_dsi;
reg ex_delayslot_nop;
reg spr_read;
reg spr_write;
reg [31:2] ex_branch_addrtarget;
 
//
// Register file read addresses
221,7 → 255,7
//
assign rf_addra = if_insn[20:16];
assign rf_addrb = if_insn[15:11];
assign rf_rda = if_insn[31];
assign rf_rda = if_insn[31] || if_maci_op;
assign rf_rdb = if_insn[30];
 
//
228,24 → 262,147
// Force fetch of delay slot instruction when jump/branch is preceeded by load/store
// instructions
//
// SIMON
// assign force_dslot_fetch = ((|pre_branch_op) & (|lsu_op));
assign force_dslot_fetch = 1'b0;
assign no_more_dslot = |branch_op & !id_void & branch_taken | (branch_op == `OR1200_BRANCHOP_RFE);
assign no_more_dslot = (|ex_branch_op & !id_void & ex_branch_taken) | (ex_branch_op == `OR1200_BRANCHOP_RFE);
 
assign id_void = (id_insn[31:26] == `OR1200_OR32_NOP) & id_insn[16];
assign ex_void = (ex_insn[31:26] == `OR1200_OR32_NOP) & ex_insn[16];
assign wb_void = (wb_insn[31:26] == `OR1200_OR32_NOP) & wb_insn[16];
 
assign ex_spr_write = spr_write && !abort_mvspr;
assign ex_spr_read = spr_read && !abort_mvspr;
 
//
// Sign/Zero extension of immediates
// ex_delayslot_dsi: delay slot insn is in EX stage
// ex_delayslot_nop: (filler) nop insn is in EX stage (before nops jump/branch was executed)
//
assign simm = (imm_signextend == 1'b1) ? {{16{id_insn[15]}}, id_insn[15:0]} : {{16'b0}, id_insn[15:0]};
// ex_delayslot_dsi & !ex_delayslot_nop - DS insn in EX stage
// !ex_delayslot_dsi & ex_delayslot_nop - NOP insn in EX stage,
// next different is DS insn, previous different was Jump/Branch
// !ex_delayslot_dsi & !ex_delayslot_nop - normal insn in EX stage
//
always @(posedge clk or posedge rst) begin
if (rst) begin
ex_delayslot_nop <= #1 1'b0;
ex_delayslot_dsi <= #1 1'b0;
end
else if (!ex_freeze & !ex_delayslot_dsi & ex_delayslot_nop) begin
ex_delayslot_nop <= #1 id_void;
ex_delayslot_dsi <= #1 !id_void;
end
else if (!ex_freeze & ex_delayslot_dsi & !ex_delayslot_nop) begin
ex_delayslot_nop <= #1 1'b0;
ex_delayslot_dsi <= #1 1'b0;
end
else if (!ex_freeze) begin
ex_delayslot_nop <= #1 id_void && ex_branch_taken && (ex_branch_op != `OR1200_BRANCHOP_NOP) &&
(ex_branch_op != `OR1200_BRANCHOP_RFE);
ex_delayslot_dsi <= #1 !id_void && ex_branch_taken && (ex_branch_op != `OR1200_BRANCHOP_NOP) &&
(ex_branch_op != `OR1200_BRANCHOP_RFE);
end
end
 
//
// Sign extension of branch offset
// Flush pipeline
//
assign branch_addrofs = {{4{ex_insn[25]}}, ex_insn[25:0]};
assign if_flushpipe = except_flushpipe | pc_we | extend_flush;
assign id_flushpipe = except_flushpipe | pc_we | extend_flush;
assign ex_flushpipe = except_flushpipe | pc_we | extend_flush;
assign wb_flushpipe = except_flushpipe | pc_we | extend_flush;
 
//
// EX Sign/Zero extension of immediates
//
always @(posedge clk or posedge rst) begin
if (rst)
ex_simm <= #1 32'h0000_0000;
else if (!ex_freeze) begin
ex_simm <= #1 id_simm;
end
end
 
//
// ID Sign/Zero extension of immediate
//
always @(id_insn) begin
case (id_insn[31:26]) // synopsys parallel_case
 
// l.addi
`OR1200_OR32_ADDI:
id_simm = {{16{id_insn[15]}}, id_insn[15:0]};
 
// l.addic
`OR1200_OR32_ADDIC:
id_simm = {{16{id_insn[15]}}, id_insn[15:0]};
 
// l.lxx (load instructions)
`OR1200_OR32_LWZ, `OR1200_OR32_LBZ, `OR1200_OR32_LBS, `OR1200_OR32_LHZ, `OR1200_OR32_LHS:
id_simm = {{16{id_insn[15]}}, id_insn[15:0]};
 
// l.muli
`ifdef OR1200_MULT_IMPLEMENTED
`OR1200_OR32_MULI:
id_simm = {{16{id_insn[15]}}, id_insn[15:0]};
`endif
 
// l.maci
`ifdef OR1200_MAC_IMPLEMENTED
`OR1200_OR32_MACI:
id_simm = {{16{id_insn[25]}}, id_insn[25:21], id_insn[10:0]};
`endif
 
// l.mtspr
`OR1200_OR32_MTSPR:
id_simm = {16'b0, id_insn[25:21], id_insn[10:0]};
 
// l.sxx (store instructions)
`OR1200_OR32_SW, `OR1200_OR32_SH, `OR1200_OR32_SB:
id_simm = {{16{id_insn[25]}}, id_insn[25:21], id_insn[10:0]};
 
// l.xori
`OR1200_OR32_XORI:
id_simm = {{16{id_insn[15]}}, id_insn[15:0]};
 
// l.sfxxi (SFXX with immediate)
`OR1200_OR32_SFXXI:
id_simm = {{16{id_insn[15]}}, id_insn[15:0]};
 
// Instructions with no or zero extended immediate
default:
id_simm = {{16'b0}, id_insn[15:0]};
 
endcase
end
 
//
// ID Sign extension of branch offset
//
assign id_branch_addrtarget = {{4{id_insn[25]}}, id_insn[25:0]} + id_pc[31:2];
 
//
// EX Sign extension of branch offset
//
 
// pipeline ID and EX branch target address
always @(posedge clk or posedge rst) begin
if (rst)
ex_branch_addrtarget <= #1 32'h00000000;
else if (!ex_freeze)
ex_branch_addrtarget <= #1 id_branch_addrtarget;
end
// not pipelined
//assign ex_branch_addrtarget = {{4{ex_insn[25]}}, ex_insn[25:0]} + ex_pc[31:2];
 
//
// l.maci in IF stage
//
`ifdef OR1200_MAC_IMPLEMENTED
assign if_maci_op = (if_insn[31:26] == `OR1200_OR32_MACI);
`else
assign if_maci_op = 1'b0;
`endif
 
//
// l.macrc in ID stage
//
`ifdef OR1200_MAC_IMPLEMENTED
255,6 → 412,22
`endif
 
//
// l.macrc in EX stage
//
`ifdef OR1200_MAC_IMPLEMENTED
always @(posedge clk or posedge rst) begin
if (rst)
ex_macrc_op <= #1 1'b0;
else if (!ex_freeze & id_freeze | ex_flushpipe)
ex_macrc_op <= #1 1'b0;
else if (!ex_freeze)
ex_macrc_op <= #1 id_macrc_op;
end
`else
assign ex_macrc_op = 1'b0;
`endif
 
//
// cust5_op, cust5_limm (L immediate)
//
assign cust5_op = ex_insn[4:0];
263,7 → 436,7
//
//
//
assign rfe = (pre_branch_op == `OR1200_BRANCHOP_RFE) | (branch_op == `OR1200_BRANCHOP_RFE);
assign rfe = (id_branch_op == `OR1200_BRANCHOP_RFE) | (ex_branch_op == `OR1200_BRANCHOP_RFE);
 
//
// Generation of sel_a
290,42 → 463,6
sel_b = `OR1200_SEL_RF;
 
//
// l.macrc in EX stage
//
`ifdef OR1200_MAC_IMPLEMENTED
always @(posedge clk or posedge rst) begin
if (rst)
ex_macrc_op <= #1 1'b0;
else if (!ex_freeze & id_freeze | flushpipe)
ex_macrc_op <= #1 1'b0;
else if (!ex_freeze)
ex_macrc_op <= #1 id_macrc_op;
end
`else
assign ex_macrc_op = 1'b0;
`endif
 
//
// Decode of spr_addrimm
//
always @(posedge clk or posedge rst) begin
if (rst)
spr_addrimm <= #1 16'h0000;
else if (!ex_freeze & id_freeze | flushpipe)
spr_addrimm <= #1 16'h0000;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys parallel_case
// l.mfspr
`OR1200_OR32_MFSPR:
spr_addrimm <= #1 id_insn[15:0];
// l.mtspr
default:
spr_addrimm <= #1 {id_insn[25:21], id_insn[10:0]};
endcase
end
end
 
//
// Decode of multicycle
//
always @(id_insn) begin
363,10 → 500,23
`OR1200_OR32_SH:
multicycle = `OR1200_TWO_CYCLES;
`endif
// l.mfspr
`OR1200_OR32_MFSPR:
multicycle = `OR1200_TWO_CYCLES; // to read from ITLB/DTLB (sync RAMs)
 
// ALU instructions except the one with immediate
`OR1200_OR32_ALU:
multicycle = id_insn[`OR1200_ALUMCYC_POS];
case (id_insn[3:0]) // synopsys parallel_case
4'h6: multicycle = 2'b11; // l.mul
4'h9: multicycle = 2'b10; // l.div
4'hA: multicycle = 2'b10; // l.divu
4'hB: multicycle = 2'b11; // l.mulu
default: multicycle = 2'b00;
endcase
`OR1200_OR32_MULI:
multicycle = 2'h3;
// Single cycle instructions
default: begin
multicycle = `OR1200_ONE_CYCLE;
373,66 → 523,9
end
endcase
end
 
//
// Decode of imm_signextend
//
always @(id_insn) begin
case (id_insn[31:26]) // synopsys parallel_case
 
// l.addi
`OR1200_OR32_ADDI:
imm_signextend = 1'b1;
 
// l.addic
`OR1200_OR32_ADDIC:
imm_signextend = 1'b1;
 
// l.xori
`OR1200_OR32_XORI:
imm_signextend = 1'b1;
 
// l.muli
`ifdef OR1200_MULT_IMPLEMENTED
`OR1200_OR32_MULI:
imm_signextend = 1'b1;
`endif
 
// l.maci
`ifdef OR1200_MAC_IMPLEMENTED
`OR1200_OR32_MACI:
imm_signextend = 1'b1;
`endif
 
// SFXX insns with immediate
`OR1200_OR32_SFXXI:
imm_signextend = 1'b1;
 
// Instructions with no or zero extended immediate
default: begin
imm_signextend = 1'b0;
end
 
endcase
 
end
 
//
// LSU addr offset
//
always @(lsu_op or ex_insn) begin
lsu_addrofs[10:0] = ex_insn[10:0];
case(lsu_op) // synopsys parallel_case
`OR1200_LSUOP_SW, `OR1200_LSUOP_SH, `OR1200_LSUOP_SB :
lsu_addrofs[31:11] = {{16{ex_insn[25]}}, ex_insn[25:21]};
default :
lsu_addrofs[31:11] = {{16{ex_insn[15]}}, ex_insn[15:11]};
endcase
end
 
//
// Register file write address
//
always @(posedge clk or posedge rst) begin
441,8 → 534,8
else if (!ex_freeze & id_freeze)
rf_addrw <= #1 5'd00;
else if (!ex_freeze)
case (pre_branch_op) // synopsys parallel_case
`OR1200_BRANCHOP_JR, `OR1200_BRANCHOP_BAL:
case (id_insn[31:26]) // synopsys parallel_case
`OR1200_OR32_JAL, `OR1200_OR32_JALR:
rf_addrw <= #1 5'd09; // link register r9
default:
rf_addrw <= #1 id_insn[25:21];
465,8 → 558,8
always @(posedge clk or posedge rst) begin
if (rst)
id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
else if (flushpipe)
id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // id_insn[16] must be 1
else if (id_flushpipe)
id_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // NOP -> id_insn[16] must be 1
else if (!id_freeze) begin
id_insn <= #1 if_insn;
`ifdef OR1200_VERBOSE
483,8 → 576,8
always @(posedge clk or posedge rst) begin
if (rst)
ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
else if (!ex_freeze & id_freeze | flushpipe)
ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // ex_insn[16] must be 1
else if (!ex_freeze & id_freeze | ex_flushpipe)
ex_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // NOP -> ex_insn[16] must be 1
else if (!ex_freeze) begin
ex_insn <= #1 id_insn;
`ifdef OR1200_VERBOSE
501,8 → 594,9
always @(posedge clk or posedge rst) begin
if (rst)
wb_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000};
else if (flushpipe)
wb_insn <= #1 {`OR1200_OR32_NOP, 26'h041_0000}; // wb_insn[16] must be 1
// wb_insn should not be changed by exceptions due to correct
// recording of display_arch_state in the or1200_monitor!
// wb_insn changed by exception is not used elsewhere!
else if (!wb_freeze) begin
wb_insn <= #1 ex_insn;
end
593,59 → 687,89
always @(posedge clk or posedge rst) begin
if (rst)
except_illegal <= #1 1'b0;
else if (!ex_freeze & id_freeze | flushpipe)
else if (!ex_freeze & id_freeze | ex_flushpipe)
except_illegal <= #1 1'b0;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys parallel_case
case (id_insn[31:26]) // synopsys parallel_case
 
`OR1200_OR32_J,
`OR1200_OR32_JAL,
`OR1200_OR32_JALR,
`OR1200_OR32_JR,
`OR1200_OR32_BNF,
`OR1200_OR32_BF,
`OR1200_OR32_RFE,
`OR1200_OR32_MOVHI,
`OR1200_OR32_MFSPR,
`OR1200_OR32_XSYNC,
`OR1200_OR32_J,
`OR1200_OR32_JAL,
`OR1200_OR32_JALR,
`OR1200_OR32_JR,
`OR1200_OR32_BNF,
`OR1200_OR32_BF,
`OR1200_OR32_RFE,
`OR1200_OR32_MOVHI,
`OR1200_OR32_MFSPR,
`OR1200_OR32_XSYNC,
`ifdef OR1200_MAC_IMPLEMENTED
`OR1200_OR32_MACI,
`OR1200_OR32_MACI,
`endif
`OR1200_OR32_LWZ,
`OR1200_OR32_LBZ,
`OR1200_OR32_LBS,
`OR1200_OR32_LHZ,
`OR1200_OR32_LHS,
`OR1200_OR32_ADDI,
`OR1200_OR32_ADDIC,
`OR1200_OR32_ANDI,
`OR1200_OR32_ORI,
`OR1200_OR32_XORI,
`OR1200_OR32_LWZ,
`OR1200_OR32_LBZ,
`OR1200_OR32_LBS,
`OR1200_OR32_LHZ,
`OR1200_OR32_LHS,
`OR1200_OR32_ADDI,
`OR1200_OR32_ADDIC,
`OR1200_OR32_ANDI,
`OR1200_OR32_ORI,
`OR1200_OR32_XORI,
`ifdef OR1200_MULT_IMPLEMENTED
`OR1200_OR32_MULI,
`OR1200_OR32_MULI,
`endif
`OR1200_OR32_SH_ROTI,
`OR1200_OR32_SFXXI,
`OR1200_OR32_MTSPR,
`OR1200_OR32_SH_ROTI,
`OR1200_OR32_SFXXI,
`OR1200_OR32_MTSPR,
`ifdef OR1200_MAC_IMPLEMENTED
`OR1200_OR32_MACMSB,
`OR1200_OR32_MACMSB,
`endif
`OR1200_OR32_SW,
`OR1200_OR32_SB,
`OR1200_OR32_SH,
`OR1200_OR32_ALU,
`OR1200_OR32_SFXX,
`OR1200_OR32_SW,
`OR1200_OR32_SB,
`OR1200_OR32_SH,
`OR1200_OR32_SFXX,
`ifdef OR1200_OR32_CUST5
`OR1200_OR32_CUST5,
`OR1200_OR32_CUST5,
`endif
`OR1200_OR32_NOP:
except_illegal <= #1 1'b0;
`OR1200_OR32_NOP:
except_illegal <= #1 1'b0;
 
// Illegal and OR1200 unsupported instructions
default:
except_illegal <= #1 1'b1;
`OR1200_OR32_ALU:
except_illegal <= #1 1'b0
 
endcase
`ifdef OR1200_MULT_IMPLEMENTED
`ifdef OR1200_IMPL_DIV
`else
| ({1'b0, id_insn[3:0]} == `OR1200_ALUOP_DIV)
| ({1'b0, id_insn[3:0]} == `OR1200_ALUOP_DIVU)
`endif
`else
| ({1'b0, id_insn[3:0]} == `OR1200_ALUOP_DIV)
| ({1'b0, id_insn[3:0]} == `OR1200_ALUOP_DIVU)
| ({1'b0, id_insn[3:0]} == `OR1200_ALUOP_MUL)
`endif
 
`ifdef OR1200_IMPL_ADDC
`else
| ({1'b0, id_insn[3:0]} == `OR1200_ALUOP_ADDC)
`endif
 
`ifdef OR1200_IMPL_ALU_ROTATE
`else
| (({1'b0, id_insn[3:0]} == `OR1200_ALUOP_SHROT) && (id_insn[7:6] == `OR1200_SHROTOP_ROR))
`endif
 
`ifdef OR1200_IMPL_SUB
`else
| ({1'b0, id_insn[3:0]} == `OR1200_ALUOP_SUB)
`endif
;
 
// Illegal and OR1200 unsupported instructions
default:
except_illegal <= #1 1'b1;
 
endcase
end
end
656,39 → 780,15
always @(posedge clk or posedge rst) begin
if (rst)
alu_op <= #1 `OR1200_ALUOP_NOP;
else if (!ex_freeze & id_freeze | flushpipe)
else if (!ex_freeze & id_freeze | ex_flushpipe)
alu_op <= #1 `OR1200_ALUOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys parallel_case
// l.j
`OR1200_OR32_J:
alu_op <= #1 `OR1200_ALUOP_IMM;
// j.jal
`OR1200_OR32_JAL:
alu_op <= #1 `OR1200_ALUOP_IMM;
// l.bnf
`OR1200_OR32_BNF:
alu_op <= #1 `OR1200_ALUOP_NOP;
// l.bf
`OR1200_OR32_BF:
alu_op <= #1 `OR1200_ALUOP_NOP;
// l.movhi
`OR1200_OR32_MOVHI:
alu_op <= #1 `OR1200_ALUOP_MOVHI;
// l.mfspr
`OR1200_OR32_MFSPR:
alu_op <= #1 `OR1200_ALUOP_MFSR;
// l.mtspr
`OR1200_OR32_MTSPR:
alu_op <= #1 `OR1200_ALUOP_MTSR;
// l.addi
`OR1200_OR32_ADDI:
alu_op <= #1 `OR1200_ALUOP_ADD;
748,35 → 848,76
end
 
//
// Decode of spr_read, spr_write
//
always @(posedge clk or posedge rst) begin
if (rst) begin
spr_read <= #1 1'b0;
spr_write <= #1 1'b0;
end
else if (!ex_freeze & id_freeze | ex_flushpipe) begin
spr_read <= #1 1'b0;
spr_write <= #1 1'b0;
end
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys parallel_case
 
// l.mfspr
`OR1200_OR32_MFSPR: begin
spr_read <= #1 1'b1;
spr_write <= #1 1'b0;
end
 
// l.mtspr
`OR1200_OR32_MTSPR: begin
spr_read <= #1 1'b0;
spr_write <= #1 1'b1;
end
 
// Default
default: begin
spr_read <= #1 1'b0;
spr_write <= #1 1'b0;
end
 
endcase
end
end
 
//
// Decode of mac_op
//
`ifdef OR1200_MAC_IMPLEMENTED
always @(posedge clk or posedge rst) begin
if (rst)
mac_op <= #1 `OR1200_MACOP_NOP;
else if (!ex_freeze & id_freeze | flushpipe)
mac_op <= #1 `OR1200_MACOP_NOP;
else if (!ex_freeze)
case (id_insn[31:26]) // synopsys parallel_case
always @(id_insn) begin
case (id_insn[31:26]) // synopsys parallel_case
 
// l.maci
`OR1200_OR32_MACI:
mac_op <= #1 `OR1200_MACOP_MAC;
// l.maci
`OR1200_OR32_MACI:
id_mac_op <= #1 `OR1200_MACOP_MAC;
 
// l.nop
`OR1200_OR32_MACMSB:
mac_op <= #1 id_insn[1:0];
// l.mac, l.msb
`OR1200_OR32_MACMSB:
id_mac_op <= #1 id_insn[2:0];
 
// Illegal and OR1200 unsupported instructions
default: begin
mac_op <= #1 `OR1200_MACOP_NOP;
end
// Illegal and OR1200 unsupported instructions
default:
id_mac_op <= #1 `OR1200_MACOP_NOP;
 
endcase
else
mac_op <= #1 `OR1200_MACOP_NOP;
endcase
end
 
always @(posedge clk or posedge rst) begin
if (rst)
ex_mac_op <= #1 `OR1200_MACOP_NOP;
else if (!ex_freeze & id_freeze | ex_flushpipe)
ex_mac_op <= #1 `OR1200_MACOP_NOP;
else if (!ex_freeze)
ex_mac_op <= #1 id_mac_op;
end
 
assign mac_op = abort_mvspr ? `OR1200_MACOP_NOP : ex_mac_op;
`else
assign id_mac_op = `OR1200_MACOP_NOP;
assign mac_op = `OR1200_MACOP_NOP;
`endif
 
786,7 → 927,7
always @(posedge clk or posedge rst) begin
if (rst)
shrot_op <= #1 `OR1200_SHROTOP_NOP;
else if (!ex_freeze & id_freeze | flushpipe)
else if (!ex_freeze & id_freeze | ex_flushpipe)
shrot_op <= #1 `OR1200_SHROTOP_NOP;
else if (!ex_freeze) begin
shrot_op <= #1 id_insn[`OR1200_SHROTOP_POS];
799,203 → 940,197
always @(posedge clk or posedge rst) begin
if (rst)
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
else if (!ex_freeze & id_freeze | flushpipe)
else if (!ex_freeze & id_freeze | ex_flushpipe)
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys parallel_case
 
// j.jal
`OR1200_OR32_JAL:
rfwb_op <= #1 `OR1200_RFWBOP_LR;
// j.jal
`OR1200_OR32_JAL:
rfwb_op <= #1 `OR1200_RFWBOP_LR;
// j.jalr
`OR1200_OR32_JALR:
rfwb_op <= #1 `OR1200_RFWBOP_LR;
// j.jalr
`OR1200_OR32_JALR:
rfwb_op <= #1 `OR1200_RFWBOP_LR;
// l.movhi
`OR1200_OR32_MOVHI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.movhi
`OR1200_OR32_MOVHI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.mfspr
`OR1200_OR32_MFSPR:
rfwb_op <= #1 `OR1200_RFWBOP_SPRS;
// l.mfspr
`OR1200_OR32_MFSPR:
rfwb_op <= #1 `OR1200_RFWBOP_SPRS;
// l.lwz
`OR1200_OR32_LWZ:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lwz
`OR1200_OR32_LWZ:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lbz
`OR1200_OR32_LBZ:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lbz
`OR1200_OR32_LBZ:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lbs
`OR1200_OR32_LBS:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lbs
`OR1200_OR32_LBS:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lhz
`OR1200_OR32_LHZ:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lhz
`OR1200_OR32_LHZ:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lhs
`OR1200_OR32_LHS:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.lhs
`OR1200_OR32_LHS:
rfwb_op <= #1 `OR1200_RFWBOP_LSU;
// l.addi
`OR1200_OR32_ADDI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.addi
`OR1200_OR32_ADDI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.addic
`OR1200_OR32_ADDIC:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.addic
`OR1200_OR32_ADDIC:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.andi
`OR1200_OR32_ANDI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.andi
`OR1200_OR32_ANDI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.ori
`OR1200_OR32_ORI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.ori
`OR1200_OR32_ORI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.xori
`OR1200_OR32_XORI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.xori
`OR1200_OR32_XORI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.muli
// l.muli
`ifdef OR1200_MULT_IMPLEMENTED
`OR1200_OR32_MULI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
`OR1200_OR32_MULI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
`endif
// Shift and rotate insns with immediate
`OR1200_OR32_SH_ROTI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// Shift and rotate insns with immediate
`OR1200_OR32_SH_ROTI:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// ALU instructions except the one with immediate
`OR1200_OR32_ALU:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// ALU instructions except the one with immediate
`OR1200_OR32_ALU:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
 
`ifdef OR1200_OR32_CUST5
// l.cust5 instructions
`OR1200_OR32_CUST5:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
// l.cust5 instructions
`OR1200_OR32_CUST5:
rfwb_op <= #1 `OR1200_RFWBOP_ALU;
`endif
 
// Instructions w/o register-file write-back
default: begin
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
end
// Instructions w/o register-file write-back
default:
rfwb_op <= #1 `OR1200_RFWBOP_NOP;
 
 
endcase
end
end
 
//
// Decode of pre_branch_op
// Decode of id_branch_op
//
always @(posedge clk or posedge rst) begin
if (rst)
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
else if (flushpipe)
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
id_branch_op <= #1 `OR1200_BRANCHOP_NOP;
else if (id_flushpipe)
id_branch_op <= #1 `OR1200_BRANCHOP_NOP;
else if (!id_freeze) begin
case (if_insn[31:26]) // synopsys parallel_case
 
// l.j
`OR1200_OR32_J:
id_branch_op <= #1 `OR1200_BRANCHOP_J;
// l.j
`OR1200_OR32_J:
pre_branch_op <= #1 `OR1200_BRANCHOP_BAL;
// j.jal
`OR1200_OR32_JAL:
id_branch_op <= #1 `OR1200_BRANCHOP_J;
// j.jal
`OR1200_OR32_JAL:
pre_branch_op <= #1 `OR1200_BRANCHOP_BAL;
// j.jalr
`OR1200_OR32_JALR:
id_branch_op <= #1 `OR1200_BRANCHOP_JR;
// j.jalr
`OR1200_OR32_JALR:
pre_branch_op <= #1 `OR1200_BRANCHOP_JR;
// l.jr
`OR1200_OR32_JR:
id_branch_op <= #1 `OR1200_BRANCHOP_JR;
// l.jr
`OR1200_OR32_JR:
pre_branch_op <= #1 `OR1200_BRANCHOP_JR;
// l.bnf
`OR1200_OR32_BNF:
id_branch_op <= #1 `OR1200_BRANCHOP_BNF;
// l.bnf
`OR1200_OR32_BNF:
pre_branch_op <= #1 `OR1200_BRANCHOP_BNF;
// l.bf
`OR1200_OR32_BF:
id_branch_op <= #1 `OR1200_BRANCHOP_BF;
// l.bf
`OR1200_OR32_BF:
pre_branch_op <= #1 `OR1200_BRANCHOP_BF;
// l.rfe
`OR1200_OR32_RFE:
id_branch_op <= #1 `OR1200_BRANCHOP_RFE;
// l.rfe
`OR1200_OR32_RFE:
pre_branch_op <= #1 `OR1200_BRANCHOP_RFE;
// Non branch instructions
default: begin
pre_branch_op <= #1 `OR1200_BRANCHOP_NOP;
end
// Non branch instructions
default:
id_branch_op <= #1 `OR1200_BRANCHOP_NOP;
 
endcase
end
end
 
//
// Generation of branch_op
// Generation of ex_branch_op
//
always @(posedge clk or posedge rst)
if (rst)
branch_op <= #1 `OR1200_BRANCHOP_NOP;
else if (!ex_freeze & id_freeze | flushpipe)
branch_op <= #1 `OR1200_BRANCHOP_NOP;
ex_branch_op <= #1 `OR1200_BRANCHOP_NOP;
else if (!ex_freeze & id_freeze | ex_flushpipe)
ex_branch_op <= #1 `OR1200_BRANCHOP_NOP;
else if (!ex_freeze)
branch_op <= #1 pre_branch_op;
ex_branch_op <= #1 id_branch_op;
 
//
// Decode of lsu_op
// Decode of id_lsu_op
//
always @(posedge clk or posedge rst) begin
if (rst)
lsu_op <= #1 `OR1200_LSUOP_NOP;
else if (!ex_freeze & id_freeze | flushpipe)
lsu_op <= #1 `OR1200_LSUOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys parallel_case
// l.lwz
`OR1200_OR32_LWZ:
lsu_op <= #1 `OR1200_LSUOP_LWZ;
// l.lbz
`OR1200_OR32_LBZ:
lsu_op <= #1 `OR1200_LSUOP_LBZ;
// l.lbs
`OR1200_OR32_LBS:
lsu_op <= #1 `OR1200_LSUOP_LBS;
// l.lhz
`OR1200_OR32_LHZ:
lsu_op <= #1 `OR1200_LSUOP_LHZ;
// l.lhs
`OR1200_OR32_LHS:
lsu_op <= #1 `OR1200_LSUOP_LHS;
// l.sw
`OR1200_OR32_SW:
lsu_op <= #1 `OR1200_LSUOP_SW;
// l.sb
`OR1200_OR32_SB:
lsu_op <= #1 `OR1200_LSUOP_SB;
// l.sh
`OR1200_OR32_SH:
lsu_op <= #1 `OR1200_LSUOP_SH;
// Non load/store instructions
default: begin
lsu_op <= #1 `OR1200_LSUOP_NOP;
end
endcase
end
always @(id_insn) begin
case (id_insn[31:26]) // synopsys parallel_case
 
// l.lwz
`OR1200_OR32_LWZ:
id_lsu_op <= #1 `OR1200_LSUOP_LWZ;
 
// l.lbz
`OR1200_OR32_LBZ:
id_lsu_op <= #1 `OR1200_LSUOP_LBZ;
 
// l.lbs
`OR1200_OR32_LBS:
id_lsu_op <= #1 `OR1200_LSUOP_LBS;
 
// l.lhz
`OR1200_OR32_LHZ:
id_lsu_op <= #1 `OR1200_LSUOP_LHZ;
 
// l.lhs
`OR1200_OR32_LHS:
id_lsu_op <= #1 `OR1200_LSUOP_LHS;
 
// l.sw
`OR1200_OR32_SW:
id_lsu_op <= #1 `OR1200_LSUOP_SW;
 
// l.sb
`OR1200_OR32_SB:
id_lsu_op <= #1 `OR1200_LSUOP_SB;
 
// l.sh
`OR1200_OR32_SH:
id_lsu_op <= #1 `OR1200_LSUOP_SH;
 
// Non load/store instructions
default:
id_lsu_op <= #1 `OR1200_LSUOP_NOP;
 
endcase
end
 
//
1004,7 → 1139,7
always @(posedge clk or posedge rst) begin
if (rst) begin
comp_op <= #1 4'd0;
end else if (!ex_freeze & id_freeze | flushpipe)
end else if (!ex_freeze & id_freeze | ex_flushpipe)
comp_op <= #1 4'd0;
else if (!ex_freeze)
comp_op <= #1 id_insn[24:21];
1016,7 → 1151,7
always @(posedge clk or posedge rst) begin
if (rst)
sig_syscall <= #1 1'b0;
else if (!ex_freeze & id_freeze | flushpipe)
else if (!ex_freeze & id_freeze | ex_flushpipe)
sig_syscall <= #1 1'b0;
else if (!ex_freeze) begin
`ifdef OR1200_VERBOSE
1035,7 → 1170,7
always @(posedge clk or posedge rst) begin
if (rst)
sig_trap <= #1 1'b0;
else if (!ex_freeze & id_freeze | flushpipe)
else if (!ex_freeze & id_freeze | ex_flushpipe)
sig_trap <= #1 1'b0;
else if (!ex_freeze) begin
`ifdef OR1200_VERBOSE
/rtl/verilog/or1200_rf.v
43,7 → 43,14
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// $Log: or1200_rf.v,v $
// Revision 2.0 2010/06/30 11:00:00 ORSoC
// Minor update:
// Bugs fixed, coding style changed.
//
// Revision 1.3 2003/04/07 01:21:56 lampret
// RFRAM type always need to be defined.
//
// Revision 1.2 2002/06/08 16:19:09 lampret
// Added generic flip-flop based memory macro instantiation.
//
92,7 → 99,7
clk, rst,
 
// Write i/f
supv, wb_freeze, addrw, dataw, we, flushpipe,
cy_we_i, cy_we_o, supv, wb_freeze, addrw, dataw, we, flushpipe,
 
// Read i/f
id_freeze, addra, addrb, dataa, datab, rda, rdb,
117,6 → 124,8
//
// Write i/f
//
input cy_we_i;
output cy_we_o;
input supv;
input wb_freeze;
input [aw-1:0] addrw;
149,8 → 158,6
//
wire [dw-1:0] from_rfa;
wire [dw-1:0] from_rfb;
reg [dw:0] dataa_saved;
reg [dw:0] datab_saved;
wire [aw-1:0] rf_addra;
wire [aw-1:0] rf_addrw;
wire [dw-1:0] rf_dataw;
174,12 → 181,12
//
// Operand A comes from RF or from saved A register
//
assign dataa = (dataa_saved[32]) ? dataa_saved[31:0] : from_rfa;
assign dataa = from_rfa;
 
//
// Operand B comes from RF or from saved B register
//
assign datab = (datab_saved[32]) ? datab_saved[31:0] : from_rfb;
assign datab = from_rfb;
 
//
// RF A read address is either from SPRS or normal from CPU control
205,13 → 212,17
else if (~wb_freeze)
rf_we_allow <= #1 ~flushpipe;
 
assign rf_we = ((spr_valid & spr_write) | (we & ~wb_freeze)) & rf_we_allow & (supv | (|rf_addrw));
//assign rf_we = ((spr_valid & spr_write) | (we & ~wb_freeze)) & rf_we_allow & (supv | (|rf_addrw));
assign rf_we = ((spr_valid & spr_write) | (we & ~wb_freeze)) & rf_we_allow;
//assign cy_we_o = cy_we_i && rf_we;
assign cy_we_o = cy_we_i && ~wb_freeze && rf_we_allow;
 
//
// CS RF A asserted when instruction reads operand A and ID stage
// is not stalled
//
assign rf_ena = rda & ~id_freeze | spr_valid; // probably works with fixed binutils
//assign rf_ena = rda & ~id_freeze | spr_valid; // probably works with fixed binutils
assign rf_ena = (rda & ~id_freeze) | (spr_valid & !spr_write); // probably works with fixed binutils
// assign rf_ena = 1'b1; // does not work with single-stepping
//assign rf_ena = ~id_freeze | spr_valid; // works with broken binutils
 
219,36 → 230,11
// CS RF B asserted when instruction reads operand B and ID stage
// is not stalled
//
assign rf_enb = rdb & ~id_freeze | spr_valid;
//assign rf_enb = rdb & ~id_freeze | spr_valid;
assign rf_enb = rdb & ~id_freeze;
// assign rf_enb = 1'b1;
//assign rf_enb = ~id_freeze | spr_valid; // works with broken binutils
 
//
// Stores operand from RF_A into temp reg when pipeline is frozen
//
always @(posedge clk or posedge rst)
if (rst) begin
dataa_saved <= #1 33'b0;
end
else if (id_freeze & !dataa_saved[32]) begin
dataa_saved <= #1 {1'b1, from_rfa};
end
else if (!id_freeze)
dataa_saved <= #1 33'b0;
 
//
// Stores operand from RF_B into temp reg when pipeline is frozen
//
always @(posedge clk or posedge rst)
if (rst) begin
datab_saved <= #1 33'b0;
end
else if (id_freeze & !datab_saved[32]) begin
datab_saved <= #1 {1'b1, from_rfb};
end
else if (!id_freeze)
datab_saved <= #1 33'b0;
 
`ifdef OR1200_RFRAM_TWOPORT
 
//
308,45 → 294,51
//
// Instantiation of register file two-port RAM A
//
or1200_dpram_32x32 rf_a(
// Port A
.clk_a(clk),
.rst_a(rst),
.ce_a(rf_ena),
.oe_a(1'b1),
.addr_a(rf_addra),
.do_a(from_rfa),
or1200_dpram #
(
.aw(5),
.dw(32)
)
rf_a
(
// Port A
.clk_a(clk),
.ce_a(rf_ena),
.addr_a(rf_addra),
.do_a(from_rfa),
// Port B
.clk_b(clk),
.ce_b(rf_we),
.we_b(rf_we),
.addr_b(rf_addrw),
.di_b(rf_dataw)
);
 
// Port B
.clk_b(clk),
.rst_b(rst),
.ce_b(rf_we),
.we_b(rf_we),
.addr_b(rf_addrw),
.di_b(rf_dataw)
);
 
//
// Instantiation of register file two-port RAM B
//
or1200_dpram_32x32 rf_b(
// Port A
.clk_a(clk),
.rst_a(rst),
.ce_a(rf_enb),
.oe_a(1'b1),
.addr_a(addrb),
.do_a(from_rfb),
 
// Port B
.clk_b(clk),
.rst_b(rst),
.ce_b(rf_we),
.we_b(rf_we),
.addr_b(rf_addrw),
.di_b(rf_dataw)
);
 
//
// Instantiation of register file two-port RAM B
//
or1200_dpram #
(
.aw(5),
.dw(32)
)
rf_b
(
// Port A
.clk_a(clk),
.ce_a(rf_enb),
.addr_a(addrb),
.do_a(from_rfb),
// Port B
.clk_b(clk),
.ce_b(rf_we),
.we_b(rf_we),
.addr_b(rf_addrw),
.di_b(rf_dataw)
);
`else
 
`ifdef OR1200_RFRAM_GENERIC

powered by: WebSVN 2.1.0

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