OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /zipcpu/trunk/rtl
    from Rev 69 to Rev 71
    Reverse comparison

Rev 69 → Rev 71

/core/idecode.v
55,7 → 55,8
o_cond, o_wF,
o_op, o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
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,
IMPLEMENT_DIVIDE=1, IMPLEMENT_FPU=0, AW = ADDRESS_WIDTH;
78,6 → 79,7
output reg o_wR, o_rA, o_rB;
output wire o_early_branch;
output wire [(AW-1):0] o_branch_pc;
output reg o_pipe;
 
wire dcdA_stall, dcdB_stall, dcdF_stall;
wire o_dcd_early_branch;
230,24 → 232,17
`endif
 
 
initial o_illegal = 1'b0;
always @(posedge i_clk)
if (i_ce)
if (i_rst)
o_illegal <= 1'b0;
else 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
 
o_illegal <= (i_illegal);
o_illegal <= (i_illegal);
`else
o_illegal <= ((i_illegal) || (i_instruction[31]));
o_gie<= i_gie;
o_pc <= i_pc+{{(AW-1){1'b0}},1'b1};
`endif
 
if ((IMPLEMENT_MPY!=1)&&(w_op[4:1]==4'h5))
o_illegal <= 1'b1;
 
262,6 → 257,30
else if ((IMPLEMENT_FPU==0)&&(w_dcdFP))
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
// instruction? Only the load immediate instruction
// is completely unconditional.
301,10 → 320,6
 
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);
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
r_nxt_half <= { iword[31], iword[13:5],
((iword[21])? iword[20:19] : 2'h0),
354,6 → 369,37
assign o_branch_pc = {(AW){1'b0}};
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] };
 
endmodule
/core/idecode_deprecated.v
52,7 → 52,7
o_I, o_zI, o_cond, o_wF, o_op,
o_ALU, o_M, o_DV, o_FP, o_break, o_lock,
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,
IMPLEMENT_DIVIDE=0, IMPLEMENT_FPU=0, AW=ADDRESS_WIDTH;
77,6 → 77,7
output reg o_wR, o_rA, o_rB;
output wire o_early_branch;
output wire [(AW-1):0] o_branch_pc;
output wire o_pipe;
 
 
assign o_phase = 1'b0;
303,4 → 304,17
assign o_DV = 1'b0;
assign o_FP = 1'b0;
 
always @(posedge i_clk)
if (i_ce)
begin
o_pipe <= (o_valid)&&(i_valid)
&&(o_M)&&(w_op[3:1] == 3'h3)&&(w_op[0]==o_op[0])
&&(i_instruction[19:16] == o_B[3:0])
&&(i_gie == o_gie)
&&((i_instruction[23:21]==o_cond)
||(o_cond == 3'h0))
&&((i_instruction[15:0] == r_I[15:0])
||(i_instruction[15:0] == (r_I[15:0]+16'h1)));
end
 
endmodule
/core/cpuops.v
33,7 → 33,7
///////////////////////////////////////////////////////////////////////////
//
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;
input i_clk, i_rst, i_ce;
input [3:0] i_op;
43,6 → 43,7
output wire [3:0] o_f;
output reg o_valid;
output wire o_illegal;
output wire o_busy;
 
// Rotate-left pre-logic
wire [63:0] w_rol_tmp;
121,19 → 122,27
default: o_c <= i_b; // MOV, LDI
endcase
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
//
// Multiply pre-logic
//
wire signed_mpy;
assign signed_mpy = i_op[0];
wire signed [16:0] w_mpy_a_input, w_mpy_b_input;
wire signed [33:0] w_mpy_result;
assign w_mpy_a_input ={ ((i_a[15])&&(signed_mpy)), i_a[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;
wire [16:0] w_mpy_a_input, w_mpy_b_input;
wire [33:0] w_mpy_result;
reg [31:0] r_mpy_result;
assign w_mpy_a_input ={ ((i_a[15])&(i_op[0])), i_a[15:0] };
assign w_mpy_b_input ={ ((i_b[15])&(i_op[0])), i_b[15:0] };
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
//
153,26 → 162,26
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'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'b1011:{c,o_c } <= {1'b0,w_mpy_result[31:0]}; // MPYS
4'b1010: o_c <= r_mpy_result; // MPYU
4'b1011: o_c <= r_mpy_result; // MPYS
4'b1100: o_c <= w_brev_result; // BREV
4'b1101: o_c <= w_popc_result; // POPC
4'b1110: o_c <= w_rol_result; // ROL
default: o_c <= i_b; // MOV, LDI
endcase
end
end endgenerate
end else if (r_busy)
o_c <= r_mpy_result;
 
generate
if (IMPLEMENT_MPY == 0)
begin
reg r_illegal;
reg r_busy;
initial r_busy = 1'b0;
always @(posedge i_clk)
r_illegal <= (i_ce)&&((i_op == 4'h3)||(i_op == 4'h4));
assign o_illegal = r_illegal;
end else
r_busy <= (~i_rst)&&(i_ce)&&(i_valid)
&&(i_op[3:1] == 3'h5);
 
assign o_busy = r_busy;
 
assign o_illegal = 1'b0;
endgenerate
end endgenerate
 
assign z = (o_c == 32'h0000);
assign n = (o_c[31]);
185,5 → 194,6
if (i_rst)
o_valid <= 1'b0;
else
o_valid <= (i_ce)&&(i_valid);
o_valid <= (i_ce)&&(i_valid)&&(i_op[3:1] != 3'h5)
||(o_busy);
endmodule
/core/pfcache.v
100,7 → 100,7
// anyway.
initial lastpc = 0;
always @(posedge i_clk)
if ((r_v)||(i_clear_cache)||(i_new_pc))
if (((r_v)&&(i_stall_n))||(i_clear_cache)||(i_new_pc))
lastpc <= i_pc;
 
initial lasttag = 0;
120,12 → 120,12
initial delay = 2'h3;
initial r_v = 1'b0;
always @(posedge i_clk)
if ((i_rst)||(i_clear_cache)||(i_new_pc)||(r_v))
if ((i_rst)||(i_clear_cache)||(i_new_pc)||((r_v)&&(i_stall_n)))
begin
r_v <= r_v_from_pc;
delay <= 2'h2;
end else begin
r_v <= r_v_from_last;
end else if (~r_v) begin // Otherwise, r_v was true and we were
r_v <= r_v_from_last; // stalled, hence only if ~r_v
if (o_wb_cyc)
delay <= 2'h2;
else if (delay != 0)
166,7 → 166,8
 
end else if ((~r_v)&&(delay==0)
&&((tagval != lastpc[(AW-1):CW])
||(~vmask[lastpc[(CW-1):PW]])))
||(~vmask[lastpc[(CW-1):PW]]))
&&(~o_illegal))
begin
o_wb_cyc <= 1'b1;
o_wb_stb <= 1'b1;
189,16 → 190,27
else if ((o_wb_cyc)&&(i_wb_ack)&&(rdaddr[(PW-1):0] == {(PW){1'b1}}))
vmask[rdaddr[(CW-1):PW]] <= 1'b1;
 
reg illegal_valid;
initial illegal_cache = 0;
initial illegal_valid = 0;
always @(posedge i_clk)
if ((i_rst)||(i_clear_cache))
begin
illegal_cache <= 0;
else if ((o_wb_cyc)&&(i_wb_err))
illegal_valid <= 0;
end else if ((o_wb_cyc)&&(i_wb_err))
begin
illegal_cache <= lastpc[(AW-1):PW];
illegal_valid <= 1'b1;
end
 
initial o_illegal = 1'b0;
always @(posedge i_clk)
if (i_stall_n)
o_illegal <= (illegal_cache == lastpc[(AW-1):PW]);
if ((i_rst)||(i_clear_cache))
o_illegal <= 1'b0;
else
o_illegal <= (illegal_valid)
&&(tagval == i_pc[(AW-1):CW])
&&(illegal_cache == i_pc[(AW-1):PW]);
 
endmodule
/core/zipcpu.v
141,7 → 141,16
`else
parameter IMPLEMENT_MPY = 0;
`endif
parameter IMPLEMENT_DIVIDE = 1, IMPLEMENT_FPU = 0,
`ifdef OPT_DIVIDE
parameter IMPLEMENT_DIVIDE = 1;
`else
parameter IMPLEMENT_DIVIDE = 0;
`endif
`ifdef OPT_IMPLEMENT_FPU
parameter IMPLEMENT_FPU = 1,
`else
parameter IMPLEMENT_FPU = 0,
`endif
IMPLEMENT_LOCK=1;
`ifdef OPT_EARLY_BRANCHING
parameter EARLY_BRANCHING = 1;
242,7 → 251,8
wire [3:0] dcdF;
wire dcdR_wr, dcdA_rd, dcdB_rd,
dcdALU, dcdM, dcdDV, dcdFP,
dcdF_wr, dcd_gie, dcd_break, dcd_lock;
dcdF_wr, dcd_gie, dcd_break, dcd_lock,
dcd_pipe;
reg r_dcdvalid;
wire dcdvalid;
wire [(AW-1):0] dcd_pc;
300,7 → 310,7
wire alu_ce, alu_stall;
wire [31:0] alu_result;
wire [3:0] alu_flags;
wire alu_valid;
wire alu_valid, alu_busy;
wire set_cond;
reg alu_wr, alF_wr, alu_gie;
wire alu_illegal_op;
319,7 → 329,6
wire mem_busy, mem_rdbusy;
wire [(AW-1):0] mem_addr;
wire [31:0] mem_data, mem_result;
reg [4:0] mem_last_reg; // Last register result to go in
 
wire div_ce, div_error, div_busy, div_valid;
wire [31:0] div_result;
407,14 → 416,12
// that cannot be pipelined, and the memory is
// already busy
||((opvalid_mem)&&(mem_stalled))
// ||((opvalid_mem)&&(dcdvalid)&&(dcdM)&&(~dcd_pipe))
)
||(dcdvalid)&&(
// Stall if we've got a read going with an
// unknown output (known w/in the memory module)
(mem_rdbusy)
// Or if we need to wait for an operand A
// Stall if we need to wait for an operand A
// to be ready to read
||(dcdA_stall)
(dcdA_stall)
// Likewise for B, also includes logic
// regarding immediate offset (register must
// be in register file if we need to add to
424,10 → 431,10
// CC register
||(dcdF_stall)
);
assign op_ce = (dcdvalid)&&((~opvalid)||(~op_stall))&&(~clear_pipeline);
assign op_ce = ((dcdvalid)||(dcd_illegal))&&(~op_stall)&&(~clear_pipeline);
`else
assign op_stall = (opvalid)&&(~master_ce);
assign op_ce = (dcdvalid);
assign op_ce = ((dcdvalid)||(dcd_illegal));
`endif
 
//
444,7 → 451,7
// through the ALU. Break instructions are not allowed through
// the ALU.
`ifdef OPT_PIPELINED
assign alu_stall = (((~master_ce)||(mem_rdbusy))&&(opvalid_alu)) //Case 1&2
assign alu_stall = (((~master_ce)||(mem_rdbusy)||(alu_busy))&&(opvalid_alu)) //Case 1&2
// Old case #3--this isn't an ALU stall though ...
||((opvalid_alu)&&(wr_reg_ce)&&(wr_reg_id[4] == op_gie)
&&(wr_write_cc)) // Case 3
451,13 → 458,13
||((opvalid)&&(op_lock)&&(op_lock_stall))
||((opvalid)&&(op_break))
||(div_busy)||(fpu_busy);
assign alu_ce = (master_ce)&&(opvalid_alu)
assign alu_ce = (master_ce)&&((opvalid_alu)||(op_illegal))
&&(~alu_stall)
&&(~clear_pipeline);
`else
assign alu_stall = ((~master_ce)&&(opvalid_alu))
||((opvalid_alu)&&(op_break));
assign alu_ce = (master_ce)&&(opvalid_alu)&&(~alu_stall);
assign alu_ce = (master_ce)&&((opvalid_alu)||(op_illegal))&&(~alu_stall);
`endif
//
 
467,16 → 474,15
//
`ifdef OPT_PIPELINED
assign mem_ce = (master_ce)&&(opvalid_mem)&&(~mem_stalled)
&&(~clear_pipeline)&&(set_cond);
&&(~clear_pipeline);
`else
// If we aren't pipelined, then no one will be changing what's in the
// pipeline (i.e. clear_pipeline), while our only instruction goes
// through the ... pipeline.
assign mem_ce = (master_ce)&&(opvalid_mem)
&&(set_cond)&&(~mem_stalled);
assign mem_ce = (master_ce)&&(opvalid_mem)&&(~mem_stalled);
`endif
`ifdef OPT_PIPELINED_BUS_ACCESS
assign mem_stalled = (~master_ce)||((opvalid_mem)&&(
assign mem_stalled = (~master_ce)||(alu_busy)||((opvalid_mem)&&(
(mem_pipe_stalled)
||((~op_pipe)&&(mem_busy))
||(div_busy)
585,7 → 591,8
dcdALU, dcdM, dcdDV, dcdFP, dcd_break, dcd_lock,
dcdR_wr,dcdA_rd, dcdB_rd,
dcd_early_branch,
dcd_branch_pc);
dcd_branch_pc,
dcd_pipe);
`else
idecode_deprecated
#(AW, IMPLEMENT_MPY, EARLY_BRANCHING, IMPLEMENT_DIVIDE,
601,12 → 608,11
dcdALU, dcdM, dcdDV, dcdFP, dcd_break, dcd_lock,
dcdR_wr,dcdA_rd, dcdB_rd,
dcd_early_branch,
dcd_branch_pc);
dcd_branch_pc,
dcd_pipe);
`endif
 
`ifdef OPT_PIPELINED_BUS_ACCESS
reg [23:0] r_opI;
reg [4:0] op_B;
reg op_pipe;
 
