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_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;
|
input [31:0] i_instruction;
|
input [31:0] i_instruction;
|
Line 76... |
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 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;
|
reg o_dcdI, o_dcdIz;
|
reg o_dcdI, o_dcdIz;
|
Line 228... |
Line 230... |
`else
|
`else
|
assign o_phase = 1'b0;
|
assign o_phase = 1'b0;
|
`endif
|
`endif
|
|
|
|
|
|
initial o_illegal = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_ce)
|
if (i_rst)
|
|
o_illegal <= 1'b0;
|
|
else if (i_ce)
|
begin
|
begin
|
`ifdef OPT_VLIW
|
`ifdef OPT_VLIW
|
if (~o_phase)
|
|
begin
|
|
o_gie<= i_gie;
|
|
// i.e. dcd_pc+1
|
|
o_pc <= i_pc+{{(AW-1){1'b0}},1'b1};
|
|
end
|
|
|
|
o_illegal <= (i_illegal);
|
o_illegal <= (i_illegal);
|
`else
|
`else
|
o_illegal <= ((i_illegal) || (i_instruction[31]));
|
o_illegal <= ((i_illegal) || (i_instruction[31]));
|
o_gie<= i_gie;
|
|
o_pc <= i_pc+{{(AW-1){1'b0}},1'b1};
|
|
`endif
|
`endif
|
|
|
if ((IMPLEMENT_MPY!=1)&&(w_op[4:1]==4'h5))
|
if ((IMPLEMENT_MPY!=1)&&(w_op[4:1]==4'h5))
|
o_illegal <= 1'b1;
|
o_illegal <= 1'b1;
|
|
|
if ((IMPLEMENT_DIVIDE==0)&&(w_dcdDV))
|
if ((IMPLEMENT_DIVIDE==0)&&(w_dcdDV))
|
o_illegal <= 1'b1;
|
o_illegal <= 1'b1;
|
Line 260... |
Line 255... |
if ((IMPLEMENT_FPU!=0)&&(w_dcdFP)&&(w_dcdR[3:1]==3'h7))
|
if ((IMPLEMENT_FPU!=0)&&(w_dcdFP)&&(w_dcdR[3:1]==3'h7))
|
o_illegal <= 1'b1;
|
o_illegal <= 1'b1;
|
else if ((IMPLEMENT_FPU==0)&&(w_dcdFP))
|
else if ((IMPLEMENT_FPU==0)&&(w_dcdFP))
|
o_illegal <= 1'b1;
|
o_illegal <= 1'b1;
|
|
|
|
if ((w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)
|
|
&&(
|
|
(w_op[2:0] != 3'h2) // LOCK
|
|
&&(w_op[2:0] != 3'h1) // BREAK
|
|
&&(w_op[2:0] != 3'h0))) // NOOP
|
|
o_illegal <= 1'b1;
|
|
end
|
|
|
|
|
|
always @(posedge i_clk)
|
|
if (i_ce)
|
|
begin
|
|
`ifdef OPT_VLIW
|
|
if (~o_phase)
|
|
begin
|
|
o_gie<= i_gie;
|
|
// i.e. dcd_pc+1
|
|
o_pc <= i_pc+{{(AW-1){1'b0}},1'b1};
|
|
end
|
|
`else
|
|
o_gie<= i_gie;
|
|
o_pc <= i_pc+{{(AW-1){1'b0}},1'b1};
|
|
`endif
|
|
|
// Under what condition will we execute this
|
// Under what condition will we execute this
|
// instruction? Only the load immediate instruction
|
// instruction? Only the load immediate instruction
|
// is completely unconditional.
|
// is completely unconditional.
|
o_cond <= w_cond;
|
o_cond <= w_cond;
|
// Don't change the flags on conditional instructions,
|
// Don't change the flags on conditional instructions,
|
Line 299... |
Line 318... |
o_DV <= w_dcdDV;
|
o_DV <= w_dcdDV;
|
o_FP <= w_dcdFP;
|
o_FP <= w_dcdFP;
|
|
|
o_break <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b001);
|
o_break <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b001);
|
o_lock <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b010);
|
o_lock <= (w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)&&(w_op[2:0]==3'b010);
|
if ((w_op[4:3]==2'b11)&&(w_dcdR[3:1]==3'h7)
|
|
&&((w_op[2])||(w_op[1:0]==2'b11)))
|
|
o_illegal <= 1'b1;
|
|
|
|
`ifdef OPT_VLIW
|
`ifdef OPT_VLIW
|
r_nxt_half <= { iword[31], iword[13:5],
|
r_nxt_half <= { iword[31], iword[13:5],
|
((iword[21])? iword[20:19] : 2'h0),
|
((iword[21])? iword[20:19] : 2'h0),
|
iword[4:0] };
|
iword[4:0] };
|
`endif
|
`endif
|
Line 352... |
Line 367... |
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}};
|
end endgenerate
|
end endgenerate
|
|
|
|
|
|
// To be a pipeable operation there must be ...
|
|
// 1. Two valid adjacent instructions
|
|
// 2. Both must be memory operations, of the same time (both lods
|
|
// or both stos)
|
|
// 3. Both must use the same register base address
|
|
// 4. Both must be to the same address, or the address incremented
|
|
// by one
|
|
// Note that we're not using iword here ... there's a lot of logic
|
|
// taking place, and it's only valid if the new word is not compressed.
|
|
//
|
|
reg r_valid;
|
|
always @(posedge i_clk)
|
|
if (i_ce)
|
|
o_pipe <= (r_valid)&&(i_pf_valid)&&(~i_instruction[31])
|
|
&&(w_dcdM)&&(o_M)&&(o_op[0] ==i_instruction[22])
|
|
&&(i_instruction[17:14] == o_dcdB[3:0])
|
|
&&(i_gie == o_gie)
|
|
&&((i_instruction[21:19]==o_cond[2:0])
|
|
||(o_cond[2:0] == 3'h0))
|
|
&&((i_instruction[13:0]==r_I[13:0])
|
|
||({1'b0, i_instruction[13:0]}==(r_I[13:0]+14'h1)));
|
|
always @(posedge i_clk)
|
|
if (i_rst)
|
|
r_valid <= 1'b0;
|
|
else if ((i_ce)&&(i_pf_valid))
|
|
r_valid <= 1'b1;
|
|
else if (~i_stalled)
|
|
r_valid <= 1'b0;
|
|
|
|
|
assign o_I = { {(32-22){r_I[22]}}, r_I[21:0] };
|
assign o_I = { {(32-22){r_I[22]}}, r_I[21:0] };
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|