Line 31... |
Line 31... |
//
|
//
|
//
|
//
|
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
//
|
//
|
module cpuops(i_clk,i_rst, i_ce, i_valid, i_op, i_a, i_b, o_c, o_f, o_valid,
|
module cpuops(i_clk,i_rst, i_ce, i_valid, i_op, i_a, i_b, o_c, o_f, o_valid,
|
o_illegal);
|
o_illegal, o_busy);
|
parameter IMPLEMENT_MPY = 1;
|
parameter IMPLEMENT_MPY = 1;
|
input i_clk, i_rst, i_ce;
|
input i_clk, i_rst, i_ce;
|
input [3:0] i_op;
|
input [3:0] i_op;
|
input [31:0] i_a, i_b;
|
input [31:0] i_a, i_b;
|
input i_valid;
|
input i_valid;
|
output reg [31:0] o_c;
|
output reg [31:0] o_c;
|
output wire [3:0] o_f;
|
output wire [3:0] o_f;
|
output reg o_valid;
|
output reg o_valid;
|
output wire o_illegal;
|
output wire o_illegal;
|
|
output wire o_busy;
|
|
|
// Rotate-left pre-logic
|
// Rotate-left pre-logic
|
wire [63:0] w_rol_tmp;
|
wire [63:0] w_rol_tmp;
|
assign w_rol_tmp = { i_a, i_a } << i_b[4:0];
|
assign w_rol_tmp = { i_a, i_a } << i_b[4:0];
|
wire [31:0] w_rol_result;
|
wire [31:0] w_rol_result;
|
Line 119... |
Line 120... |
4'b1101: o_c <= w_popc_result; // POPC
|
4'b1101: o_c <= w_popc_result; // POPC
|
4'b1110: o_c <= w_rol_result; // ROL
|
4'b1110: o_c <= w_rol_result; // ROL
|
default: o_c <= i_b; // MOV, LDI
|
default: o_c <= i_b; // MOV, LDI
|
endcase
|
endcase
|
end
|
end
|
|
|
|
assign o_busy = 1'b0;
|
|
|
|
reg r_illegal;
|
|
always @(posedge i_clk)
|
|
r_illegal <= (i_ce)&&((i_op == 4'h3)||(i_op == 4'h4));
|
|
assign o_illegal = r_illegal;
|
end else begin
|
end else begin
|
//
|
//
|
// Multiply pre-logic
|
// Multiply pre-logic
|
//
|
//
|
wire signed_mpy;
|
wire [16:0] w_mpy_a_input, w_mpy_b_input;
|
assign signed_mpy = i_op[0];
|
wire [33:0] w_mpy_result;
|
wire signed [16:0] w_mpy_a_input, w_mpy_b_input;
|
reg [31:0] r_mpy_result;
|
wire signed [33:0] w_mpy_result;
|
assign w_mpy_a_input ={ ((i_a[15])&(i_op[0])), i_a[15:0] };
|
assign w_mpy_a_input ={ ((i_a[15])&&(signed_mpy)), i_a[15:0] };
|
assign w_mpy_b_input ={ ((i_b[15])&(i_op[0])), i_b[15:0] };
|
assign w_mpy_b_input ={ ((i_b[15])&&(signed_mpy)), i_b[15:0] };
|
|
assign w_mpy_result = w_mpy_a_input * w_mpy_b_input;
|
assign w_mpy_result = w_mpy_a_input * w_mpy_b_input;
|
|
always @(posedge i_clk)
|
|
if (i_ce)
|
|
r_mpy_result = w_mpy_result[31:0];
|
|
|
//
|
//
|
// The master ALU case statement
|
// The master ALU case statement
|
//
|
//
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
Line 151... |
Line 160... |
4'b0101:{o_c,c } <= w_lsr_result[32:0]; // LSR
|
4'b0101:{o_c,c } <= w_lsr_result[32:0]; // LSR
|
4'b0110:{c,o_c } <= (|i_b[31:5])? 33'h00 : {1'b0, i_a } << i_b[4:0]; // LSL
|
4'b0110:{c,o_c } <= (|i_b[31:5])? 33'h00 : {1'b0, i_a } << i_b[4:0]; // LSL
|
4'b0111:{o_c,c } <= w_asr_result[32:0]; // ASR
|
4'b0111:{o_c,c } <= w_asr_result[32:0]; // ASR
|
4'b1000: o_c <= { i_b[15: 0], i_a[15:0] }; // LODIHI
|
4'b1000: o_c <= { i_b[15: 0], i_a[15:0] }; // LODIHI
|
4'b1001: o_c <= { i_a[31:16], i_b[15:0] }; // LODILO
|
4'b1001: o_c <= { i_a[31:16], i_b[15:0] }; // LODILO
|
4'b1010:{c,o_c } <= {1'b0,w_mpy_result[31:0]}; // MPYU
|
4'b1010: o_c <= r_mpy_result; // MPYU
|
4'b1011:{c,o_c } <= {1'b0,w_mpy_result[31:0]}; // MPYS
|
4'b1011: o_c <= r_mpy_result; // MPYS
|
4'b1100: o_c <= w_brev_result; // BREV
|
4'b1100: o_c <= w_brev_result; // BREV
|
4'b1101: o_c <= w_popc_result; // POPC
|
4'b1101: o_c <= w_popc_result; // POPC
|
4'b1110: o_c <= w_rol_result; // ROL
|
4'b1110: o_c <= w_rol_result; // ROL
|
default: o_c <= i_b; // MOV, LDI
|
default: o_c <= i_b; // MOV, LDI
|
endcase
|
endcase
|
end
|
end else if (r_busy)
|
end endgenerate
|
o_c <= r_mpy_result;
|
|
|
generate
|
reg r_busy;
|
if (IMPLEMENT_MPY == 0)
|
initial r_busy = 1'b0;
|
begin
|
|
reg r_illegal;
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
r_illegal <= (i_ce)&&((i_op == 4'h3)||(i_op == 4'h4));
|
r_busy <= (~i_rst)&&(i_ce)&&(i_valid)
|
assign o_illegal = r_illegal;
|
&&(i_op[3:1] == 3'h5);
|
end else
|
|
|
assign o_busy = r_busy;
|
|
|
assign o_illegal = 1'b0;
|
assign o_illegal = 1'b0;
|
endgenerate
|
end endgenerate
|
|
|
assign z = (o_c == 32'h0000);
|
assign z = (o_c == 32'h0000);
|
assign n = (o_c[31]);
|
assign n = (o_c[31]);
|
assign v = (set_ovfl)&&(pre_sign != o_c[31]);
|
assign v = (set_ovfl)&&(pre_sign != o_c[31]);
|
|
|
Line 183... |
Line 192... |
initial o_valid = 1'b0;
|
initial o_valid = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
o_valid <= 1'b0;
|
o_valid <= 1'b0;
|
else
|
else
|
o_valid <= (i_ce)&&(i_valid);
|
o_valid <= (i_ce)&&(i_valid)&&(i_op[3:1] != 3'h5)
|
|
||(o_busy);
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|