initial op_pipe = 1'b0;
616,20 → 622,12
// Both must be writes, or both must be reads
// Both operations must be to the same identical address,
// or at least a single (one) increment above that address
//
// However ... we need to know this before this clock, hence this is
// calculated in the instruction decoder.
always @(posedge i_clk)
if (op_ce)
op_pipe <= (dcdvalid)&&(opvalid_mem)&&(dcdM) // Both mem
&&(dcdOp[0]==opn[0]) // Both Rd, or both Wr
&&(dcdB == op_B) // Same address register
&&((dcdF[2:0] == opF_cp) // Same condition
||(opF_cp == 3'h0)) // or no prev condition
&&((dcdI[23:0] == r_opI)||(dcdI[23:0]==r_opI+24'h1));
always @(posedge i_clk)
if (op_ce) // &&(dcdvalid))
r_opI <= dcdI[23:0];
always @(posedge i_clk)
if (op_ce) // &&(dcdvalid))
op_B <= dcdB;
op_pipe <= dcd_pipe;
`endif
 
//
647,7 → 645,21
else
assign w_pcA_v = (dcdA[4] == dcd_gie)?dcd_pc:upc;
endgenerate
 
`ifdef OPT_PIPELINED
reg [4:0] opA_id, opB_id;
reg opA_rd, opB_rd;
always @(posedge i_clk)
if (op_ce)
begin
opA_id <= dcdA;
opB_id <= dcdB;
opA_rd <= dcdA_rd;
opB_rd <= dcdB_rd;
end
`endif
 
always @(posedge i_clk)
if (op_ce) // &&(dcdvalid))
begin
if ((wr_reg_ce)&&(wr_reg_id == dcdA))
659,11 → 671,13
else
r_opA <= w_opA;
`ifdef OPT_PIPELINED
end else if (opvalid)
end else
begin // We were going to pick these up when they became valid,
// but for some reason we're stuck here as they became
// valid. Pick them up now anyway
if (((opA_alu)&&(alu_wr))||((opA_mem)&&(mem_valid)))
// if (((opA_alu)&&(alu_wr))||((opA_mem)&&(mem_valid)))
// r_opA <= wr_reg_vl;
if ((wr_reg_ce)&&(wr_reg_id == opA_id)&&(opA_rd))
r_opA <= wr_reg_vl;
`endif
end
686,9 → 700,7
if (op_ce) // &&(dcdvalid))
r_opB <= w_opBnI + dcdI;
`ifdef OPT_PIPELINED
else if ((opvalid)&&(
((opB_alu)&&(alu_wr))
||((opB_mem)&&(mem_valid))))
else if ((wr_reg_ce)&&(opB_id == wr_reg_id)&&(opB_rd))
r_opB <= wr_reg_vl;
`endif
 
827,8 → 839,11
`endif
 
`ifdef OPT_ILLEGAL_INSTRUCTION
initial op_illegal = 1'b0;
always @(posedge i_clk)
if(op_ce)
if ((i_rst)||(clear_pipeline))
op_illegal <= 1'b0;
else if(op_ce)
`ifdef OPT_PIPELINED
op_illegal <=(dcd_illegal)||((dcd_lock)&&(IMPLEMENT_LOCK == 0));
`else
836,32 → 851,18
`endif
`endif
 
generate
if (EARLY_BRANCHING > 0)
begin
always @(posedge i_clk)
if (op_ce)
begin
opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr))&&(~dcd_early_branch);
opR_wr <= (dcdR_wr)&&(~dcd_early_branch);
op_wr_pc <= ((dcdR_wr)&&(dcdR_pc)
&&(dcdR[4] == dcd_gie))
&&(~dcd_early_branch);
end
end else begin
always @(posedge i_clk)
if (op_ce)
begin
// Will we write the flags/CC Register with
// our result?
opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr));
// Will we be writing our results into a
// register?
opR_wr <= dcdR_wr;
op_wr_pc <= ((dcdR_wr)&&(dcdR_pc)
&&(dcdR[4] == dcd_gie));
end
end endgenerate
// No generate on EARLY_BRANCHING here, since if EARLY_BRANCHING is not
// set, dcd_early_branch will simply be a wire connected to zero and
// this logic should just optimize.
always @(posedge i_clk)
if (op_ce)
begin
opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr))&&(~dcd_early_branch);
opR_wr <= (dcdR_wr)&&(~dcd_early_branch);
op_wr_pc <= ((dcdR_wr)&&(dcdR_pc)
&&(dcdR[4] == dcd_gie))
&&(~dcd_early_branch);
end
 
always @(posedge i_clk)
if (op_ce)
906,29 → 907,8
// define this flag to something other than just plain zero, then
// the stalls will already be in place.
`ifdef OPT_PIPELINED
initial opA_alu = 1'b0;
always @(posedge i_clk)
if (op_ce)
opA_alu <= (opvalid_alu)&&(opR == dcdA)&&(opR_wr)&&(dcdA_rd);
else if ((opvalid)&&(opA_alu)&&(alu_valid))
opA_alu <= 1'b0;
initial opA_mem = 1'b0;
always @(posedge i_clk)
if (op_ce)
opA_mem <= ((opvalid_mem)&&(opR == dcdA)&&(dcdA_rd)&&(~opn[0]))
||((~opvalid)&&(mem_busy)&&(~mem_we)
&&(mem_last_reg == dcdA)&&(dcdA_rd));
else if ((opvalid)&&(opA_mem)&&(mem_valid))
opA_mem <= 1'b0;
`endif
 
always @(posedge i_clk)
if (mem_ce)
mem_last_reg <= opR;
`ifdef OPT_PIPELINED
assign opA = ((opA_alu)&&(alu_wr)) ? alu_result
: ( ((opA_mem)&&(mem_valid))?mem_result
: r_opA );
assign opA = ((wr_reg_ce)&&(wr_reg_id == opA_id)&&(opA_rd))
? wr_reg_vl : r_opA;
`else
assign opA = r_opA;
`endif
935,7 → 915,8
 
`ifdef OPT_PIPELINED
assign dcdA_stall = (dcdvalid)&&(dcdA_rd)&&(
((opvalid_alu)&&(opF_wr)&&(dcdA_cc)));
((opvalid_alu)&&(opF_wr)&&(dcdA_cc))
);
`else
// There are no pipeline hazards, if we aren't pipelined
assign dcdA_stall = 1'b0;
942,20 → 923,8
`endif
 
`ifdef OPT_PIPELINED
always @(posedge i_clk)
if (op_ce)
opB_alu <= (opvalid_alu)&&(opR == dcdB)&&(opR_wr)&&(dcdB_rd)&&(dcd_zI);
always @(posedge i_clk)
if (op_ce)
opB_mem <= (dcd_zI)&&(dcdB_rd)&&(
((opvalid_mem)&&(opR == dcdB)&&(~opn[0]))
||((~opvalid)&&(mem_busy)&&(~mem_we)
&&(mem_last_reg == dcdB)));
else if ((opvalid)&&(opB_mem)&&(mem_valid))
opB_mem <= 1'b0;
assign opB = ((opB_alu)&&(alu_wr)) ? alu_result
: ( ((opB_mem)&&(mem_valid))?mem_result
: r_opB );
assign opB = ((wr_reg_ce)&&(wr_reg_id == opB_id)&&(opB_rd))
? wr_reg_vl: r_opB;
`else
assign opB = r_opB;
`endif
971,16 → 940,18
// operand. That'll get wiped in the
// next operation anyway, so don't stall
// here.
((opvalid)&&(opR_wr)&&(opR == dcdB)
&&(opR != { op_gie, `CPU_PC_REG} )
&&(~dcd_zI))
((~dcd_zI)&&(dcdB_rd)&&(opR == dcdB)&&(opR_wr)
&&(opR != { op_gie, `CPU_PC_REG } )
&&((opvalid)||(mem_rdbusy)
||(div_busy)||(fpu_busy)))
// Stall on any write to the flags register,
// if we're going to need the flags value for
// opB.
||((opvalid_alu)&&(opF_wr)&&(dcdB_cc))
// Stall on any ongoing memory operation that
// will write to opB
||((mem_busy)&&(~mem_we)&&(mem_last_reg==dcdB)));
// will write to opB -- captured above
// ||((mem_busy)&&(~mem_we)&&(mem_last_reg==dcdB)&&(~dcd_zI))
);
`else
// No stalls without pipelining, 'cause how can you have a pipeline
// hazard without the pipeline?
998,11 → 969,13
`ifdef OPT_NEW_INSTRUCTION_SET
cpuops #(IMPLEMENT_MPY) doalu(i_clk, i_rst, alu_ce,
(opvalid_alu), opn, opA, opB,
alu_result, alu_flags, alu_valid, alu_illegal_op);
alu_result, alu_flags, alu_valid, alu_illegal_op,
alu_busy);
`else
cpuops_deprecated #(IMPLEMENT_MPY) doalu(i_clk, i_rst, alu_ce,
(opvalid_alu), opn, opA, opB,
alu_result, alu_flags, alu_valid, alu_illegal_op);
assign alu_busy = 1'b0;
`endif
 
