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
- from Rev 639 to Rev 640
- ↔ Reverse comparison
Rev 639 → Rev 640
/or1200/rtl/verilog/or1200_defines.v
354,6 → 354,16
`define OR1200_IMPL_ALU_FFL1 |
|
// |
// Implement l.cust5 ALU instruction |
// |
//`define OR1200_IMPL_ALU_CUST5 |
|
// |
// Implement l.extXs and l.extXz instructions |
// |
`define OR1200_IMPL_ALU_EXT |
|
// |
// Implement multiplier |
// |
// By default multiplier is implemented |
395,7 → 405,6
// |
//`define OR1200_FPU_IMPLEMENTED |
|
|
// |
// Clock ratio RISC clock versus WB clock |
// |
452,37 → 461,35
// |
// ALUOPs |
// |
`define OR1200_ALUOP_WIDTH 4 |
`define OR1200_ALUOP_NOP 4'd4 |
/* Order defined by arith insns that have two source operands both in regs |
(see binutils/include/opcode/or32.h) */ |
`define OR1200_ALUOP_ADD 4'd0 |
`define OR1200_ALUOP_ADDC 4'd1 |
`define OR1200_ALUOP_SUB 4'd2 |
`define OR1200_ALUOP_AND 4'd3 |
`define OR1200_ALUOP_OR 4'd4 |
`define OR1200_ALUOP_XOR 4'd5 |
`define OR1200_ALUOP_MUL 4'd6 |
`define OR1200_ALUOP_CUST5 4'd7 |
`define OR1200_ALUOP_SHROT 4'd8 |
`define OR1200_ALUOP_DIV 4'd9 |
`define OR1200_ALUOP_DIVU 4'd10 |
`define OR1200_ALUOP_MULU 4'd11 |
/* Values sent to ALU from decode unit - not strictly defined by ISA */ |
`define OR1200_ALUOP_MOVHI 4'd12 |
`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_FFL1 4'd15 |
`define OR1200_ALUOP_WIDTH 5 |
`define OR1200_ALUOP_NOP 5'b0_0100 |
/* LS-nibble encodings correspond to bits [3:0] of instruction */ |
`define OR1200_ALUOP_ADD 5'b0_0000 // 0 |
`define OR1200_ALUOP_ADDC 5'b0_0001 // 1 |
`define OR1200_ALUOP_SUB 5'b0_0010 // 2 |
`define OR1200_ALUOP_AND 5'b0_0011 // 3 |
`define OR1200_ALUOP_OR 5'b0_0100 // 4 |
`define OR1200_ALUOP_XOR 5'b0_0101 // 5 |
`define OR1200_ALUOP_MUL 5'b0_0110 // 6 |
`define OR1200_ALUOP_RESERVED 5'b0_0111 // 7 |
`define OR1200_ALUOP_SHROT 5'b0_1000 // 8 |
`define OR1200_ALUOP_DIV 5'b0_1001 // 9 |
`define OR1200_ALUOP_DIVU 5'b0_1010 // a |
`define OR1200_ALUOP_MULU 5'b0_1011 // b |
`define OR1200_ALUOP_EXTHB 5'b0_1100 // c |
`define OR1200_ALUOP_EXTW 5'b0_1101 // d |
`define OR1200_ALUOP_CMOV 5'b0_1110 // e |
`define OR1200_ALUOP_FFL1 5'b0_1111 // f |
|
/* Values sent to ALU from decode unit - not defined by ISA */ |
`define OR1200_ALUOP_COMP 5'b1_0000 // Comparison |
`define OR1200_ALUOP_MOVHI 5'b1_0001 // Move-high |
`define OR1200_ALUOP_CUST5 5'b1_0010 // l.cust5 |
|
// ALU instructions second opcode field (previously multicycle field in |
// machine word) |
`define OR1200_ALUOP2_POS 9:8 |
`define OR1200_ALUOP2_WIDTH 2 |
// ALU instructions second opcode field |
`define OR1200_ALUOP2_POS 9:6 |
`define OR1200_ALUOP2_WIDTH 4 |
|
|
// |
// MACOPs |
// |
494,13 → 501,25
// |
// Shift/rotate ops |
// |
`define OR1200_SHROTOP_WIDTH 2 |
`define OR1200_SHROTOP_NOP 2'd0 |
`define OR1200_SHROTOP_SLL 2'd0 |
`define OR1200_SHROTOP_SRL 2'd1 |
`define OR1200_SHROTOP_SRA 2'd2 |
`define OR1200_SHROTOP_ROR 2'd3 |
`define OR1200_SHROTOP_WIDTH 4 |
`define OR1200_SHROTOP_NOP 4'd0 |
`define OR1200_SHROTOP_SLL 4'd0 |
`define OR1200_SHROTOP_SRL 4'd1 |
`define OR1200_SHROTOP_SRA 4'd2 |
`define OR1200_SHROTOP_ROR 4'd3 |
|
// |
// Zero/Sign Extend ops |
// |
`define OR1200_EXTHBOP_WIDTH 4 |
`define OR1200_EXTHBOP_BS 4'h1 |
`define OR1200_EXTHBOP_HS 4'h0 |
`define OR1200_EXTHBOP_BZ 4'h3 |
`define OR1200_EXTHBOP_HZ 4'h2 |
`define OR1200_EXTWOP_WIDTH 4 |
`define OR1200_EXTWOP_WS 4'h0 |
`define OR1200_EXTWOP_WZ 4'h1 |
|
// Execution cycles per instruction |
`define OR1200_MULTICYCLE_WIDTH 3 |
`define OR1200_ONE_CYCLE 3'd0 |
508,9 → 527,12
|
// Execution control which will "wait on" a module to finish |
`define OR1200_WAIT_ON_WIDTH 2 |
`define OR1200_WAIT_ON_FPU `OR1200_WAIT_ON_WIDTH'd1 |
`define OR1200_WAIT_ON_MTSPR `OR1200_WAIT_ON_WIDTH'd2 |
`define OR1200_WAIT_ON_NOTHING `OR1200_WAIT_ON_WIDTH'd0 |
`define OR1200_WAIT_ON_MULTMAC `OR1200_WAIT_ON_WIDTH'd1 |
`define OR1200_WAIT_ON_FPU `OR1200_WAIT_ON_WIDTH'd2 |
`define OR1200_WAIT_ON_MTSPR `OR1200_WAIT_ON_WIDTH'd3 |
|
|
// Operand MUX selects |
`define OR1200_SEL_WIDTH 2 |
`define OR1200_SEL_RF 2'd0 |
650,6 → 672,7
`define OR1200_OR32_BF 6'b000100 |
`define OR1200_OR32_NOP 6'b000101 |
`define OR1200_OR32_MOVHI 6'b000110 |
`define OR1200_OR32_MACRC 6'b000110 |
`define OR1200_OR32_XSYNC 6'b001000 |
`define OR1200_OR32_RFE 6'b001001 |
/* */ |
681,9 → 704,8
`define OR1200_OR32_SH 6'b110111 |
`define OR1200_OR32_ALU 6'b111000 |
`define OR1200_OR32_SFXX 6'b111001 |
//`define OR1200_OR32_CUST5 6'b111100 |
`define OR1200_OR32_CUST5 6'b111100 |
|
|
///////////////////////////////////////////////////// |
// |
// Exceptions |
/or1200/rtl/verilog/or1200_freeze.v
130,11 → 130,11
assign if_freeze = id_freeze | extend_flush; |
|
assign id_freeze = (lsu_stall | (~lsu_unstall & if_stall) | multicycle_freeze |
| (|waiting_on) | force_dslot_fetch) | du_stall | mac_stall; |
| (|waiting_on) | force_dslot_fetch) | du_stall; |
assign ex_freeze = wb_freeze; |
|
assign wb_freeze = (lsu_stall | (~lsu_unstall & if_stall) | multicycle_freeze |
| (|waiting_on)) | du_stall | mac_stall | abort_ex; |
| (|waiting_on)) | du_stall | abort_ex; |
|
// |
// registered flushpipe |
171,6 → 171,8
always @(posedge clk or `OR1200_RST_EVENT rst) |
if (rst == `OR1200_RST_VALUE) |
waiting_on <= 0; |
else if ((waiting_on == `OR1200_WAIT_ON_MULTMAC) & !mac_stall) |
waiting_on <= 0; |
else if ((waiting_on == `OR1200_WAIT_ON_FPU) & fpu_done) |
waiting_on <= 0; |
else if ((waiting_on == `OR1200_WAIT_ON_MTSPR) & mtspr_done) |
/or1200/rtl/verilog/or1200_alu.v
53,7 → 53,7
|
module or1200_alu( |
a, b, mult_mac_result, macrc_op, |
alu_op, alu_op2, shrot_op, comp_op, |
alu_op, alu_op2, comp_op, |
cust5_op, cust5_limm, |
result, flagforw, flag_we, |
cyforw, cy_we, carry, flag |
70,7 → 70,6
input macrc_op; |
input [`OR1200_ALUOP_WIDTH-1:0] alu_op; |
input [`OR1200_ALUOP2_WIDTH-1:0] alu_op2; |
input [`OR1200_SHROTOP_WIDTH-1:0] shrot_op; |
input [`OR1200_COMPOP_WIDTH-1:0] comp_op; |
input [4:0] cust5_op; |
input [5:0] cust5_limm; |
87,6 → 86,7
// |
reg [width-1:0] result; |
reg [width-1:0] shifted_rotated; |
reg [width-1:0] extended; |
reg [width-1:0] result_cust5; |
reg flagforw; |
reg flagcomp; |
148,6 → 148,9
`ifdef OR1200_IMPL_ADDC |
or result_csum |
`endif |
`ifdef OR1200_IMPL_ALU_EXT |
or extended |
`endif |
) begin |
`ifdef OR1200_CASE_DEFAULT |
casez (alu_op) // synopsys parallel_case |
169,10 → 172,13
end |
endcase // casez (alu_op2) |
end // case: `OR1200_ALUOP_FFL1 |
`endif |
`endif // `ifdef OR1200_IMPL_ALU_FFL1 |
`ifdef OR1200_IMPL_ALU_CUST5 |
|
`OR1200_ALUOP_CUST5 : begin |
result = result_cust5; |
end |
`endif |
`OR1200_ALUOP_SHROT : begin |
result = shifted_rotated; |
end |
195,6 → 201,14
`OR1200_ALUOP_OR : begin |
result = a | b; |
end |
`ifdef OR1200_IMPL_ALU_EXT |
`OR1200_ALUOP_EXTHB : begin |
result = extended; |
end |
`OR1200_ALUOP_EXTW : begin |
result = extended; |
end |
`endif |
`OR1200_ALUOP_MOVHI : begin |
if (macrc_op) begin |
result = mult_mac_result; |
228,34 → 242,6
end |
|
// |
// l.cust5 custom instructions |
// |
// Examples for move byte, set bit and clear bit |
// |
always @(cust5_op or cust5_limm or a or b) begin |
casez (cust5_op) // synopsys parallel_case |
5'h1 : begin |
casez (cust5_limm[1:0]) |
2'h0: result_cust5 = {a[31:8], b[7:0]}; |
2'h1: result_cust5 = {a[31:16], b[7:0], a[7:0]}; |
2'h2: result_cust5 = {a[31:24], b[7:0], a[15:0]}; |
2'h3: result_cust5 = {b[7:0], a[23:0]}; |
endcase |
end |
5'h2 : |
result_cust5 = a | (1 << cust5_limm); |
5'h3 : |
result_cust5 = a & (32'hffffffff ^ (1 << cust5_limm)); |
// |
// *** Put here new l.cust5 custom instructions *** |
// |
default: begin |
result_cust5 = a; |
end |
endcase |
end |
|
// |
// Generate flag and flag write enable |
// |
always @(alu_op or result_sum or result_and or flagcomp |
333,19 → 319,22
// |
// Shifts and rotation |
// |
always @(shrot_op or a or b) begin |
case (shrot_op) // synopsys parallel_case |
`OR1200_SHROTOP_SLL : |
always @(alu_op2 or a or b) begin |
case (alu_op2) // synopsys parallel_case |
`OR1200_SHROTOP_SLL : |
shifted_rotated = (a << b[4:0]); |
`OR1200_SHROTOP_SRL : |
`OR1200_SHROTOP_SRL : |
shifted_rotated = (a >> b[4:0]); |
|
`ifdef OR1200_IMPL_ALU_ROTATE |
`OR1200_SHROTOP_ROR : |
shifted_rotated = (a << (6'd32-{1'b0, b[4:0]})) | (a >> b[4:0]); |
`OR1200_SHROTOP_ROR : |
shifted_rotated = (a << (6'd32-{1'b0,b[4:0]})) | |
(a >> b[4:0]); |
`endif |
default: |
shifted_rotated = ({32{a[31]}} << (6'd32-{1'b0, b[4:0]})) | a >> b[4:0]; |
default: |
shifted_rotated = ({32{a[31]}} << |
(6'd32-{1'b0, b[4:0]})) | |
a >> b[4:0]; |
endcase |
end |
|
397,4 → 386,47
end |
`endif |
|
`ifdef OR1200_IMPL_ALU_EXT |
always @(alu_op or alu_op2 or a) begin |
casez (alu_op2) |
`OR1200_EXTHBOP_HS : extended = {{16{a[15]}},a[15:0]}; |
`OR1200_EXTHBOP_BS : extended = {{24{a[7]}},a[7:0]}; |
`OR1200_EXTHBOP_HZ : extended = {16'd0,a[15:0]}; |
`OR1200_EXTHBOP_BZ : extended = {24'd0,a[7:0]}; |
default: extended = a; // Used for l.extw instructions |
endcase // casez (alu_op2) |
end |
`endif |
|
|
// |
// l.cust5 custom instructions |
// |
`ifdef OR1200_IMPL_ALU_CUST5 |
// Examples for move byte, set bit and clear bit |
// |
always @(cust5_op or cust5_limm or a or b) begin |
casez (cust5_op) // synopsys parallel_case |
5'h1 : begin |
casez (cust5_limm[1:0]) |
2'h0: result_cust5 = {a[31:8], b[7:0]}; |
2'h1: result_cust5 = {a[31:16], b[7:0], a[7:0]}; |
2'h2: result_cust5 = {a[31:24], b[7:0], a[15:0]}; |
2'h3: result_cust5 = {b[7:0], a[23:0]}; |
endcase |
end |
5'h2 : |
result_cust5 = a | (1 << cust5_limm); |
5'h3 : |
result_cust5 = a & (32'hffffffff ^ (1 << cust5_limm)); |
// |
// *** Put here new l.cust5 custom instructions *** |
// |
default: begin |
result_cust5 = a; |
end |
endcase |
end // always @ (cust5_op or cust5_limm or a or b) |
`endif |
|
endmodule |
/or1200/rtl/verilog/or1200_cpu.v
222,7 → 222,6
wire [dw-1:2] ex_branch_addrtarget; |
wire [`OR1200_ALUOP_WIDTH-1:0] alu_op; |
wire [`OR1200_ALUOP2_WIDTH-1:0] alu_op2; |
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; |
487,7 → 486,6
.alu_op(alu_op), |
.alu_op2(alu_op2), |
.mac_op(mac_op), |
.shrot_op(shrot_op), |
.comp_op(comp_op), |
.rf_addrw(rf_addrw), |
.rfwb_op(rfwb_op), |
585,7 → 583,6
.macrc_op(ex_macrc_op), |
.alu_op(alu_op), |
.alu_op2(alu_op2), |
.shrot_op(shrot_op), |
.comp_op(comp_op), |
.cust5_op(cust5_op), |
.cust5_limm(cust5_limm), |
/or1200/rtl/verilog/or1200_ctrl.v
62,7 → 62,7
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, alu_op2, mac_op, shrot_op, |
rf_addra, rf_addrb, rf_rda, rf_rdb, alu_op, alu_op2, mac_op, |
comp_op, rf_addrw, rfwb_op, fpu_op, |
wb_insn, id_simm, ex_simm, id_branch_addrtarget, ex_branch_addrtarget, sel_a, |
sel_b, id_lsu_op, |
102,7 → 102,6
output [`OR1200_ALUOP_WIDTH-1:0] alu_op; |
output [`OR1200_ALUOP2_WIDTH-1:0] alu_op2; |
output [`OR1200_MACOP_WIDTH-1:0] mac_op; |
output [`OR1200_SHROTOP_WIDTH-1:0] shrot_op; |
output [`OR1200_RFWBOP_WIDTH-1:0] rfwb_op; |
output [`OR1200_FPUOP_WIDTH-1:0] fpu_op; |
input pc_we; |
156,7 → 155,6
wire [`OR1200_MACOP_WIDTH-1:0] mac_op; |
wire ex_macrc_op; |
`endif |
reg [`OR1200_SHROTOP_WIDTH-1:0] shrot_op; |
reg [31:0] id_insn /* verilator public */; |
reg [31:0] ex_insn /* verilator public */; |
reg [31:0] wb_insn /* verilator public */; |
196,11 → 194,12
assign rf_rdb = if_insn[30]; |
|
// |
// Force fetch of delay slot instruction when jump/branch is preceeded by load/store |
// instructions |
// Force fetch of delay slot instruction when jump/branch is preceeded by |
// load/store instructions |
// |
assign force_dslot_fetch = 1'b0; |
assign no_more_dslot = (|ex_branch_op & !id_void & ex_branch_taken) | (ex_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]; |
211,7 → 210,8
|
// |
// 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) |
// ex_delayslot_nop: (filler) nop insn is in EX stage (before nops |
// jump/branch was executed) |
// |
// ex_delayslot_dsi & !ex_delayslot_nop - DS insn in EX stage |
// !ex_delayslot_dsi & ex_delayslot_nop - NOP insn in EX stage, |
232,10 → 232,12
ex_delayslot_dsi <= 1'b0; |
end |
else if (!ex_freeze) begin |
ex_delayslot_nop <= id_void && ex_branch_taken && (ex_branch_op != `OR1200_BRANCHOP_NOP) && |
(ex_branch_op != `OR1200_BRANCHOP_RFE); |
ex_delayslot_dsi <= !id_void && ex_branch_taken && (ex_branch_op != `OR1200_BRANCHOP_NOP) && |
(ex_branch_op != `OR1200_BRANCHOP_RFE); |
ex_delayslot_nop <= id_void && ex_branch_taken && |
(ex_branch_op != `OR1200_BRANCHOP_NOP) && |
(ex_branch_op != `OR1200_BRANCHOP_RFE); |
ex_delayslot_dsi <= !id_void && ex_branch_taken && |
(ex_branch_op != `OR1200_BRANCHOP_NOP) && |
(ex_branch_op != `OR1200_BRANCHOP_RFE); |
end |
end |
|
273,7 → 275,8
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: |
`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 |
285,7 → 288,7
// l.maci |
`ifdef OR1200_MAC_IMPLEMENTED |
`OR1200_OR32_MACI: |
id_simm = {{16{id_insn[25]}}, id_insn[25:21], id_insn[10:0]}; |
id_simm = {{16{id_insn[15]}}, id_insn[15:0]}; |
`endif |
|
// l.mtspr |
343,7 → 346,7
// l.macrc in ID stage |
// |
`ifdef OR1200_MAC_IMPLEMENTED |
assign id_macrc_op = (id_insn[31:26] == `OR1200_OR32_MOVHI) & id_insn[16]; |
assign id_macrc_op = (id_insn[31:26] == `OR1200_OR32_MACRC) & id_insn[16]; |
`else |
assign id_macrc_op = 1'b0; |
`endif |
373,7 → 376,8
// |
// |
// |
assign rfe = (id_branch_op == `OR1200_BRANCHOP_RFE) | (ex_branch_op == `OR1200_BRANCHOP_RFE); |
assign rfe = (id_branch_op == `OR1200_BRANCHOP_RFE) | |
(ex_branch_op == `OR1200_BRANCHOP_RFE); |
|
|
`ifdef verilator |
418,7 → 422,8
// |
// Generation of sel_b |
// |
always @(rf_addrw or sel_imm or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw) |
always @(rf_addrw or sel_imm or id_insn or rfwb_op or wbforw_valid or |
wb_rfaddrw) |
if (sel_imm) |
sel_b = `OR1200_SEL_IMM; |
else if ((id_insn[15:11] == rf_addrw) && rfwb_op[0]) |
433,55 → 438,9
// |
always @(id_insn) begin |
case (id_insn[31:26]) // synopsys parallel_case |
`ifdef UNUSED |
// l.lwz |
`OR1200_OR32_LWZ: |
multicycle = `OR1200_TWO_CYCLES; |
|
// l.lbz |
`OR1200_OR32_LBZ: |
multicycle = `OR1200_TWO_CYCLES; |
|
// l.lbs |
`OR1200_OR32_LBS: |
multicycle = `OR1200_TWO_CYCLES; |
|
// l.lhz |
`OR1200_OR32_LHZ: |
multicycle = `OR1200_TWO_CYCLES; |
|
// l.lhs |
`OR1200_OR32_LHS: |
multicycle = `OR1200_TWO_CYCLES; |
|
// l.sw |
`OR1200_OR32_SW: |
multicycle = `OR1200_TWO_CYCLES; |
|
// l.sb |
`OR1200_OR32_SB: |
multicycle = `OR1200_TWO_CYCLES; |
|
// l.sh |
`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: |
case (id_insn[3:0]) // synopsys parallel_case |
4'h6: multicycle = `OR1200_MULTICYCLE_WIDTH'd3; // l.mul |
4'h9: multicycle = `OR1200_MULTICYCLE_WIDTH'd2; // l.div |
4'hA: multicycle = `OR1200_MULTICYCLE_WIDTH'd2; // l.divu |
4'hB: multicycle = `OR1200_MULTICYCLE_WIDTH'd3; // l.mulu |
default: multicycle = `OR1200_MULTICYCLE_WIDTH'd0; |
endcase |
`OR1200_OR32_MULI: |
multicycle = `OR1200_MULTICYCLE_WIDTH'd3; |
|
// Single cycle instructions |
default: begin |
multicycle = `OR1200_ONE_CYCLE; |
494,12 → 453,36
// |
always @(id_insn) begin |
case (id_insn[31:26]) // synopsys parallel_case |
`OR1200_OR32_ALU: |
wait_on = ( 1'b0 |
`ifdef OR1200_DIV_IMPLEMENTED |
| (id_insn[4:0] == `OR1200_ALUOP_DIV) |
| (id_insn[4:0] == `OR1200_ALUOP_DIVU) |
`endif |
`ifdef OR1200_MULT_IMPLEMENTED |
| (id_insn[4:0] == `OR1200_ALUOP_MUL) |
| (id_insn[4:0] == `OR1200_ALUOP_MULU) |
`endif |
) ? `OR1200_WAIT_ON_MULTMAC : `OR1200_WAIT_ON_NOTHING; |
`ifdef OR1200_MULT_IMPLEMENTED |
`ifdef OR1200_MAC_IMPLEMENTED |
`OR1200_OR32_MACMSB, |
`OR1200_OR32_MACI, |
`endif |
`OR1200_OR32_MULI: |
wait_on = `OR1200_WAIT_ON_MULTMAC; |
`endif |
`ifdef OR1200_MAC_IMPLEMENTED |
`OR1200_OR32_MACRC: |
wait_on = id_insn[16] ? `OR1200_WAIT_ON_MULTMAC : |
`OR1200_WAIT_ON_NOTHING; |
`endif |
`ifdef OR1200_FPU_IMPLEMENTED |
`OR1200_OR32_FLOAT: begin |
wait_on = id_insn[`OR1200_FPUOP_DOUBLE_BIT] ? 0 : `OR1200_WAIT_ON_FPU; |
end |
`endif |
`ifndef OR1200_DC_WRITHROUGH |
`ifndef OR1200_DC_WRITEHROUGH |
// l.mtspr |
`OR1200_OR32_MTSPR: begin |
wait_on = `OR1200_WAIT_ON_MTSPR; |
506,7 → 489,7
end |
`endif |
default: begin |
wait_on = 0; |
wait_on = `OR1200_WAIT_ON_NOTHING; |
end |
endcase // case (id_insn[31:26]) |
end // always @ (id_insn) |
650,7 → 633,7
`OR1200_OR32_SFXX: |
sel_imm <= 1'b0; |
|
`ifdef OR1200_OR32_CUST5 |
`ifdef OR1200_IMPL_ALU_CUST5 |
// l.cust5 instructions |
`OR1200_OR32_CUST5: |
sel_imm <= 1'b0; |
721,7 → 704,7
`OR1200_OR32_SB, |
`OR1200_OR32_SH, |
`OR1200_OR32_SFXX, |
`ifdef OR1200_OR32_CUST5 |
`ifdef OR1200_IMPL_ALU_CUST5 |
`OR1200_OR32_CUST5, |
`endif |
`OR1200_OR32_NOP: |
738,35 → 721,40
`ifdef OR1200_MULT_IMPLEMENTED |
`ifdef OR1200_DIV_IMPLEMENTED |
`else |
| (id_insn[3:0] == `OR1200_ALUOP_DIV) |
| (id_insn[3:0] == `OR1200_ALUOP_DIVU) |
| (id_insn[4:0] == `OR1200_ALUOP_DIV) |
| (id_insn[4:0] == `OR1200_ALUOP_DIVU) |
`endif |
`else |
| (id_insn[3:0] == `OR1200_ALUOP_DIV) |
| (id_insn[3:0] == `OR1200_ALUOP_DIVU) |
| (id_insn[3:0] == `OR1200_ALUOP_MUL) |
| (id_insn[4:0] == `OR1200_ALUOP_DIV) |
| (id_insn[4:0] == `OR1200_ALUOP_DIVU) |
| (id_insn[4:0] == `OR1200_ALUOP_MUL) |
`endif |
|
`ifdef OR1200_IMPL_ADDC |
`else |
| (id_insn[3:0] == `OR1200_ALUOP_ADDC) |
| (id_insn[4:0] == `OR1200_ALUOP_ADDC) |
`endif |
|
`ifdef OR1200_IMPL_ALU_FFL1 |
`else |
| (id_insn[3:0] == `OR1200_ALUOP_FFL1) |
| (id_insn[4:0] == `OR1200_ALUOP_FFL1) |
`endif |
|
`ifdef OR1200_IMPL_ALU_ROTATE |
`else |
| ((id_insn[3:0] == `OR1200_ALUOP_SHROT) & |
(id_insn[7:6] == `OR1200_SHROTOP_ROR)) |
| ((id_insn[4:0] == `OR1200_ALUOP_SHROT) & |
(id_insn[9:6] == `OR1200_SHROTOP_ROR)) |
`endif |
|
`ifdef OR1200_IMPL_SUB |
`else |
| (id_insn[3:0] == `OR1200_ALUOP_SUB) |
| (id_insn[4:0] == `OR1200_ALUOP_SUB) |
`endif |
`ifdef OR1200_IMPL_ALU_EXT |
`else |
| (id_insn[4:0] == `OR1200_ALUOP_EXTHB) |
| (id_insn[4:0] == `OR1200_ALUOP_EXTW) |
`endif |
; |
|
// Illegal and OR1200 unsupported instructions |
829,18 → 817,16
|
// ALU instructions except the one with immediate |
`OR1200_OR32_ALU: |
alu_op <= id_insn[3:0]; |
alu_op <= {1'b0,id_insn[3:0]}; |
|
// SFXX instructions |
`OR1200_OR32_SFXX: |
alu_op <= `OR1200_ALUOP_COMP; |
|
`ifdef OR1200_OR32_CUST5 |
// l.cust5 instructions |
`ifdef OR1200_IMPL_ALU_CUST5 |
// l.cust5 |
`OR1200_OR32_CUST5: |
alu_op <= `OR1200_ALUOP_CUST5; |
`endif |
|
`endif |
// Default |
default: begin |
alu_op <= `OR1200_ALUOP_NOP; |
853,7 → 839,7
|
|
// |
// Decode of alu_op2 (field of bits 9:8) |
// Decode of second ALU operation field [9:6] |
// |
always @(posedge clk or `OR1200_RST_EVENT rst) begin |
if (rst == `OR1200_RST_VALUE) |
865,7 → 851,6
end |
end |
|
|
// |
// Decode of spr_read, spr_write |
// |
940,18 → 925,6
assign mac_op = `OR1200_MACOP_NOP; |
`endif |
|
// |
// Decode of shrot_op |
// |
always @(posedge clk or `OR1200_RST_EVENT rst) begin |
if (rst == `OR1200_RST_VALUE) |
shrot_op <= `OR1200_SHROTOP_NOP; |
else if (!ex_freeze & id_freeze | ex_flushpipe) |
shrot_op <= `OR1200_SHROTOP_NOP; |
else if (!ex_freeze) begin |
shrot_op <= id_insn[`OR1200_SHROTOP_POS]; |
end |
end |
|
// |
// Decode of rfwb_op |
1034,7 → 1007,7
`OR1200_OR32_ALU: |
rfwb_op <= {`OR1200_RFWBOP_ALU, 1'b1}; |
|
`ifdef OR1200_OR32_CUST5 |
`ifdef OR1200_ALU_IMPL_CUST5 |
// l.cust5 instructions |
`OR1200_OR32_CUST5: |
rfwb_op <= {`OR1200_RFWBOP_ALU, 1'b1}; |
/or1200/rtl/verilog/or1200_mult_mac.v
107,6 → 107,7
// Internal wires and regs |
// |
reg [width-1:0] result; |
reg ex_freeze_r; |
`ifdef OR1200_MULT_IMPLEMENTED |
reg [2*width-1:0] mul_prod_r; |
wire alu_op_smul; |
121,7 → 122,7
`endif |
wire [2*width-1:0] mul_prod; |
wire mul_stall; |
|
reg [1:0] mul_stall_count; |
wire [`OR1200_MACOP_WIDTH-1:0] mac_op; |
`ifdef OR1200_MAC_IMPLEMENTED |
reg [`OR1200_MACOP_WIDTH-1:0] mac_op_r1; |
188,6 → 189,13
assign y = (alu_op_sdiv | alu_op_smul) & b[31] ? ~b + 32'b1 : |
alu_op_div | alu_op_mul | (|mac_op) ? b : 32'd0; |
|
// 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) |
ex_freeze_r <= 1'b1; |
else |
ex_freeze_r <= ex_freeze; |
|
// |
// Select result of current ALU operation to be forwarded |
// to next instruction and to WB stage |
287,7 → 295,20
mul_prod_r <= mul_prod[63:0]; |
end |
|
assign mul_stall = 0; |
// |
// Generate stall signal during multiplication |
// |
always @(`OR1200_RST_EVENT rst or posedge clk) |
if (rst == `OR1200_RST_VALUE) |
mul_stall_count <= 0; |
else if (!(|mul_stall_count)) |
mul_stall_count <= {mul_stall_count[0], alu_op_mul & !ex_freeze_r}; |
else |
mul_stall_count <= {mul_stall_count[0],1'b0}; |
|
assign mul_stall = (|mul_stall_count) | |
(!(|mul_stall_count) & alu_op_mul & !ex_freeze_r); |
|
`endif // !`ifdef OR1200_MULT_SERIAL |
|
`else // OR1200_MULT_IMPLEMENTED |
297,15 → 318,7
`endif // OR1200_MULT_IMPLEMENTED |
|
`ifdef OR1200_MAC_IMPLEMENTED |
// Signal to indicate when we should check for new MAC op |
reg ex_freeze_r; |
|
always @(posedge clk or `OR1200_RST_EVENT rst) |
if (rst == `OR1200_RST_VALUE) |
ex_freeze_r <= 1'b1; |
else |
ex_freeze_r <= ex_freeze; |
|
// |
// Propagation of l.mac opcode, only register it for one cycle |
// |
363,6 → 376,7
else |
mac_stall_r <= (|mac_op | (|mac_op_r1) | (|mac_op_r2)) & |
(id_macrc_op | mac_stall_r); |
|
`else // OR1200_MAC_IMPLEMENTED |
assign mac_stall_r = 1'b0; |
assign mac_r = {2*width{1'b0}}; |