Line 24... |
Line 24... |
//
|
//
|
// ============================================================================
|
// ============================================================================
|
//
|
//
|
`include "Thor_defines.v"
|
`include "Thor_defines.v"
|
|
|
module Thor_alu(corenum, rst, clk, alu_ld, alu_op, alu_fn, alu_argA, alu_argB, alu_argC, alu_argI, alu_pc, insnsz, o, alu_done, alu_divByZero);
|
module Thor_alu(corenum, rst, clk, alu_ld, alu_abort, alu_op, alu_fn, alu_argA, alu_argB, alu_argC, alu_argI, alu_pc, insnsz, o, alu_done, alu_idle, alu_divByZero);
|
parameter DBW=64;
|
parameter DBW=64;
|
parameter BIG=1;
|
parameter BIG=1;
|
parameter FEATURES = 0;
|
parameter FEATURES = 0;
|
input [63:0] corenum;
|
input [63:0] corenum;
|
input rst;
|
input rst;
|
input clk;
|
input clk;
|
input alu_ld;
|
input alu_ld;
|
|
input alu_abort;
|
input [7:0] alu_op;
|
input [7:0] alu_op;
|
input [5:0] alu_fn;
|
input [5:0] alu_fn;
|
input [DBW-1:0] alu_argA;
|
input [DBW-1:0] alu_argA;
|
input [DBW-1:0] alu_argB;
|
input [DBW-1:0] alu_argB;
|
input [DBW-1:0] alu_argC;
|
input [DBW-1:0] alu_argC;
|
input [DBW-1:0] alu_argI;
|
input [DBW-1:0] alu_argI;
|
input [DBW-1:0] alu_pc;
|
input [DBW-1:0] alu_pc;
|
input [3:0] insnsz;
|
input [3:0] insnsz;
|
output reg [DBW-1:0] o;
|
output reg [DBW-1:0] o;
|
output reg alu_done;
|
output reg alu_done;
|
|
output reg alu_idle;
|
output alu_divByZero;
|
output alu_divByZero;
|
|
|
wire signed [DBW-1:0] alu_argAs = alu_argA;
|
wire signed [DBW-1:0] alu_argAs = alu_argA;
|
wire signed [DBW-1:0] alu_argBs = alu_argB;
|
wire signed [DBW-1:0] alu_argBs = alu_argB;
|
wire signed [DBW-1:0] alu_argIs = alu_argI;
|
wire signed [DBW-1:0] alu_argIs = alu_argI;
|
Line 56... |
Line 58... |
wire [7:0] bcdao,bcdso;
|
wire [7:0] bcdao,bcdso;
|
wire [15:0] bcdmo;
|
wire [15:0] bcdmo;
|
wire [DBW-1:0] bf_out;
|
wire [DBW-1:0] bf_out;
|
wire [DBW-1:0] shfto;
|
wire [DBW-1:0] shfto;
|
wire alu_mult_done,alu_div_done;
|
wire alu_mult_done,alu_div_done;
|
|
wire alu_mult_idle,alu_div_idle;
|
wire [DBW-1:0] p_out;
|
wire [DBW-1:0] p_out;
|
reg [3:0] o1;
|
reg [3:0] o1;
|
|
|
integer n;
|
integer n;
|
|
|
Thor_multiplier #(DBW) umult1
|
Thor_multiplier #(DBW) umult1
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(alu_ld && ((alu_op==`RR && (alu_fn==`MUL || alu_fn==`MULU)) || alu_op==`MULI || alu_op==`MULUI)),
|
.ld(alu_ld && ((alu_op==`RR && (alu_fn==`MUL || alu_fn==`MULU)) || alu_op==`MULI || alu_op==`MULUI)),
|
|
.abort(alu_abort),
|
.sgn((alu_op==`RR && alu_op==`MUL) || alu_op==`MULI),
|
.sgn((alu_op==`RR && alu_op==`MUL) || alu_op==`MULI),
|
.isMuli(alu_op==`MULI || alu_op==`MULUI),
|
.isMuli(alu_op==`MULI || alu_op==`MULUI),
|
.a(alu_argA),
|
.a(alu_argA),
|
.b(alu_argB),
|
.b(alu_argB),
|
.imm(alu_argI),
|
.imm(alu_argI),
|
.o(alu_prod),
|
.o(alu_prod),
|
.done(alu_mult_done)
|
.done(alu_mult_done),
|
|
.idle(alu_mult_idle)
|
);
|
);
|
|
|
Thor_divider #(DBW) udiv1
|
Thor_divider #(DBW) udiv1
|
(
|
(
|
.rst(rst),
|
.rst(rst),
|
.clk(clk),
|
.clk(clk),
|
.ld(alu_ld && ((alu_op==`RR && (alu_fn==`DIV || alu_fn==`DIVU)) || alu_op==`DIVI || alu_op==`DIVUI)),
|
.ld(alu_ld && ((alu_op==`RR && (alu_fn==`DIV || alu_fn==`DIVU || alu_fn==`MOD || alu_fn==`MODU))
|
.sgn((alu_op==`RR && alu_fn==`DIV) || alu_op==`DIVI),
|
|| alu_op==`DIVI || alu_op==`DIVUI || alu_op==`MODI || alu_op==`MODUI)),
|
.isDivi(alu_op==`DIVI || alu_op==`DIVUI),
|
.abort(alu_abort),
|
|
.sgn((alu_op==`RR && (alu_fn==`DIV || alu_fn==`MOD)) || alu_op==`DIVI || alu_op==`MODI),
|
|
.isDivi(alu_op==`DIVI || alu_op==`DIVUI || alu_op==`MODI || alu_op==`MODUI),
|
.a(alu_argA),
|
.a(alu_argA),
|
.b(alu_argB),
|
.b(alu_argB),
|
.imm(alu_argI),
|
.imm(alu_argI),
|
.qo(alu_divq),
|
.qo(alu_divq),
|
.ro(alu_rem),
|
.ro(alu_rem),
|
.dvByZr(alu_divByZero),
|
.dvByZr(alu_divByZero),
|
.done(alu_div_done)
|
.done(alu_div_done),
|
|
.idle(alu_div_idle)
|
);
|
);
|
|
|
Thor_shifter #(DBW) ushft0
|
Thor_shifter #(DBW) ushft0
|
(
|
(
|
.func(alu_fn),
|
.func(alu_fn),
|
Line 197... |
Line 205... |
`_16ADDU: o <= {alu_argA[DBW-5:0],4'b0} + alu_argB;
|
`_16ADDU: o <= {alu_argA[DBW-5:0],4'b0} + alu_argB;
|
`MIN: o <= BIG ? (alu_argA < alu_argB ? alu_argA : alu_argB) : 64'hDEADDEADDEADDEAD;
|
`MIN: o <= BIG ? (alu_argA < alu_argB ? alu_argA : alu_argB) : 64'hDEADDEADDEADDEAD;
|
`MAX: o <= BIG ? (alu_argA < alu_argB ? alu_argB : alu_argA) : 64'hDEADDEADDEADDEAD;
|
`MAX: o <= BIG ? (alu_argA < alu_argB ? alu_argB : alu_argA) : 64'hDEADDEADDEADDEAD;
|
`MUL,`MULU: o <= BIG ? alu_prod[63:0] : 64'hDEADDEADDEADDEAD;
|
`MUL,`MULU: o <= BIG ? alu_prod[63:0] : 64'hDEADDEADDEADDEAD;
|
`DIV,`DIVU: o <= BIG ? alu_divq : 64'hDEADDEADDEADDEAD;
|
`DIV,`DIVU: o <= BIG ? alu_divq : 64'hDEADDEADDEADDEAD;
|
|
`MOD,`MODU: o <= BIG ? alu_rem : 64'hDEADDEADDEADDEAD;
|
default: o <= 64'hDEADDEADDEADDEAD;
|
default: o <= 64'hDEADDEADDEADDEAD;
|
endcase
|
endcase
|
`MULI,`MULUI: o <= BIG ? alu_prod[63:0] : 64'hDEADDEADDEADDEAD;
|
`MULI,`MULUI: o <= BIG ? alu_prod[63:0] : 64'hDEADDEADDEADDEAD;
|
`DIVI,`DIVUI: o <= BIG ? alu_divq : 64'hDEADDEADDEADDEAD;
|
`DIVI,`DIVUI: o <= BIG ? alu_divq : 64'hDEADDEADDEADDEAD;
|
|
`MODI,`MODUI: o <= BIG ? alu_rem : 64'hDEADDEADDEADDEAD;
|
`_2ADDUI: o <= {alu_argA[DBW-2:0],1'b0} + alu_argI;
|
`_2ADDUI: o <= {alu_argA[DBW-2:0],1'b0} + alu_argI;
|
`_4ADDUI: o <= {alu_argA[DBW-3:0],2'b0} + alu_argI;
|
`_4ADDUI: o <= {alu_argA[DBW-3:0],2'b0} + alu_argI;
|
`_8ADDUI: o <= {alu_argA[DBW-4:0],3'b0} + alu_argI;
|
`_8ADDUI: o <= {alu_argA[DBW-4:0],3'b0} + alu_argI;
|
`_16ADDUI: o <= {alu_argA[DBW-5:0],4'b0} + alu_argI;
|
`_16ADDUI: o <= {alu_argA[DBW-5:0],4'b0} + alu_argI;
|
`R:
|
`R:
|
Line 345... |
Line 355... |
8'h10,8'h11,8'h12,8'h13,8'h14,8'h15,8'h16,8'h17,8'h18,8'h19,8'h1A,8'h1B,8'h1C,8'h1D,8'h1E,8'h1f:
|
8'h10,8'h11,8'h12,8'h13,8'h14,8'h15,8'h16,8'h17,8'h18,8'h19,8'h1A,8'h1B,8'h1C,8'h1D,8'h1E,8'h1f:
|
begin
|
begin
|
case(alu_fn)
|
case(alu_fn)
|
2'd0: begin // ICMP
|
2'd0: begin // ICMP
|
o1[0] = alu_argA == alu_argB;
|
o1[0] = alu_argA == alu_argB;
|
o1[1] = alu_argAs < alu_argBs;
|
o1[1] = ($signed(alu_argA) < $signed(alu_argB));
|
o1[2] = alu_argA < alu_argB;
|
o1[2] = alu_argA < alu_argB;
|
o1[3] = 1'b0;
|
o1[3] = 1'b0;
|
o <= {16{o1}};
|
o <= {16{o1}};
|
end
|
end
|
`ifdef FLOATING_POINT
|
`ifdef FLOATING_POINT
|
Line 373... |
Line 383... |
end
|
end
|
// CMPI
|
// CMPI
|
8'h20,8'h21,8'h22,8'h23,8'h24,8'h25,8'h26,8'h27,8'h28,8'h29,8'h2A,8'h2B,8'h2C,8'h2D,8'h2E,8'h2f:
|
8'h20,8'h21,8'h22,8'h23,8'h24,8'h25,8'h26,8'h27,8'h28,8'h29,8'h2A,8'h2B,8'h2C,8'h2D,8'h2E,8'h2f:
|
begin
|
begin
|
o1[0] = alu_argA == alu_argI;
|
o1[0] = alu_argA == alu_argI;
|
o1[1] = alu_argAs < alu_argIs;
|
o1[1] = ($signed(alu_argA) < $signed(alu_argI));
|
o1[2] = alu_argA < alu_argI;
|
o1[2] = alu_argA < alu_argI;
|
o1[3] = 1'b0;
|
o1[3] = 1'b0;
|
o <= {16{o1}};
|
o <= {16{o1}};
|
end
|
end
|
|
`LLA,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`SB,`SC,`SH,`SW,`CAS,`LVB,`LVC,`LVH,`LVW,`STI,
|
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`SB,`SC,`SH,`SW,`CAS,`LVB,`LVC,`LVH,`LVW,`STI,
|
`LWS,`SWS,`RTS2,`STS,`STFND,`STCMP,`PUSH:
|
`LWS,`SWS,`STS,`STFND,`STCMP,`PUSH:
|
begin
|
begin
|
o <= alu_argA + alu_argC + alu_argI;
|
o <= alu_argA + alu_argC + alu_argI;
|
end
|
end
|
`JMPI: o <= {alu_argA << alu_fn[1:0]} + alu_argC + alu_argI;
|
`JMPI: o <= {alu_argA << alu_fn[1:0]} + alu_argC + alu_argI;
|
`LBX,`LBUX,`SBX,
|
`LBX,`LBUX,`SBX,
|
`LCX,`LCUX,`SCX,
|
`LCX,`LCUX,`SCX,
|
`LHX,`LHUX,`SHX,
|
`LHX,`LHUX,`SHX,
|
`LWX,`SWX,
|
`LWX,`SWX,`LLAX,
|
`JMPIX:
|
`JMPIX:
|
case(alu_fn[1:0])
|
case(alu_fn[1:0])
|
2'd0: o <= alu_argA + alu_argC + alu_argB;
|
2'd0: o <= alu_argA + alu_argC + alu_argB;
|
2'd1: o <= alu_argA + alu_argC + {alu_argB,1'b0};
|
2'd1: o <= alu_argA + alu_argC + {alu_argB,1'b0};
|
2'd2: o <= alu_argA + alu_argC + {alu_argB,2'b0};
|
2'd2: o <= alu_argA + alu_argC + {alu_argB,2'b0};
|
Line 434... |
Line 445... |
always @*
|
always @*
|
case(alu_op)
|
case(alu_op)
|
`RR:
|
`RR:
|
case(alu_fn)
|
case(alu_fn)
|
`MUL,`MULU: alu_done <= alu_mult_done;
|
`MUL,`MULU: alu_done <= alu_mult_done;
|
`DIV,`DIVU: alu_done <= alu_div_done;
|
`DIV,`DIVU,`MOD,`MODU: alu_done <= alu_div_done;
|
default: alu_done <= `TRUE;
|
default: alu_done <= `TRUE;
|
endcase
|
endcase
|
`MULI,`MULUI: alu_done <= alu_mult_done;
|
`MULI,`MULUI: alu_done <= alu_mult_done;
|
`DIVI,`DIVUI: alu_done <= alu_div_done;
|
`DIVI,`DIVUI,`MODI,`MODUI: alu_done <= alu_div_done;
|
default: alu_done <= `TRUE;
|
default: alu_done <= `TRUE;
|
endcase
|
endcase
|
|
|
|
// Generate idle signal
|
|
always @*
|
|
case(alu_op)
|
|
`RR:
|
|
case(alu_fn)
|
|
`MUL,`MULU: alu_idle <= alu_mult_idle;
|
|
`DIV,`DIVU,`MOD,`MODU: alu_idle <= alu_div_idle;
|
|
default: alu_idle <= `TRUE;
|
|
endcase
|
|
`MULI,`MULUI: alu_idle <= alu_mult_idle;
|
|
`DIVI,`DIVUI,`MODI,`MODUI: alu_idle <= alu_div_idle;
|
|
default: alu_idle <= `TRUE;
|
|
endcase
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|