URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/or1200/rtl/verilog
- from Rev 10 to Rev 141
- ↔ Reverse comparison
Rev 10 → Rev 141
/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; |
|
// |
/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. |
// |
/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. |
// |
/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 |
/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 |
/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; |
/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; |
/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 |
/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 |
/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; |
/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. |
// |
/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 |
/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), |
/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 |
// |
/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 |
/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 |
// |
/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" |
/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 |
/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 |
/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 ( |
/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), |
/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. |
// |
/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 |
/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) |
); |
|
/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; |
|
// |
/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. |
// |
/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 |
/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 |
/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) |
/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 |
/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 |
/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. |
// |
/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. |
// |
/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 |
/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) |
); |
/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 |
/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 |
/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 |
/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 |