Line 53... |
Line 53... |
o_pc, o_gie,
|
o_pc, o_gie,
|
o_dcdR, o_dcdA, o_dcdB, o_I, o_zI,
|
o_dcdR, o_dcdA, o_dcdB, o_I, o_zI,
|
o_cond, o_wF,
|
o_cond, o_wF,
|
o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
|
o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
|
o_wR, o_rA, o_rB,
|
o_wR, o_rA, o_rB,
|
o_early_branch, o_branch_pc,
|
o_early_branch, o_branch_pc, o_ljmp,
|
o_pipe
|
o_pipe
|
);
|
);
|
parameter ADDRESS_WIDTH=24, IMPLEMENT_MPY=1, EARLY_BRANCHING=1,
|
parameter ADDRESS_WIDTH=24, IMPLEMENT_MPY=1, EARLY_BRANCHING=1,
|
IMPLEMENT_DIVIDE=1, IMPLEMENT_FPU=0, AW = ADDRESS_WIDTH;
|
IMPLEMENT_DIVIDE=1, IMPLEMENT_FPU=0, AW = ADDRESS_WIDTH;
|
input i_clk, i_rst, i_ce, i_stalled;
|
input i_clk, i_rst, i_ce, i_stalled;
|
Line 77... |
Line 77... |
output reg [3:0] o_op;
|
output reg [3:0] o_op;
|
output reg o_ALU, o_M, o_DV, o_FP, o_break, o_lock;
|
output reg o_ALU, o_M, o_DV, o_FP, o_break, o_lock;
|
output reg o_wR, o_rA, o_rB;
|
output reg o_wR, o_rA, o_rB;
|
output wire o_early_branch;
|
output wire o_early_branch;
|
output wire [(AW-1):0] o_branch_pc;
|
output wire [(AW-1):0] o_branch_pc;
|
|
output wire o_ljmp;
|
output reg o_pipe;
|
output reg o_pipe;
|
|
|
wire dcdA_stall, dcdB_stall, dcdF_stall;
|
wire dcdA_stall, dcdB_stall, dcdF_stall;
|
wire o_dcd_early_branch;
|
wire o_dcd_early_branch;
|
wire [(AW-1):0] o_dcd_branch_pc;
|
wire [(AW-1):0] o_dcd_branch_pc;
|
Line 94... |
Line 95... |
wire w_dcdA_pc, w_dcdA_cc;
|
wire w_dcdA_pc, w_dcdA_cc;
|
wire w_dcdB_pc, w_dcdB_cc;
|
wire w_dcdB_pc, w_dcdB_cc;
|
wire [3:0] w_cond;
|
wire [3:0] w_cond;
|
wire w_wF, w_dcdM, w_dcdDV, w_dcdFP;
|
wire w_wF, w_dcdM, w_dcdDV, w_dcdFP;
|
wire w_wR, w_rA, w_rB, w_wR_n;
|
wire w_wR, w_rA, w_rB, w_wR_n;
|
|
wire w_ljmp;
|
|
|
|
generate
|
|
if (EARLY_BRANCHING != 0)
|
|
assign w_ljmp = (iword == 32'h7c87c000);
|
|
else
|
|
assign w_ljmp = 1'b0;
|
|
endgenerate
|
|
|
|
|
wire [31:0] iword;
|
wire [31:0] iword;
|
`ifdef OPT_VLIW
|
`ifdef OPT_VLIW
|
reg [16:0] r_nxt_half;
|
reg [16:0] r_nxt_half;
|
Line 328... |
Line 337... |
((iword[21])? iword[20:19] : 2'h0),
|
((iword[21])? iword[20:19] : 2'h0),
|
iword[4:0] };
|
iword[4:0] };
|
`endif
|
`endif
|
end
|
end
|
|
|
|
|
generate
|
generate
|
if (EARLY_BRANCHING!=0)
|
if (EARLY_BRANCHING!=0)
|
begin
|
begin
|
reg r_early_branch;
|
reg r_early_branch, r_ljmp;
|
reg [(AW-1):0] r_branch_pc;
|
reg [(AW-1):0] r_branch_pc;
|
|
|
|
initial r_ljmp = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_ce)
|
if (i_rst)
|
|
r_ljmp <= 1'b0;
|
|
else if ((i_ce)&&(i_pf_valid))
|
|
r_ljmp <= (w_ljmp);
|
|
assign o_ljmp = r_ljmp;
|
|
|
|
always @(posedge i_clk)
|
|
if (i_rst)
|
|
r_early_branch <= 1'b0;
|
|
else if ((i_ce)&&(i_pf_valid))
|
begin
|
begin
|
if ((~iword[31])&&(iword[30:27]==`CPU_PC_REG)&&(w_cond[3]))
|
if (r_ljmp)
|
|
// LOD (PC),PC
|
|
r_early_branch <= 1'b1;
|
|
else if ((~iword[31])&&(iword[30:27]==`CPU_PC_REG)&&(w_cond[3]))
|
begin
|
begin
|
if (w_op[4:1] == 4'hb) // LDI to PC
|
if (w_op[4:1] == 4'hb) // LDI to PC
|
begin // LDI x,PC
|
// LDI x,PC
|
r_early_branch <= 1'b1;
|
r_early_branch <= 1'b1;
|
end else if ((w_op[4:0]==5'h02)&&(~iword[18]))
|
else if ((w_op[4:0]==5'h02)&&(~iword[18]))
|
begin // Add x,PC
|
// Add x,PC
|
r_early_branch <= 1'b1;
|
r_early_branch <= 1'b1;
|
end else begin
|
else begin
|
r_early_branch <= 1'b0;
|
r_early_branch <= 1'b0;
|
end
|
end
|
end else
|
end else
|
r_early_branch <= 1'b0;
|
r_early_branch <= 1'b0;
|
end
|
end else if (i_ce)
|
|
r_early_branch <= 1'b0;
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_ce)
|
if (i_ce)
|
begin
|
begin
|
if (w_op[4:1] == 4'hb) // LDI
|
if (r_ljmp)
|
|
r_branch_pc <= iword[(AW-1):0];
|
|
else if (w_op[4:1] == 4'hb) // LDI
|
r_branch_pc <= {{(AW-23){iword[22]}},iword[22:0]};
|
r_branch_pc <= {{(AW-23){iword[22]}},iword[22:0]};
|
else // Add x,PC
|
else // Add x,PC
|
r_branch_pc <= i_pc
|
r_branch_pc <= i_pc
|
+ {{(AW-18){iword[17]}},iword[16:0]}
|
+ {{(AW-17){iword[17]}},iword[16:0]}
|
+ {{(AW-1){1'b0}},1'b1};
|
+ {{(AW-1){1'b0}},1'b1};
|
end
|
end
|
|
|
assign o_early_branch = r_early_branch;
|
assign o_early_branch = r_early_branch;
|
assign o_branch_pc = r_branch_pc;
|
assign o_branch_pc = r_branch_pc;
|
end else begin
|
end else begin
|
assign o_early_branch = 1'b0;
|
assign o_early_branch = 1'b0;
|
assign o_branch_pc = {(AW){1'b0}};
|
assign o_branch_pc = {(AW){1'b0}};
|
|
assign o_ljmp = 1'b0;
|
end endgenerate
|
end endgenerate
|
|
|
|
|
// To be a pipeable operation there must be ...
|
// To be a pipeable operation there must be ...
|
// 1. Two valid adjacent instructions
|
// 1. Two valid adjacent instructions
|
Line 394... |
Line 421... |
&&((i_instruction[13:0]==r_I[13:0])
|
&&((i_instruction[13:0]==r_I[13:0])
|
||({1'b0, i_instruction[13:0]}==(r_I[13:0]+14'h1)));
|
||({1'b0, i_instruction[13:0]}==(r_I[13:0]+14'h1)));
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
r_valid <= 1'b0;
|
r_valid <= 1'b0;
|
|
else if ((i_ce)&&(o_ljmp))
|
|
r_valid <= 1'b0;
|
else if ((i_ce)&&(i_pf_valid))
|
else if ((i_ce)&&(i_pf_valid))
|
r_valid <= 1'b1;
|
r_valid <= 1'b1;
|
else if (~i_stalled)
|
else if (~i_stalled)
|
r_valid <= 1'b0;
|
r_valid <= 1'b0;
|
|
|