Skip to content
Permalink
Browse files

or1200: add carry, overflow bits, and range exception

  • Loading branch information...
julius
julius committed Sep 1, 2011
1 parent bc9b53b commit 2c0765d7ba12813df273cd693a99c4e744f0fbd5
@@ -56,6 +56,7 @@ module or1200_alu(
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 flagforw;
output flag_we;
output cyforw;
output cy_we;
output ovforw;
output ov_we;
input carry;
input flag;

@@ -91,24 +94,28 @@ reg [width-1:0] result_cust5;
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
wire a_eq_b;
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_eq_b = (comp_a == comp_b);
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 @@ end
//
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 @@ always @(alu_op or alu_op2 or a or b or result_sum or result_and or macrc_op
`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 @@ end
// 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,26 +288,20 @@ end
//
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
`endif
) 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,6 +316,31 @@ always @(alu_op or cy_sum
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
//
@@ -271,6 +271,10 @@ wire flag_we_fpu;
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 fpu_except_started;
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,9 +398,15 @@ assign flagforw = (flag_we_alu & flagforw_alu) | (flagforw_fpu & flag_we_fpu);
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];



//
@@ -591,6 +602,8 @@ or1200_alu or1200_alu(
.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 @@ or1200_mult_mac or1200_mult_mac(
.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 @@ or1200_sprs or1200_sprs(
.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 @@ or1200_except or1200_except(
.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),
@@ -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,7 +321,24 @@
// 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
@@ -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
@@ -176,7 +176,8 @@ reg [2:0] delayed_tee;
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 tick_pending = sig_tick & (sr[`OR1200_SR_TEE] |

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 @@ assign except_trig = {
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 @@ assign except_stop = {
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

0 comments on commit 2c0765d

Please sign in to comment.
You can’t perform that action at this time.