URL
https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk
Subversion Repositories openrisc_2011-10-31
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/orpsocv2
- from Rev 501 to Rev 502
- ↔ Reverse comparison
Rev 501 → Rev 502
/rtl/verilog/include/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/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/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/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/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/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 |
/rtl/verilog/ethmac/eth_fifo.v
219,20 → 219,20
wire [DATA_WIDTH-1:0] data_out2; |
wire [DATA_WIDTH-1:0] data_out3; |
|
wire ramsel0,ramsel1,ramsel2,ramsel3; |
wire we_ram0,we_ram1,we_ram2,we_ram3; |
|
assign ramsel0 = (read_pointer[5:4]==2'b00); |
assign ramsel1 = (read_pointer[5:4]==2'b01); |
assign ramsel2 = (read_pointer[5:4]==2'b10); |
assign ramsel3 = (read_pointer[5:4]==2'b11); |
assign we_ram0 = (write_pointer[5:4]==2'b00); |
assign we_ram1 = (write_pointer[5:4]==2'b01); |
assign we_ram2 = (write_pointer[5:4]==2'b10); |
assign we_ram3 = (write_pointer[5:4]==2'b11); |
|
assign data_out = ramsel3 ? data_out3 : |
ramsel2 ? data_out2 : |
ramsel1 ? data_out1 : data_out0; |
assign data_out = (read_pointer[5:4]==2'b11) ? data_out3 : |
(read_pointer[5:4]==2'b10) ? data_out2 : |
(read_pointer[5:4]==2'b01) ? data_out1 : data_out0; |
|
xilinx_dist_ram_16x32 fifo0 |
( .data_out(data_out0), |
.we((write & ~full) & ramsel0), |
.we(write & ~full & we_ram0), |
.data_in(data_in), |
.read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]), |
.write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]), |
241,7 → 241,7
|
xilinx_dist_ram_16x32 fifo1 |
( .data_out(data_out1), |
.we(write & ~full & ramsel1), |
.we(write & ~full & we_ram1), |
.data_in(data_in), |
.read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]), |
.write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]), |
250,7 → 250,7
|
xilinx_dist_ram_16x32 fifo2 |
( .data_out(data_out2), |
.we(write & ~full & ramsel2), |
.we(write & ~full & we_ram2), |
.data_in(data_in), |
.read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]), |
.write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]), |
259,7 → 259,7
|
xilinx_dist_ram_16x32 fifo3 |
( .data_out(data_out3), |
.we(write & ~full & ramsel3), |
.we(write & ~full & we_ram3), |
.data_in(data_in), |
.read_address( clear ? {CNT_WIDTH-1{1'b0}} : read_pointer[3:0]), |
.write_address(clear ? {CNT_WIDTH-1{1'b0}} : write_pointer[3:0]), |
/sim/bin/Makefile
64,6 → 64,8
or1200-except \ |
or1200-mac \ |
or1200-ext \ |
or1200-cy \ |
or1200-ov \ |
or1200-ffl1 \ |
or1200-linkregtest \ |
or1200-tick \ |
/sw/tests/or1200/sim/or1200-cy.S
0,0 → 1,302
/* |
OR1200 carry bit checking |
|
Carry generated on all adds which we interpret to be |
unsigned. The CPU will generate both CY and OV. |
CY is generated when unsigned values generate an extra bit. |
OV is when the values, interpreted as signed, cannot have |
the result displayed as it is too large. |
|
OV is not checked here. Just CY generation and inclusion by |
the l.addc and l.addic instructions. |
|
Very basic, testing. |
|
TODO: Substraction carry out testing. |
|
Julius Baxter, ORSoC AB, julius.baxter@orsoc.se |
|
*/ |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2011 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
#include "spr-defs.h" |
#include "board.h" |
#include "or1200-defines.h" |
|
|
/* =================================================== [ exceptions ] === */ |
.section .vectors, "ax" |
|
|
/* ---[ 0x100: RESET exception ]----------------------------------------- */ |
.org 0x100 |
l.movhi r0, 0 |
/* Clear status register */ |
l.ori r1, r0, SPR_SR_SM |
l.mtspr r0, r1, SPR_SR |
/* Clear timer */ |
l.mtspr r0, r0, SPR_TTMR |
|
/* Jump to program initialisation code */ |
.global _start |
l.movhi r4, hi(_start) |
l.ori r4, r4, lo(_start) |
l.jr r4 |
l.nop |
|
.org 0x600 |
l.nop 0x1 |
|
|
/* ---[ 0x700: Illegal instruction exception ]-------------------------- */ |
.org 0x700 |
#ifndef OR1200_IMPL_ADDC |
// No problem - instruction not supported |
l.movhi r3, hi(0x8000000d) |
l.ori r3, r3, lo(0x8000000d) |
l.nop 0x2 |
l.ori r3, r0, 0 |
#else |
l.ori r3, r0, 1 |
#endif |
l.nop 0x1 |
|
/* ---[ 0xb00: Range exception ]---------------------------------------- */ |
.org 0xb00 |
l.sw 0(r0), r3 |
l.ori r3, r0, 0xaaee |
l.nop 0x2 |
l.lwz r3, 0(r0) |
l.rfe |
|
/* =================================================== [ text ] === */ |
.section .text |
|
/* =================================================== [ start ] === */ |
|
.global _start |
_start: |
// Clear all regs |
l.movhi r1, 0 |
l.movhi r2, 0 |
l.movhi r3, 0 |
l.movhi r4, 0 |
l.movhi r5, 0 |
l.movhi r6, 0 |
l.movhi r7, 0 |
l.movhi r8, 0 |
l.movhi r9, 0 |
l.movhi r10, 0 |
l.movhi r11, 0 |
l.movhi r12, 0 |
l.movhi r13, 0 |
l.movhi r14, 0 |
l.movhi r15, 0 |
l.movhi r16, 0 |
l.movhi r17, 0 |
l.movhi r18, 0 |
l.movhi r19, 0 |
l.movhi r20, 0 |
l.movhi r21, 0 |
l.movhi r22, 0 |
l.movhi r23, 0 |
l.movhi r24, 0 |
l.movhi r25, 0 |
l.movhi r26, 0 |
l.movhi r27, 0 |
l.movhi r28, 0 |
l.movhi r29, 0 |
l.movhi r30, 0 |
l.movhi r31, 0 |
|
#ifdef OR1200_IMPL_CY |
// Kick off test |
l.jal _main |
#else |
// Not supported, exit test |
l.j _finish |
#endif |
l.nop |
|
|
/* =================================================== [ main ] === */ |
|
|
#define CHECK_CY_CLEAR \ |
l.mfspr r20, r0, SPR_SR ; \ |
l.andi r21, r20, SPR_SR_CY ; \ |
l.sfne r21, r0 ; \ |
l.bf _fail ; \ |
l.nop |
|
#define CHECK_CY_SET \ |
l.mfspr r20, r0, SPR_SR ; \ |
l.andi r21, r20, SPR_SR_CY ; \ |
l.sfnei r21, SPR_SR_CY ; \ |
l.bf _fail ; \ |
l.nop |
|
.global _main |
_main: |
|
// Set up some values, check the CY bit is cleared from reset |
CHECK_CY_CLEAR |
|
// A large unsigned value |
l.movhi r4, 0xffff |
l.ori r4, r4, 0xefff |
|
// A value large enough to cause carry |
l.ori r5, r0, 0x1001 |
|
l.add r3, r5, r4 ;// Should set CY |
l.nop 0x2 |
CHECK_CY_SET |
|
l.add r3, r0, r0 ;// Should clear CY |
CHECK_CY_CLEAR |
|
l.addi r3, r4, 0x1001 ;// Should set CY |
l.nop 0x2 |
CHECK_CY_SET |
|
l.addi r3, r4, 0x1000 ;// Shouldn't set CY |
l.nop 0x2 |
CHECK_CY_CLEAR |
|
l.add r3, r0, r0 ;// Should clear CY |
CHECK_CY_CLEAR |
|
// Check use of carry - l.addc |
l.addi r3, r4, 0x1001 ;// Should set CY |
;; // Consequtive instructions |
l.addc r3, r3, r5 ;// r3 should be 0x1002 |
l.nop 0x2 ;// Report |
|
l.sfnei r3, 0x1002 |
l.bf _fail |
l.nop |
|
l.add r3, r4, r5 ;// Should set CY |
l.nop ;// 1 delay instruction |
l.addc r3, r3, r5 ;// r3 should be 0x1002 |
l.nop 0x2 ;// Report |
|
l.sfnei r3, 0x1002 |
l.bf _fail |
l.nop |
|
l.add r3, r4, r5 ;// Should set |
l.nop 0x2 ;// 1 delay instruction |
l.nop ;// 2nd delay instruction |
l.addc r3, r3, r5 ;// r3 should be 0x1002 |
l.nop 0x2 ;// Report |
|
l.sfnei r3, 0x1002 |
l.bf _fail |
l.nop |
|
l.add r3, r0, r0 ;// Should clear CY |
CHECK_CY_CLEAR |
|
// Check use of carry - l.addic |
l.addi r3, r4, 0x1001 ;// Should set CY |
;; // Consequtive instructions |
l.addic r3, r3, 0x1 ;// r3 should be 2 |
l.nop 0x2 ;// Report |
|
l.sfnei r3, 0x2 |
l.bf _fail |
l.nop |
|
l.add r3, r0, r0 ;// Should clear CY |
CHECK_CY_CLEAR |
|
l.add r3, r4, r5 ;// Should set CY |
l.nop ;// 1 delay instruction |
l.addic r3, r3, 0x1 ;// r3 should be 2 |
l.nop 0x2 ;// Report |
|
l.sfnei r3, 0x2 |
l.bf _fail |
l.nop |
|
l.add r3, r0, r0 ;// Should clear CY |
CHECK_CY_CLEAR |
|
l.add r3, r4, r5 ;// Should set |
l.nop 0x2 ;// 1 delay instruction |
l.nop ;// 2nd delay instruction |
l.addic r3, r3, 0x1 ;// r3 should be 2 |
l.nop 0x2 ;// Report |
|
l.sfnei r3, 0x2 |
l.bf _fail |
l.nop |
|
l.add r3, r0, r0 ;// Should clear CY |
CHECK_CY_CLEAR |
|
// Add with carry and generate carry with l.addc |
|
l.add r3, r4, r5 |
l.addc r3, r4, r5 |
l.nop 0x2 |
|
l.sfnei r3, 0x1 |
l.bf _fail |
l.nop |
|
CHECK_CY_SET |
|
l.add r3, r0, r0 ;// Should clear CY |
CHECK_CY_CLEAR |
|
// Add with carry and generate carry with l.addic |
|
l.addi r3, r4, 0x1001 |
l.addic r3, r4, 0x1001 |
l.nop 0x2 |
|
l.sfnei r3, 0x1 |
l.bf _fail |
l.nop |
|
CHECK_CY_SET |
|
_finish: |
l.movhi r3, hi(0x8000000d) |
l.ori r3, r3, lo(0x8000000d) |
l.nop 0x2 |
l.ori r3, r0, 0 |
l.nop 0x1 |
|
_fail: |
l.ori r3, r0, 1 |
l.nop 0x1 |
/sw/tests/or1200/sim/or1200-ov.S
0,0 → 1,697
/* |
OR1200 overflow bit checking |
|
Very basic, testing |
|
TODO: Check range exception handling in delay slots |
|
Julius Baxter, ORSoC AB, julius.baxter@orsoc.se |
|
*/ |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2011 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
|
#include "spr-defs.h" |
#include "board.h" |
#include "or1200-defines.h" |
|
|
/* =================================================== [ exceptions ] === */ |
.section .vectors, "ax" |
|
|
/* ---[ 0x100: RESET exception ]----------------------------------------- */ |
.org 0x100 |
l.movhi r0, 0 |
/* Clear status register */ |
l.ori r1, r0, SPR_SR_SM |
l.mtspr r0, r1, SPR_SR |
/* Clear timer */ |
l.mtspr r0, r0, SPR_TTMR |
|
/* Jump to program initialisation code */ |
.global _start |
l.movhi r4, hi(_start) |
l.ori r4, r4, lo(_start) |
l.jr r4 |
l.nop |
|
.org 0x600 |
l.nop 0x1 |
|
|
/* ---[ 0x700: Illegal instruction exception ]-------------------------- */ |
.org 0x700 |
#ifndef OR1200_IMPL_ADDC |
// No problem - instruction not supported |
l.movhi r3, hi(0x8000000d) |
l.ori r3, r3, lo(0x8000000d) |
l.nop 0x2 |
l.ori r3, r0, 0 |
#else |
l.ori r3, r0, 1 |
#endif |
l.nop 0x1 |
|
#define INCREMENT_EXCEPTION_COUNTER l.addi r11, r11, 0x1 |
#define CHECK_EXCEPTION_COUNTER \ |
l.sfne r11, r12 ; \ |
l.bf _fail ; \ |
l.nop ; |
#define EXPECT_RANGE_EXCEPT \ |
l.addi r12, r12, 1 ; \ |
CHECK_EXCEPTION_COUNTER |
|
/* ---[ 0xb00: Range exception ]---------------------------------------- */ |
.org 0xb00 |
l.sw 0(r0), r3 ;// Save r3 - don't disrupt it during exceptions |
l.ori r3, r0, 0xaaee |
l.nop 0x2 |
// TODO - get instruction and decode to ensure it was an instruction |
// which is capable of causing a range exception. Remember delay slot! |
INCREMENT_EXCEPTION_COUNTER |
|
// Clear OV in ESR |
l.mfspr r3,r0,SPR_ESR_BASE ;// Get ESR |
l.nop 2 |
l.xori r3, r3,SPR_SR_OV ;// Clear OV bit |
l.mtspr r0,r3,SPR_ESR_BASE ;// Get EPC |
|
l.mfspr r3,r0,SPR_EPCR_BASE ;// Get EPC |
l.nop 2 |
l.addi r3, r3, 0x4 ;// Increment |
l.mtspr r0,r3,SPR_EPCR_BASE ;// Get EPC |
// For now, increment EPCR so we step over instruction and continue |
|
l.lwz r3, 0(r0) |
l.rfe |
|
/* =================================================== [ text ] === */ |
.section .text |
|
/* =================================================== [ start ] === */ |
|
.global _start |
_start: |
// Clear all regs |
l.movhi r1, 0 |
l.movhi r2, 0 |
l.movhi r3, 0 |
l.movhi r4, 0 |
l.movhi r5, 0 |
l.movhi r6, 0 |
l.movhi r7, 0 |
l.movhi r8, 0 |
l.movhi r9, 0 |
l.movhi r10, 0 |
l.movhi r11, 0 |
l.movhi r12, 0 |
l.movhi r13, 0 |
l.movhi r14, 0 |
l.movhi r15, 0 |
l.movhi r16, 0 |
l.movhi r17, 0 |
l.movhi r18, 0 |
l.movhi r19, 0 |
l.movhi r20, 0 |
l.movhi r21, 0 |
l.movhi r22, 0 |
l.movhi r23, 0 |
l.movhi r24, 0 |
l.movhi r25, 0 |
l.movhi r26, 0 |
l.movhi r27, 0 |
l.movhi r28, 0 |
l.movhi r29, 0 |
l.movhi r30, 0 |
l.movhi r31, 0 |
|
#ifdef OR1200_IMPL_OV |
// Kick off test |
l.jal _main |
#else |
// Not supported, exit test |
l.j _finish |
#endif |
l.nop |
|
|
/* =================================================== [ main ] === */ |
|
|
#define CHECK_OV_CLEAR \ |
l.mfspr r20, r0, SPR_SR ; \ |
l.andi r21, r20, SPR_SR_OV ; \ |
l.sfne r21, r0 ; \ |
l.bf _fail ; \ |
l.nop |
|
#define CHECK_OV_SET \ |
l.mfspr r20, r0, SPR_SR ; \ |
l.andi r21, r20, SPR_SR_OV ; \ |
l.sfnei r21, SPR_SR_OV ; \ |
l.bf _fail ; \ |
l.addi r12, r12, 0x1 ; // Increment expected counter |
|
.global _main |
_main: |
|
// Set up some values, check the OV bit is cleared |
CHECK_OV_CLEAR |
|
l.movhi r4, 0x7fff |
l.ori r4, r4, 0xefff |
|
l.ori r5, r0, 0xffff |
|
l.add r3, r5, r4 ;// Should set overflow |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
l.addi r3, r4, 0x7fff ;// Should set overflow |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
// Now test negative numbers |
|
l.movhi r4, 0x8000 |
l.ori r4, r4, 0x0000 |
|
l.movhi r5, 0xffff |
l.ori r5, r5, 0xffff |
|
l.add r3, r4, r5 // Biggest and smallest negative number |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
l.addi r3, r4, 0xffff // Biggest and smallest negative number |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
l.add r3, r4, r0 // Biggest negative number, and zero |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
l.movhi r5, 0xffff |
l.ori r5, r5, 0xfffe |
|
l.add r3, r4, r5 // Biggest and second smallest negative number |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
#ifdef OR1200_IMPL_SUB |
|
// report indicator that we're at l.sub section 0x55555555 |
l.movhi r3, 0x5555 |
l.ori r3, r3, 0x5555 |
l.nop 0x2 |
|
// Quick subtract check |
// Check largest negative number -1 tripping overflow |
l.ori r5, r0, 1 ; // +1 |
l.sub r3, r4, r5 ; // -2147483647 - 1 |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
#endif |
|
l.movhi r4, 0x8000 |
l.ori r4, r4, 0x0437 |
|
l.movhi r5, 0xffff |
l.ori r5, r5, 0xfbc7 |
|
l.add r3, r4, r5 // Very big negative number, another one big |
// enough to cause overflow hopefully |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
l.movhi r5, 0xffff |
l.ori r5, r5, 0xfff7 |
|
l.add r3, r4, r5 // Two negative numbers but shouldn't overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
#ifdef OR1200_DIV_IMPLEMENTED |
|
// report indicator that we're at l.div section 0xdddddddd |
l.movhi r3, 0xdddd |
l.ori r3, r3, 0xdddd |
l.nop 0x2 |
|
// Test divide by zero |
l.div r3, r5, r0 |
l.nop 0x2 |
|
l.sfne r3, r0 ;// Check result was 0 |
l.bf _fail |
|
CHECK_OV_SET |
|
l.add r3, r5, r0 ;// Should clear overflow |
l.nop 0x2 |
|
CHECK_OV_CLEAR |
|
// Test divide by zero |
l.divu r3, r0, r0 |
l.nop 0x2 |
CHECK_OV_SET |
|
l.sfne r3, r0 ;// Check result was 0 |
l.bf _fail |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
#endif |
|
#ifdef OR1200_MULT_IMPLEMENTED |
|
// report indicator that we're at l.multiply section 0x11111111 |
l.movhi r3, 0x1111 |
l.ori r3, r3, 0x1111 |
l.nop 0x2 |
|
// Check multiplying two large numbers, which will cause overflow, |
// trigger the flag appropriately |
|
// First signed multiply. |
l.movhi r4, 0xd555 ;//-(((2^32)-1)/3 + 2) |
l.ori r4, r4, 0x5552 |
l.ori r5, r0, 2 |
l.ori r6, r0, 3 |
|
// First multiply big negative number by 2 - shouldn't overflow |
l.mul r3, r4, r5 |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
// Now multiply by 3 - should just overflow negative |
l.mul r3, r4, r6 |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
// Now some big positive values |
l.movhi r4, 0x2aaa ;//((2^32)-1)/3 + 2 |
l.ori r4, r4, 0xaaae |
l.ori r5, r0, 2 |
l.ori r6, r0, 3 |
|
// First multiply big number by 2 - shouldn't overflow |
l.mul r3, r4, r5 |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
// Now multiply by 3 - should only just overflow |
l.mul r3, r4, r6 |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
// First multiply big number by 2 - shouldn't overflow |
l.muli r3, r4, 0x2 |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
// Now multiply by 3 - should just overflow negative |
l.muli r3, r4, 0x3 |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
|
// Now check overflow on unsigned multiply |
|
// Some stimulus to make a 32-bit multiply overflow |
l.movhi r4, 0x5555 ;//((2^32))/3 + 2 |
l.ori r4, r4, 0x5557 |
l.ori r5, r0, 2 |
l.ori r6, r0, 3 |
|
// First multiply big negative number by 2 - shouldn't overflow |
l.mulu r3, r4, r5 |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
// Now multiply by 3 - should just overflow negative |
l.mulu r3, r4, r6 |
l.nop 0x2 |
CHECK_OV_SET |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_OV_CLEAR |
|
#endif |
|
///////////////////////////////////////////////////////////// |
// // |
// Range Exception Tests // |
// // |
///////////////////////////////////////////////////////////// |
#ifdef OR1200_IMPL_OVE |
// report indicator that we're at exception section 0xeeeeeeee |
l.movhi r3, 0xeeee |
l.ori r3, r3, 0xeeee |
l.nop 0x2 |
|
// First enable OV exception in SR |
|
l.mfspr r20, r0, SPR_SR |
l.ori r21, r20, SPR_SR_OVE |
l.mtspr r0, r21, SPR_SR |
|
// Check it's set |
l.mfspr r20, r0, SPR_SR |
l.andi r21, r20, SPR_SR_OVE |
l.sfnei r21, SPR_SR_OVE |
l.bf _fail |
l.nop |
|
// now set r11 to r12 to know how many tests we've done so far |
l.or r11, r12, r12 |
|
l.movhi r4, 0x7fff |
l.ori r4, r4, 0xefff |
|
l.ori r5, r0, 0xffff |
|
l.add r3, r5, r4 ;// Should set overflow |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
|
l.addi r3, r4, 0x7fff ;// Should set overflow |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
|
// Now test negative numbers |
|
l.movhi r4, 0x8000 |
l.ori r4, r4, 0x0000 |
|
l.movhi r5, 0xffff |
l.ori r5, r5, 0xffff |
|
l.add r3, r4, r5 // Biggest and smallest negative number |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
l.addi r3, r4, 0xffff // Biggest and smallest negative number |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
l.add r3, r4, r0 // Biggest negative number, and zero |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
|
l.movhi r5, 0xffff |
l.ori r5, r5, 0xfffe |
|
l.add r3, r4, r5 // Biggest and second smallest negative number |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
#ifdef OR1200_IMPL_SUB |
|
// report indicator that we're at l.sub section 0x55555555 |
l.movhi r3, 0x5555 |
l.ori r3, r3, 0x5555 |
l.nop 0x2 |
|
// Quick subtract check |
// Check largest negative number -1 tripping overflow |
l.ori r5, r0, 1 ; // +1 |
l.sub r3, r4, r5 ; // -2147483647 - 1 |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
|
l.sub r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
#endif |
|
l.movhi r4, 0x8000 |
l.ori r4, r4, 0x0437 |
|
l.movhi r5, 0xffff |
l.ori r5, r5, 0xfbc7 |
|
l.add r3, r4, r5 // Very big negative number, another one big |
// enough to cause overflow hopefully |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
l.movhi r5, 0xffff |
l.ori r5, r5, 0xfff7 |
|
l.add r3, r4, r5 // Two negative numbers but shouldn't overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
#ifdef OR1200_DIV_IMPLEMENTED |
|
// report indicator that we're at l.div section 0xdddddddd |
l.movhi r3, 0xdddd |
l.ori r3, r3, 0xdddd |
l.nop 0x2 |
|
// Test divide by zero |
l.div r3, r5, r0 |
l.nop 0x2 |
|
l.sfne r3, r0 ;// Check result was 0 |
l.bf _fail |
|
EXPECT_RANGE_EXCEPT |
|
|
l.add r3, r5, r0 ;// Should clear overflow |
l.nop 0x2 |
|
CHECK_EXCEPTION_COUNTER |
|
// Test divide by zero |
l.divu r3, r0, r0 |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
|
l.sfne r3, r0 ;// Check result was 0 |
l.bf _fail |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
#endif |
|
#ifdef OR1200_MULT_IMPLEMENTED |
|
// report indicator that we're at l.multiply section 0x11111111 |
l.movhi r3, 0x1111 |
l.ori r3, r3, 0x1111 |
l.nop 0x2 |
|
// Check multiplying two large numbers, which will cause overflow, |
// trigger the flag appropriately |
|
// First signed multiply. |
l.movhi r4, 0xd555 ;//-(((2^32)-1)/3 + 2) |
l.ori r4, r4, 0x5552 |
l.ori r5, r0, 2 |
l.ori r6, r0, 3 |
|
// First multiply big negative number by 2 - shouldn't overflow |
l.mul r3, r4, r5 |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
// Now multiply by 3 - should just overflow negative |
l.mul r3, r4, r6 |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
// Now some big positive values |
l.movhi r4, 0x2aaa ;//((2^32)-1)/3 + 2 |
l.ori r4, r4, 0xaaae |
l.ori r5, r0, 2 |
l.ori r6, r0, 3 |
|
// First multiply big number by 2 - shouldn't overflow |
l.mul r3, r4, r5 |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
// Now multiply by 3 - should only just overflow |
l.mul r3, r4, r6 |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
// First multiply big number by 2 - shouldn't overflow |
l.muli r3, r4, 0x2 |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
// Now multiply by 3 - should just overflow negative |
l.muli r3, r4, 0x3 |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
|
// Now check overflow on unsigned multiply |
|
// Some stimulus to make a 32-bit multiply overflow |
l.movhi r4, 0x5555 ;//((2^32))/3 + 2 |
l.ori r4, r4, 0x5557 |
l.ori r5, r0, 2 |
l.ori r6, r0, 3 |
|
// First multiply big negative number by 2 - shouldn't overflow |
l.mulu r3, r4, r5 |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
// Now multiply by 3 - should just overflow negative |
l.mulu r3, r4, r6 |
l.nop 0x2 |
EXPECT_RANGE_EXCEPT |
|
l.add r3, r0, r0 ;// Should clear overflow |
l.nop 0x2 |
CHECK_EXCEPTION_COUNTER |
|
#endif |
|
#endif |
|
|
_finish: |
l.movhi r3, hi(0x8000000d) |
l.ori r3, r3, lo(0x8000000d) |
l.nop 0x2 |
l.ori r3, r0, 0 |
l.nop 0x1 |
|
_fail: |
l.or r3, r12, r0 ;// Fail and report test number we were up to |
l.nop 0x1 |
/boards/actel/ordb1a3pe1500/rtl/verilog/include/or1200_defines.v
324,6 → 324,23
//`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 |
/boards/xilinx/ml501/rtl/verilog/include/ethmac_defines.v
225,12 → 225,12
//`define ETH_RX_FIFO_DEPTH 256 |
//`define ETH_RX_FIFO_CNT_WIDTH 7 |
//`define ETH_RX_FIFO_DEPTH 128 |
//`define ETH_RX_FIFO_CNT_WIDTH 6 |
//`define ETH_RX_FIFO_DEPTH 64 |
`define ETH_RX_FIFO_CNT_WIDTH 6 |
`define ETH_RX_FIFO_DEPTH 64 |
//`define ETH_RX_FIFO_CNT_WIDTH 5 |
//`define ETH_RX_FIFO_DEPTH 32 |
`define ETH_RX_FIFO_CNT_WIDTH 4 |
`define ETH_RX_FIFO_DEPTH 16 |
//`define ETH_RX_FIFO_CNT_WIDTH 4 |
//`define ETH_RX_FIFO_DEPTH 16 |
|
`define ETH_RX_FIFO_DATA_WIDTH 32 |
|
/boards/xilinx/ml501/rtl/verilog/include/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 |
/boards/xilinx/ml501/rtl/verilog/include/uart_defines.v
240,7 → 240,7
`define FAST_TEST 1 // 64/1024 packets are sent |
|
// Defines hard baud prescaler register - uncomment to enable |
`define PRESCALER_PRESET_HARD |
//`define PRESCALER_PRESET_HARD |
// 115200 baud preset values |
// 20MHz: prescaler 10.8 (11, rounded up) |
//`define PRESCALER_HIGH_PRESET 8'd0 |
249,6 → 249,6
//`define PRESCALER_HIGH_PRESET 8'd0 |
//`define PRESCALER_LOW_PRESET 8'd27 |
// 66MHz: prescaler 36.1 |
`define PRESCALER_HIGH_PRESET 8'd0 |
`define PRESCALER_LOW_PRESET 8'd36 |
//`define PRESCALER_HIGH_PRESET 8'd0 |
//`define PRESCALER_LOW_PRESET 8'd36 |
|