URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/or1200
- from Rev 641 to Rev 642
- ↔ Reverse comparison
Rev 641 → Rev 642
/rtl/verilog/or1200_defines.v
299,7 → 299,7
// If you don't use them, then disable implementation |
// to save area. |
// |
//`define OR1200_IMPL_ADDC |
`define OR1200_IMPL_ADDC |
|
// |
// Implement l.sub instruction |
321,9 → 321,26
// 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 carry bit SR[OV] |
// |
// Compiler doesn't use this, but other code may like |
// to. |
// |
`define OR1200_IMPL_OV |
|
// |
// Implement carry bit SR[OVE] |
// |
// Overflow interrupt indicator. When enabled, SR[OV] flag |
// does not remain asserted after exception. |
// |
`define OR1200_IMPL_OVE |
|
|
// |
// Implement rotate in the ALU |
// |
// At the time of writing this, or32 |
825,9 → 842,9
`define OR1200_SR_LEE 7 |
`define OR1200_SR_CE 8 |
`define OR1200_SR_F 9 |
`define OR1200_SR_CY 10 // Unused |
`define OR1200_SR_OV 11 // Unused |
`define OR1200_SR_OVE 12 // Unused |
`define OR1200_SR_CY 10 // Optional |
`define OR1200_SR_OV 11 // Optional |
`define OR1200_SR_OVE 12 // Optional |
`define OR1200_SR_DSX 13 // Unused |
`define OR1200_SR_EPH 14 |
`define OR1200_SR_FO 15 |
/rtl/verilog/or1200_alu.v
56,6 → 56,7
alu_op, alu_op2, comp_op, |
cust5_op, cust5_limm, |
result, flagforw, flag_we, |
ovforw, ov_we, |
cyforw, cy_we, carry, flag |
); |
|
78,6 → 79,8
output flag_we; |
output cyforw; |
output cy_we; |
output ovforw; |
output ov_we; |
input carry; |
input flag; |
|
91,7 → 94,10
reg flagforw; |
reg flagcomp; |
reg flag_we; |
reg cyforw; |
reg cy_we; |
reg ovforw; |
reg ov_we; |
wire [width-1:0] comp_a; |
wire [width-1:0] comp_b; |
`ifdef OR1200_IMPL_ALU_COMP1 |
99,17 → 105,18
wire a_lt_b; |
`endif |
wire [width-1:0] result_sum; |
`ifdef OR1200_IMPL_ADDC |
wire [width-1:0] result_csum; |
wire cy_csum; |
`endif |
wire [width-1:0] result_and; |
wire cy_sum; |
`ifdef OR1200_IMPL_SUB |
wire cy_sub; |
`endif |
reg cyforw; |
wire ov_sum; |
wire [width-1:0] carry_in; |
|
wire [width-1:0] b_mux; |
|
|
|
// |
// Combinatorial logic |
// |
120,12 → 127,24
assign a_lt_b = (comp_a < comp_b); |
`endif |
`ifdef OR1200_IMPL_SUB |
assign cy_sub = a < b; |
assign cy_sub = (comp_a < comp_b); |
`endif |
assign {cy_sum, result_sum} = a + b; |
`ifdef OR1200_IMPL_ADDC |
assign {cy_csum, result_csum} = a + b + {`OR1200_OPERAND_WIDTH'd0, carry}; |
`ifdef OR1200_IMPL_ADDC |
assign carry_in = (alu_op==`OR1200_ALUOP_ADDC) ? |
{{width-1{1'b0}},carry} : {width{1'b0}}; |
`else |
assign carry_in = {width-1{1'b0}}; |
`endif |
`ifdef OR1200_IMPL_SUB |
assign b_mux = (alu_op==`OR1200_ALUOP_SUB) ? (~b)+1 : b; |
`else |
assign b_mux = b; |
`endif |
assign {cy_sum, result_sum} = (a + b_mux) + carry_in; |
// Numbers either both +ve and bit 31 of result set |
assign ov_sum = ((!a[width-1] & !b_mux[width-1]) & result_sum[width-1]) | |
// or both -ve and bit 31 of result clear |
((a[width-1] & b_mux[width-1]) & !result_sum[width-1]); |
assign result_and = a & b; |
|
// |
145,9 → 164,6
// |
always @(alu_op or alu_op2 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 |
`ifdef OR1200_IMPL_ALU_EXT |
or extended |
`endif |
182,19 → 198,15
`OR1200_ALUOP_SHROT : begin |
result = shifted_rotated; |
end |
`OR1200_ALUOP_ADD : begin |
result = result_sum; |
end |
`ifdef OR1200_IMPL_ADDC |
`OR1200_ALUOP_ADDC : begin |
result = result_csum; |
end |
`OR1200_ALUOP_ADDC, |
`endif |
`ifdef OR1200_IMPL_SUB |
`OR1200_ALUOP_SUB : begin |
result = a - b; |
`OR1200_ALUOP_SUB, |
`endif |
`OR1200_ALUOP_ADD : begin |
result = result_sum; |
end |
`endif |
`OR1200_ALUOP_XOR : begin |
result = a ^ b; |
end |
245,22 → 257,16
// Generate flag and flag write enable |
// |
always @(alu_op or result_sum or result_and or flagcomp |
`ifdef OR1200_IMPL_ADDC |
or result_csum |
`endif |
) begin |
casez (alu_op) // synopsys parallel_case |
`ifdef OR1200_ADDITIONAL_FLAG_MODIFIERS |
`ifdef OR1200_IMPL_ADDC |
`OR1200_ALUOP_ADDC, |
`endif |
`OR1200_ALUOP_ADD : begin |
flagforw = (result_sum == 32'h0000_0000); |
flag_we = 1'b1; |
end |
`ifdef OR1200_IMPL_ADDC |
`OR1200_ALUOP_ADDC : begin |
flagforw = (result_csum == 32'h0000_0000); |
flag_we = 1'b1; |
end |
`endif |
`OR1200_ALUOP_AND: begin |
flagforw = (result_and == 32'h0000_0000); |
flag_we = 1'b1; |
282,9 → 288,6
// |
always @(alu_op or cy_sum |
`ifdef OR1200_IMPL_CY |
`ifdef OR1200_IMPL_ADDC |
or cy_csum |
`endif |
`ifdef OR1200_IMPL_SUB |
or cy_sub |
`endif |
292,16 → 295,13
) begin |
casez (alu_op) // synopsys parallel_case |
`ifdef OR1200_IMPL_CY |
`ifdef OR1200_IMPL_ADDC |
`OR1200_ALUOP_ADDC, |
`endif |
`OR1200_ALUOP_ADD : begin |
cyforw = cy_sum; |
cy_we = 1'b1; |
end |
`ifdef OR1200_IMPL_ADDC |
`OR1200_ALUOP_ADDC: begin |
cyforw = cy_csum; |
cy_we = 1'b1; |
end |
`endif |
`ifdef OR1200_IMPL_SUB |
`OR1200_ALUOP_SUB: begin |
cyforw = cy_sub; |
316,7 → 316,32
endcase |
end |
|
|
// |
// Generate SR[OV] write enable |
// |
always @(alu_op or ov_sum) begin |
casez (alu_op) // synopsys parallel_case |
`ifdef OR1200_IMPL_OV |
`ifdef OR1200_IMPL_ADDC |
`OR1200_ALUOP_ADDC, |
`endif |
`ifdef OR1200_IMPL_SUB |
`OR1200_ALUOP_SUB, |
`endif |
`OR1200_ALUOP_ADD : begin |
ovforw = ov_sum; |
ov_we = 1'b1; |
end |
`endif |
default: begin |
ovforw = 1'b0; |
ov_we = 1'b0; |
end |
endcase |
end |
|
// |
// Shifts and rotation |
// |
always @(alu_op2 or a or b) begin |
/rtl/verilog/or1200_sprs.v
57,6 → 57,7
|
// Internal CPU interface |
flagforw, flag_we, flag, cyforw, cy_we, carry, |
ovforw, ov_we, |
addrbase, addrofs, dat_i, branch_op, ex_spr_read, |
ex_spr_write, |
epcr, eear, esr, except_started, |
96,6 → 97,8
input cyforw; // From ALU |
input cy_we; // From ALU |
output carry; // SR[CY] |
input ovforw; // From ALU |
input ov_we; // From ALU |
input [width-1:0] addrbase; // SPR base address |
input [15:0] addrofs; // SPR offset |
input [width-1:0] dat_i; // SPR write data |
285,18 → 288,23
// |
// What to write into SR |
// |
assign to_sr[`OR1200_SR_FO:`OR1200_SR_OV] |
= (except_started) ? sr[`OR1200_SR_FO:`OR1200_SR_OV] : |
assign to_sr[`OR1200_SR_FO:`OR1200_SR_OVE] |
= (except_started) ? {sr[`OR1200_SR_FO:`OR1200_SR_DSX],1'b0} : |
(branch_op == `OR1200_BRANCHOP_RFE) ? |
esr[`OR1200_SR_FO:`OR1200_SR_OV] : (spr_we && sr_sel) ? |
{1'b1, spr_dat_o[`OR1200_SR_FO-1:`OR1200_SR_OV]} : |
sr[`OR1200_SR_FO:`OR1200_SR_OV]; |
esr[`OR1200_SR_FO:`OR1200_SR_OVE] : (spr_we && sr_sel) ? |
{1'b1, spr_dat_o[`OR1200_SR_FO-1:`OR1200_SR_OVE]} : |
sr[`OR1200_SR_FO:`OR1200_SR_OVE]; |
assign to_sr[`OR1200_SR_TED] |
= (except_started) ? 1'b1 : |
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_TED] : |
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_TED] : |
sr[`OR1200_SR_TED]; |
|
assign to_sr[`OR1200_SR_OV] |
= (except_started) ? sr[`OR1200_SR_OV] : |
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_OV] : |
ov_we ? ovforw : |
(spr_we && sr_sel) ? spr_dat_o[`OR1200_SR_OV] : |
sr[`OR1200_SR_OV]; |
assign to_sr[`OR1200_SR_CY] |
= (except_started) ? sr[`OR1200_SR_CY] : |
(branch_op == `OR1200_BRANCHOP_RFE) ? esr[`OR1200_SR_CY] : |
345,7 → 353,7
// Write enables for system SPRs |
// |
assign sr_we = (spr_we && sr_sel) | (branch_op == `OR1200_BRANCHOP_RFE) | |
flag_we | cy_we; |
flag_we | cy_we | ov_we; |
assign pc_we = (du_write && (npc_sel | ppc_sel)); |
assign epcr_we = (spr_we && epcr_sel); |
assign eear_we = (spr_we && eear_sel); |
375,7 → 383,7
// Carry alias |
// |
assign carry = sr[`OR1200_SR_CY]; |
|
|
// |
// Supervision register |
// |
/rtl/verilog/or1200_cpu.v
271,6 → 271,10
wire carry; |
wire cyforw; |
wire cy_we_alu; |
wire ovforw; |
wire ov_we_alu; |
wire ovforw_mult_mac; |
wire ov_we_mult_mac; |
wire cy_we_rf; |
wire lsu_stall; |
wire epcr_we; |
292,6 → 296,7
wire [31:0] wb_insn; |
wire sig_syscall; |
wire sig_trap; |
wire sig_range; |
wire sig_fp; |
wire [31:0] spr_dat_cfgr; |
wire [31:0] spr_dat_rf; |
393,11 → 398,17
assign flag_we = (flag_we_alu | flag_we_fpu) & ~abort_mvspr; |
|
// |
// Flag for any MTSPR instructions, that must block execution, to indicate done |
// Flag for any MTSPR instructions, that must block execution, to indicate done |
// |
assign mtspr_done = mtspr_dc_done; |
|
// |
// Range exception |
// |
assign sig_range = sr[`OR1200_SR_OV]; |
|
|
|
// |
// Instantiation of instruction fetch block |
// |
591,6 → 602,8
.flag_we(flag_we_alu), |
.cyforw(cyforw), |
.cy_we(cy_we_alu), |
.ovforw(ovforw), |
.ov_we(ov_we_alu), |
.flag(flag), |
.carry(carry) |
); |
641,6 → 654,8
.mac_op(mac_op), |
.alu_op(alu_op), |
.result(mult_mac_result), |
.ovforw(ovforw_mult_mac), |
.ov_we(ov_we_mult_mac), |
.mult_mac_stall(mult_mac_stall), |
.spr_cs(spr_cs[`OR1200_SPR_GROUP_MAC]), |
.spr_write(spr_we), |
666,6 → 681,8
.cyforw(cyforw), |
.cy_we(cy_we_rf), |
.carry(carry), |
.ovforw(ovforw | ovforw_mult_mac), |
.ov_we(ov_we_alu | ov_we_mult_mac), |
.to_wbmux(sprs_dataout), |
|
.du_addr(du_addr), |
803,7 → 820,7
.sig_dbuserr(except_dbuserr), |
.sig_illegal(except_illegal), |
.sig_align(except_align), |
.sig_range(1'b0), |
.sig_range(sig_range), |
.sig_dtlbmiss(except_dtlbmiss), |
.sig_dmmufault(except_dmmufault), |
.sig_int(sig_int), |
/rtl/verilog/or1200_mult_mac.v
65,6 → 65,9
ex_freeze, id_macrc_op, macrc_op, a, b, mac_op, alu_op, |
result, mult_mac_stall, |
|
// Overflow |
ovforw, ov_we, |
|
// SPR interface |
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o |
); |
93,7 → 96,8
input [`OR1200_ALUOP_WIDTH-1:0] alu_op; |
output [width-1:0] result; |
output mult_mac_stall; |
|
output ovforw, ov_we; |
|
// |
// SPR interface |
// |
154,9 → 158,11
`else |
reg [width-1:0] div_quot_r; |
reg [width-1:0] div_quot_generic; |
`endif |
`endif |
wire div_by_zero; |
`endif |
|
reg ovforw, ov_we; |
|
// |
// Combinatorial logic |
// |
189,6 → 195,9
assign y = (alu_op_sdiv | alu_op_smul) & b[31] ? ~b + 32'b1 : |
alu_op_div | alu_op_mul | (|mac_op) ? b : 32'd0; |
|
assign div_by_zero = !(|b) & alu_op_div; |
|
|
// Used to indicate when we should check for new multiply or MAC ops |
always @(posedge clk or `OR1200_RST_EVENT rst) |
if (rst == `OR1200_RST_VALUE) |
228,8 → 237,44
`else |
result = {width{1'b0}}; |
`endif |
endcase |
endcase // casez (alu_op) |
|
|
// |
// Overflow generation |
// |
always @* |
casez(alu_op) // synopsys parallel_case |
`ifdef OR1200_IMPL_OV |
`ifdef OR1200_MULT_IMPLEMENTED |
`OR1200_ALUOP_MUL: begin |
// Actually doing unsigned multiply internally, and then negate on |
// output as appropriate, so if sign bit is set, then is overflow |
ovforw = mul_prod_r[31]; |
ov_we = 1; |
end |
`OR1200_ALUOP_MULU : begin |
// Overflow on unsigned multiply is simpler. |
ovforw = mul_prod_r[32]; |
ov_we = 1; |
end |
`endif // `ifdef OR1200_MULT_IMPLEMENTED |
`ifdef OR1200_DIV_IMPLEMENTED |
`OR1200_ALUOP_DIVU, |
`OR1200_ALUOP_DIV: begin |
// Overflow on divide by zero |
ovforw = div_by_zero; |
ov_we = 1; |
end |
`endif |
`endif // `ifdef OR1200_IMPL_OV |
default: begin |
ovforw = 0; |
ov_we = 0; |
end |
endcase // casez (alu_op) |
|
|
`ifdef OR1200_MULT_IMPLEMENTED |
`ifdef OR1200_MULT_SERIAL |
|
398,6 → 443,11
div_free <= 1'b1; |
div_cntr <= 6'b00_0000; |
end |
else if (div_by_zero) begin |
div_quot_r <= 64'h0000_0000_0000_0000; |
div_free <= 1'b1; |
div_cntr <= 6'b00_0000; |
end |
else if (|div_cntr) begin |
if (div_tmp[31]) |
div_quot_r <= {div_quot_r[62:0], 1'b0}; |
/rtl/verilog/or1200_except.v
176,7 → 176,8
wire int_pending; |
wire tick_pending; |
wire fp_pending; |
|
wire range_pending; |
|
reg trace_trap ; |
reg ex_freeze_prev; |
reg sr_ted_prev; |
207,6 → 208,13
|
assign fp_pending = sig_fp & fpcsr_fpee & ~ex_freeze & ~ex_branch_taken |
& ~ex_dslot; |
|
`ifdef OR1200_IMPL_OVE |
assign range_pending = sig_range & sr[`OR1200_SR_OVE] & ~ex_freeze & |
~ex_branch_taken & ~ex_dslot; |
`else |
assign range_pending = 0; |
`endif |
|
// Abort write into RF by load & other instructions |
assign abort_ex = sig_dbuserr | sig_dmmufault | sig_dtlbmiss | sig_align | |
234,7 → 242,7
sig_syscall & ~du_dsr[`OR1200_DU_DSR_SCE] & ~ex_freeze, |
sig_dmmufault & ~du_dsr[`OR1200_DU_DSR_DPFE], |
sig_dbuserr & ~du_dsr[`OR1200_DU_DSR_BUSEE], |
sig_range & ~du_dsr[`OR1200_DU_DSR_RE], |
range_pending & ~du_dsr[`OR1200_DU_DSR_RE], |
fp_pending & ~du_dsr[`OR1200_DU_DSR_FPE], |
int_pending & ~du_dsr[`OR1200_DU_DSR_IE], |
tick_pending & ~du_dsr[`OR1200_DU_DSR_TTE] |
260,7 → 268,7
sig_dtlbmiss & du_dsr[`OR1200_DU_DSR_DME], |
sig_dmmufault & du_dsr[`OR1200_DU_DSR_DPFE], |
sig_dbuserr & du_dsr[`OR1200_DU_DSR_BUSEE], |
sig_range & du_dsr[`OR1200_DU_DSR_RE], |
range_pending & du_dsr[`OR1200_DU_DSR_RE], |
sig_trap & du_dsr[`OR1200_DU_DSR_TE], |
fp_pending & du_dsr[`OR1200_DU_DSR_FPE], |
sig_syscall & du_dsr[`OR1200_DU_DSR_SCE] & ~ex_freeze |