generate
1054,7 → 1027,7
// alu_reg <= opR;
alu_wr <= (opR_wr)&&(set_cond);
alF_wr <= (opF_wr)&&(set_cond);
end else begin
end else if (~alu_busy) begin
// These are strobe signals, so clear them if not
// set for any particular clock
alu_wr <= (i_halt)&&(i_dbg_we);
1099,7 → 1072,9
reg r_alu_illegal;
initial r_alu_illegal = 0;
always @(posedge i_clk)
if ((alu_ce)||(mem_ce))
if (clear_pipeline)
r_alu_illegal <= 1'b0;
else if ((alu_ce)||(mem_ce))
r_alu_illegal <= op_illegal;
assign alu_illegal = (alu_illegal_op)||(r_alu_illegal);
`endif
1136,7 → 1111,7
`endif
 
`ifdef OPT_PIPELINED_BUS_ACCESS
pipemem #(AW,IMPLEMENT_LOCK) domem(i_clk, i_rst, mem_ce, bus_lock,
pipemem #(AW,IMPLEMENT_LOCK) domem(i_clk, i_rst,(mem_ce)&&(set_cond), bus_lock,
(opn[0]), opB, opA, opR,
mem_busy, mem_pipe_stalled,
mem_valid, bus_err, mem_wreg, mem_result,
1146,7 → 1121,7
mem_ack, mem_stall, mem_err, i_wb_data);
`else // PIPELINED_BUS_ACCESS
memops #(AW,IMPLEMENT_LOCK) domem(i_clk, i_rst, mem_ce, bus_lock,
memops #(AW,IMPLEMENT_LOCK) domem(i_clk, i_rst,(mem_ce)&&(set_cond), bus_lock,
(opn[0]), opB, opA, opR,
mem_busy,
mem_valid, bus_err, mem_wreg, mem_result,
1190,7 → 1165,7
// Further, alu_wr includes (set_cond), so we don't need to
// check for that here either.
`ifdef OPT_ILLEGAL_INSTRUCTION
assign wr_reg_ce = (~alu_illegal)&&((alu_wr)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
assign wr_reg_ce = (~alu_illegal)&&((alu_wr)&&(alu_valid)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
`else
assign wr_reg_ce = ((alu_wr)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
`endif
1205,10 → 1180,10
// Are we writing to the PC?
assign wr_write_pc = (wr_reg_id[3:0] == `CPU_PC_REG);
// What value to write?
assign wr_reg_vl = (alu_wr)?((dbgv)?dbg_val: alu_result)
:((mem_valid) ? mem_result
:((div_valid) ? div_result
:fpu_result));
assign wr_reg_vl = ((mem_valid) ? mem_result
:((div_valid|fpu_valid))
? ((div_valid) ? div_result:fpu_result)
:((dbgv) ? dbg_val : alu_result));
always @(posedge i_clk)
if (wr_reg_ce)
regset[wr_reg_id] <= wr_reg_vl;
1218,8 → 1193,14
// When shall we write to our flags register? alF_wr already
// includes the set condition ...
assign wr_flags_ce = ((alF_wr)||(div_valid)||(fpu_valid))&&(~clear_pipeline)&&(~alu_illegal);
assign w_uflags = { ufpu_err_flag, udiv_err_flag, ubus_err_flag, trap, ill_err_u, 1'b0, step, 1'b1, sleep, ((wr_flags_ce)&&(alu_gie))?alu_flags:flags };
assign w_iflags = { ifpu_err_flag, idiv_err_flag, ibus_err_flag, trap, ill_err_i,break_en, 1'b0, 1'b0, sleep, ((wr_flags_ce)&&(~alu_gie))?alu_flags:iflags };
assign w_uflags = { ufpu_err_flag,
udiv_err_flag, ubus_err_flag, trap, ill_err_u,
1'b0, step, 1'b1, sleep,
((wr_flags_ce)&&(alu_gie))?alu_flags:flags };
assign w_iflags = { ifpu_err_flag,
idiv_err_flag, ibus_err_flag, trap, ill_err_i,
break_en, 1'b0, 1'b0, sleep,
((wr_flags_ce)&&(~alu_gie))?alu_flags:iflags };
 
 
// What value to write?
1268,7 → 1249,7
||((~alu_gie)&&(bus_err))
||((~alu_gie)&&(div_valid)&&(div_error))
||((~alu_gie)&&(fpu_valid)&&(fpu_error))
||((~alu_gie)&&(alu_valid)&&(alu_illegal));
||((~alu_gie)&&(alu_pc_valid)&&(alu_illegal));
`else
assign o_break = (((break_en)||(~op_gie))&&(op_break)
&&(~alu_valid)&&(~mem_valid)&&(~mem_busy)
1324,10 → 1305,15
&&(op_break)&&(~break_en))
`ifdef OPT_ILLEGAL_INSTRUCTION
// On an illegal instruction
||((alu_valid)&&(alu_illegal))
||((alu_pc_valid)&&(alu_illegal))
`endif
||((div_valid)&&(div_error))
||((fpu_valid)&&(fpu_error))
// On division by zero. If the divide isn't
// implemented, div_valid and div_error will be short
// circuited and that logic will be bypassed
||((div_valid)&&(div_error))
// Same thing on a floating point error.
||((fpu_valid)&&(fpu_error))
//
||(bus_err)
// If we write to the CC register
||((wr_reg_ce)&&(~wr_reg_vl[`CPU_GIE_BIT])
1365,7 → 1351,7
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
&&(~wr_reg_vl[`CPU_ILL_BIT]))
ill_err_i <= 1'b0;
else if ((alu_valid)&&(alu_illegal)&&(~alu_gie))
else if ((alu_pc_valid)&&(alu_illegal)&&(~alu_gie))
ill_err_i <= 1'b1;
initial ill_err_u = 1'b0;
always @(posedge i_clk)
1380,7 → 1366,7
&&(wr_reg_ce)&&(~wr_reg_vl[`CPU_ILL_BIT])
&&(wr_reg_id[4])&&(wr_write_cc))
ill_err_u <= 1'b0;
else if ((alu_valid)&&(alu_illegal)&&(gie))
else if ((alu_pc_valid)&&(alu_illegal)&&(alu_gie))
ill_err_u <= 1'b1;
`else
assign ill_err_u = 1'b0;
1614,7 → 1600,7
// later evaluate how well we are doing.
//
//
assign o_op_stall = (master_ce)&&((~opvalid)||(op_stall));
assign o_op_stall = (master_ce)&&(op_stall);
assign o_pf_stall = (master_ce)&&(~pf_valid);
assign o_i_count = (alu_pc_valid)&&(~clear_pipeline);
 
1621,7 → 1607,6
`ifdef DEBUG_SCOPE
always @(posedge i_clk)
o_debug <= {
/*
pf_pc[3:0], flags,
pf_valid, dcdvalid, opvalid, alu_valid, mem_valid,
op_ce, alu_ce, mem_ce,
1635,8 → 1620,8
// ||((opvalid_mem)&&( op_pipe)&&(mem_pipe_stalled)));
// opA[23:20], opA[3:0],
gie, sleep,
wr_reg_vl[5:0]
*/
wr_reg_ce, wr_reg_vl[4:0]
/*
i_rst, master_ce, (new_pc),
((dcd_early_branch)&&(dcdvalid)),
pf_valid, pf_illegal,
1643,6 → 1628,7
op_ce, dcd_ce, dcdvalid, dcd_stalled,
pf_cyc, pf_stb, pf_we, pf_ack, pf_stall, pf_err,
pf_pc[7:0], pf_addr[7:0]
*/
};
`endif
/zipsystem.v
183,9 → 183,9
IMPLEMENT_DIVIDE=0,
`endif
`ifdef OPT_IMPLEMENT_FPU
IMPLEMENT_FPU=1,
`else
IMPLEMENT_FPU=0,
`else
IMPLEMENT_FPU=1,
`endif
IMPLEMENT_LOCK=1,
// Derived parameters
510,8 → 510,6
assign actr_stall = 1'b0;
assign actr_data = 32'h0000;
 
wire utc_int, uoc_int, upc_int, uic_int;
wire mtc_int, moc_int, mpc_int, mic_int;
assign mtc_int = 1'b0;
assign moc_int = 1'b0;
assign mpc_int = 1'b0;
572,18 → 570,17
assign dmac_int = 1'b0;
`endif
 
wire ctri_sel;
reg ctri_ack;
wire ctri_sel, ctri_stall;
reg ctri_ack;
wire [31:0] ctri_data;
assign ctri_sel = (sys_cyc)&&(sys_stb)&&(sys_addr == `CTRINT);
always @(posedge i_clk)
ctri_ack <= ctri_sel;
assign ctri_stall = 1'b0;
`ifdef INCLUDE_ACCOUNTING_COUNTERS
//
// Counter Interrupt controller
//
wire ctri_stall;
wire [31:0] ctri_data;
 
generate
if (EXTERNAL_INTERRUPTS <= 9)
begin
598,14 → 595,11
ctri_int);
end endgenerate
 
assign ctri_stall = 1'b0;
`else // INCLUDE_ACCOUNTING_COUNTERS
 
generate
if (EXTERNAL_INTERRUPTS <= 9)
begin
wire ctri_stall, ctri_int;
wire [31:0] ctri_data;
assign ctri_stall = 1'b0;
assign ctri_data = 32'h0000;
assign ctri_int = 1'b0;
/cpudefs.v
267,6 → 267,5
//
//
// `define DEBUG_SCOPE
`define NEW_PREFETCH_VERSION
//
`endif // CPUDEFS_H

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.