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 71 to Rev 69
    Reverse comparison

Rev 71 → Rev 69

/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_pipe
o_early_branch, o_branch_pc
);
parameter ADDRESS_WIDTH=24, IMPLEMENT_MPY=1, EARLY_BRANCHING=1,
IMPLEMENT_DIVIDE=0, IMPLEMENT_FPU=0, AW=ADDRESS_WIDTH;
77,7 → 77,6
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;
304,17 → 303,4
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/idecode.v
55,8 → 55,7
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_pipe
o_early_branch, o_branch_pc
);
parameter ADDRESS_WIDTH=24, IMPLEMENT_MPY=1, EARLY_BRANCHING=1,
IMPLEMENT_DIVIDE=1, IMPLEMENT_FPU=0, AW = ADDRESS_WIDTH;
79,7 → 78,6
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;
232,17 → 230,24
`endif
 
 
initial o_illegal = 1'b0;
always @(posedge i_clk)
if (i_rst)
o_illegal <= 1'b0;
else if (i_ce)
if (i_ce)
begin
`ifdef OPT_VLIW
o_illegal <= (i_illegal);
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);
`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;
 
257,30 → 262,6
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.
320,6 → 301,10
 
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),
369,37 → 354,6
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/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_busy);
o_illegal);
parameter IMPLEMENT_MPY = 1;
input i_clk, i_rst, i_ce;
input [3:0] i_op;
43,7 → 43,6
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;
122,27 → 121,19
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 [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];
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;
 
 
//
// The master ALU case statement
//
162,26 → 153,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: o_c <= r_mpy_result; // MPYU
4'b1011: o_c <= r_mpy_result; // MPYS
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'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 else if (r_busy)
o_c <= r_mpy_result;
end
end endgenerate
 
reg r_busy;
initial r_busy = 1'b0;
generate
if (IMPLEMENT_MPY == 0)
begin
reg r_illegal;
always @(posedge i_clk)
r_busy <= (~i_rst)&&(i_ce)&&(i_valid)
&&(i_op[3:1] == 3'h5);
 
assign o_busy = r_busy;
 
r_illegal <= (i_ce)&&((i_op == 4'h3)||(i_op == 4'h4));
assign o_illegal = r_illegal;
end else
assign o_illegal = 1'b0;
end endgenerate
endgenerate
 
assign z = (o_c == 32'h0000);
assign n = (o_c[31]);
194,6 → 185,5
if (i_rst)
o_valid <= 1'b0;
else
o_valid <= (i_ce)&&(i_valid)&&(i_op[3:1] != 3'h5)
||(o_busy);
o_valid <= (i_ce)&&(i_valid);
endmodule
/core/pfcache.v
100,7 → 100,7
// anyway.
initial lastpc = 0;
always @(posedge i_clk)
if (((r_v)&&(i_stall_n))||(i_clear_cache)||(i_new_pc))
if ((r_v)||(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)&&(i_stall_n)))
if ((i_rst)||(i_clear_cache)||(i_new_pc)||(r_v))
begin
r_v <= r_v_from_pc;
delay <= 2'h2;
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
end else begin
r_v <= r_v_from_last;
if (o_wb_cyc)
delay <= 2'h2;
else if (delay != 0)
166,8 → 166,7
 
end else if ((~r_v)&&(delay==0)
&&((tagval != lastpc[(AW-1):CW])
||(~vmask[lastpc[(CW-1):PW]]))
&&(~o_illegal))
||(~vmask[lastpc[(CW-1):PW]])))
begin
o_wb_cyc <= 1'b1;
o_wb_stb <= 1'b1;
190,27 → 189,16
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;
illegal_valid <= 0;
end else if ((o_wb_cyc)&&(i_wb_err))
begin
else if ((o_wb_cyc)&&(i_wb_err))
illegal_cache <= lastpc[(AW-1):PW];
illegal_valid <= 1'b1;
end
 
initial o_illegal = 1'b0;
always @(posedge i_clk)
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]);
if (i_stall_n)
o_illegal <= (illegal_cache == lastpc[(AW-1):PW]);
 
endmodule
/core/zipcpu.v
141,16 → 141,7
`else
parameter IMPLEMENT_MPY = 0;
`endif
`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
parameter IMPLEMENT_DIVIDE = 1, IMPLEMENT_FPU = 0,
IMPLEMENT_LOCK=1;
`ifdef OPT_EARLY_BRANCHING
parameter EARLY_BRANCHING = 1;
251,8 → 242,7
wire [3:0] dcdF;
wire dcdR_wr, dcdA_rd, dcdB_rd,
dcdALU, dcdM, dcdDV, dcdFP,
dcdF_wr, dcd_gie, dcd_break, dcd_lock,
dcd_pipe;
dcdF_wr, dcd_gie, dcd_break, dcd_lock;
reg r_dcdvalid;
wire dcdvalid;
wire [(AW-1):0] dcd_pc;
310,7 → 300,7
wire alu_ce, alu_stall;
wire [31:0] alu_result;
wire [3:0] alu_flags;
wire alu_valid, alu_busy;
wire alu_valid;
wire set_cond;
reg alu_wr, alF_wr, alu_gie;
wire alu_illegal_op;
329,6 → 319,7
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;
416,12 → 407,14
// that cannot be pipelined, and the memory is
// already busy
||((opvalid_mem)&&(mem_stalled))
// ||((opvalid_mem)&&(dcdvalid)&&(dcdM)&&(~dcd_pipe))
)
||(dcdvalid)&&(
// Stall if we need to wait for an operand A
// 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
// 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
431,10 → 424,10
// CC register
||(dcdF_stall)
);
assign op_ce = ((dcdvalid)||(dcd_illegal))&&(~op_stall)&&(~clear_pipeline);
assign op_ce = (dcdvalid)&&((~opvalid)||(~op_stall))&&(~clear_pipeline);
`else
assign op_stall = (opvalid)&&(~master_ce);
assign op_ce = ((dcdvalid)||(dcd_illegal));
assign op_ce = (dcdvalid);
`endif
 
//
451,7 → 444,7
// through the ALU. Break instructions are not allowed through
// the ALU.
`ifdef OPT_PIPELINED
assign alu_stall = (((~master_ce)||(mem_rdbusy)||(alu_busy))&&(opvalid_alu)) //Case 1&2
assign alu_stall = (((~master_ce)||(mem_rdbusy))&&(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
458,13 → 451,13
||((opvalid)&&(op_lock)&&(op_lock_stall))
||((opvalid)&&(op_break))
||(div_busy)||(fpu_busy);
assign alu_ce = (master_ce)&&((opvalid_alu)||(op_illegal))
assign alu_ce = (master_ce)&&(opvalid_alu)
&&(~alu_stall)
&&(~clear_pipeline);
`else
assign alu_stall = ((~master_ce)&&(opvalid_alu))
||((opvalid_alu)&&(op_break));
assign alu_ce = (master_ce)&&((opvalid_alu)||(op_illegal))&&(~alu_stall);
assign alu_ce = (master_ce)&&(opvalid_alu)&&(~alu_stall);
`endif
//
 
474,15 → 467,16
//
`ifdef OPT_PIPELINED
assign mem_ce = (master_ce)&&(opvalid_mem)&&(~mem_stalled)
&&(~clear_pipeline);
&&(~clear_pipeline)&&(set_cond);
`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)&&(~mem_stalled);
assign mem_ce = (master_ce)&&(opvalid_mem)
&&(set_cond)&&(~mem_stalled);
`endif
`ifdef OPT_PIPELINED_BUS_ACCESS
assign mem_stalled = (~master_ce)||(alu_busy)||((opvalid_mem)&&(
assign mem_stalled = (~master_ce)||((opvalid_mem)&&(
(mem_pipe_stalled)
||((~op_pipe)&&(mem_busy))
||(div_busy)
591,8 → 585,7
dcdALU, dcdM, dcdDV, dcdFP, dcd_break, dcd_lock,
dcdR_wr,dcdA_rd, dcdB_rd,
dcd_early_branch,
dcd_branch_pc,
dcd_pipe);
dcd_branch_pc);
`else
idecode_deprecated
#(AW, IMPLEMENT_MPY, EARLY_BRANCHING, IMPLEMENT_DIVIDE,
608,11 → 601,12
dcdALU, dcdM, dcdDV, dcdFP, dcd_break, dcd_lock,
dcdR_wr,dcdA_rd, dcdB_rd,
dcd_early_branch,
dcd_branch_pc,
dcd_pipe);
dcd_branch_pc);
`endif
 
`ifdef OPT_PIPELINED_BUS_ACCESS
reg [23:0] r_opI;
reg [4:0] op_B;
reg op_pipe;
 
initial op_pipe = 1'b0;
622,12 → 616,20
// 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 <= dcd_pipe;
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;
`endif
 
//
645,21 → 647,7
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))
671,13 → 659,11
else
r_opA <= w_opA;
`ifdef OPT_PIPELINED
end else
end else if (opvalid)
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)))
// r_opA <= wr_reg_vl;
if ((wr_reg_ce)&&(wr_reg_id == opA_id)&&(opA_rd))
if (((opA_alu)&&(alu_wr))||((opA_mem)&&(mem_valid)))
r_opA <= wr_reg_vl;
`endif
end
700,7 → 686,9
if (op_ce) // &&(dcdvalid))
r_opB <= w_opBnI + dcdI;
`ifdef OPT_PIPELINED
else if ((wr_reg_ce)&&(opB_id == wr_reg_id)&&(opB_rd))
else if ((opvalid)&&(
((opB_alu)&&(alu_wr))
||((opB_mem)&&(mem_valid))))
r_opB <= wr_reg_vl;
`endif
 
839,11 → 827,8
`endif
 
`ifdef OPT_ILLEGAL_INSTRUCTION
initial op_illegal = 1'b0;
always @(posedge i_clk)
if ((i_rst)||(clear_pipeline))
op_illegal <= 1'b0;
else if(op_ce)
if(op_ce)
`ifdef OPT_PIPELINED
op_illegal <=(dcd_illegal)||((dcd_lock)&&(IMPLEMENT_LOCK == 0));
`else
851,18 → 836,32
`endif
`endif
 
// 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
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
 
always @(posedge i_clk)
if (op_ce)
907,8 → 906,29
// define this flag to something other than just plain zero, then
// the stalls will already be in place.
`ifdef OPT_PIPELINED
assign opA = ((wr_reg_ce)&&(wr_reg_id == opA_id)&&(opA_rd))
? wr_reg_vl : r_opA;
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 );
`else
assign opA = r_opA;
`endif
915,8 → 935,7
 
`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;
923,8 → 942,20
`endif
 
`ifdef OPT_PIPELINED
assign opB = ((wr_reg_ce)&&(wr_reg_id == opB_id)&&(opB_rd))
? wr_reg_vl: r_opB;
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 );
`else
assign opB = r_opB;
`endif
940,18 → 971,16
// operand. That'll get wiped in the
// next operation anyway, so don't stall
// here.
((~dcd_zI)&&(dcdB_rd)&&(opR == dcdB)&&(opR_wr)
&&(opR != { op_gie, `CPU_PC_REG } )
&&((opvalid)||(mem_rdbusy)
||(div_busy)||(fpu_busy)))
((opvalid)&&(opR_wr)&&(opR == dcdB)
&&(opR != { op_gie, `CPU_PC_REG} )
&&(~dcd_zI))
// 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 -- captured above
// ||((mem_busy)&&(~mem_we)&&(mem_last_reg==dcdB)&&(~dcd_zI))
);
// will write to opB
||((mem_busy)&&(~mem_we)&&(mem_last_reg==dcdB)));
`else
// No stalls without pipelining, 'cause how can you have a pipeline
// hazard without the pipeline?
969,13 → 998,11
`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_busy);
alu_result, alu_flags, alu_valid, alu_illegal_op);
`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
1027,7 → 1054,7
// alu_reg <= opR;
alu_wr <= (opR_wr)&&(set_cond);
alF_wr <= (opF_wr)&&(set_cond);
end else if (~alu_busy) begin
end else begin
// These are strobe signals, so clear them if not
// set for any particular clock
alu_wr <= (i_halt)&&(i_dbg_we);
1072,9 → 1099,7
reg r_alu_illegal;
initial r_alu_illegal = 0;
always @(posedge i_clk)
if (clear_pipeline)
r_alu_illegal <= 1'b0;
else if ((alu_ce)||(mem_ce))
if ((alu_ce)||(mem_ce))
r_alu_illegal <= op_illegal;
assign alu_illegal = (alu_illegal_op)||(r_alu_illegal);
`endif
1111,7 → 1136,7
`endif
 
`ifdef OPT_PIPELINED_BUS_ACCESS
pipemem #(AW,IMPLEMENT_LOCK) domem(i_clk, i_rst,(mem_ce)&&(set_cond), bus_lock,
pipemem #(AW,IMPLEMENT_LOCK) domem(i_clk, i_rst, mem_ce, bus_lock,
(opn[0]), opB, opA, opR,
mem_busy, mem_pipe_stalled,
mem_valid, bus_err, mem_wreg, mem_result,
1121,7 → 1146,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)&&(set_cond), bus_lock,
memops #(AW,IMPLEMENT_LOCK) domem(i_clk, i_rst, mem_ce, bus_lock,
(opn[0]), opB, opA, opR,
mem_busy,
mem_valid, bus_err, mem_wreg, mem_result,
1165,7 → 1190,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)&&(alu_valid)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
assign wr_reg_ce = (~alu_illegal)&&((alu_wr)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
`else
assign wr_reg_ce = ((alu_wr)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
`endif
1180,10 → 1205,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 = ((mem_valid) ? mem_result
:((div_valid|fpu_valid))
? ((div_valid) ? div_result:fpu_result)
:((dbgv) ? dbg_val : alu_result));
assign wr_reg_vl = (alu_wr)?((dbgv)?dbg_val: alu_result)
:((mem_valid) ? mem_result
:((div_valid) ? div_result
:fpu_result));
always @(posedge i_clk)
if (wr_reg_ce)
regset[wr_reg_id] <= wr_reg_vl;
1193,14 → 1218,8
// 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?
1249,7 → 1268,7
||((~alu_gie)&&(bus_err))
||((~alu_gie)&&(div_valid)&&(div_error))
||((~alu_gie)&&(fpu_valid)&&(fpu_error))
||((~alu_gie)&&(alu_pc_valid)&&(alu_illegal));
||((~alu_gie)&&(alu_valid)&&(alu_illegal));
`else
assign o_break = (((break_en)||(~op_gie))&&(op_break)
&&(~alu_valid)&&(~mem_valid)&&(~mem_busy)
1305,15 → 1324,10
&&(op_break)&&(~break_en))
`ifdef OPT_ILLEGAL_INSTRUCTION
// On an illegal instruction
||((alu_pc_valid)&&(alu_illegal))
||((alu_valid)&&(alu_illegal))
`endif
// 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))
//
||((div_valid)&&(div_error))
||((fpu_valid)&&(fpu_error))
||(bus_err)
// If we write to the CC register
||((wr_reg_ce)&&(~wr_reg_vl[`CPU_GIE_BIT])
1351,7 → 1365,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_pc_valid)&&(alu_illegal)&&(~alu_gie))
else if ((alu_valid)&&(alu_illegal)&&(~alu_gie))
ill_err_i <= 1'b1;
initial ill_err_u = 1'b0;
always @(posedge i_clk)
1366,7 → 1380,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_pc_valid)&&(alu_illegal)&&(alu_gie))
else if ((alu_valid)&&(alu_illegal)&&(gie))
ill_err_u <= 1'b1;
`else
assign ill_err_u = 1'b0;
1600,7 → 1614,7
// later evaluate how well we are doing.
//
//
assign o_op_stall = (master_ce)&&(op_stall);
assign o_op_stall = (master_ce)&&((~opvalid)||(op_stall));
assign o_pf_stall = (master_ce)&&(~pf_valid);
assign o_i_count = (alu_pc_valid)&&(~clear_pipeline);
 
1607,6 → 1621,7
`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,
1620,8 → 1635,8
// ||((opvalid_mem)&&( op_pipe)&&(mem_pipe_stalled)));
// opA[23:20], opA[3:0],
gie, sleep,
wr_reg_ce, wr_reg_vl[4:0]
/*
wr_reg_vl[5:0]
*/
i_rst, master_ce, (new_pc),
((dcd_early_branch)&&(dcdvalid)),
pf_valid, pf_illegal,
1628,7 → 1643,6
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=0,
`else
IMPLEMENT_FPU=1,
`else
IMPLEMENT_FPU=0,
`endif
IMPLEMENT_LOCK=1,
// Derived parameters
510,6 → 510,8
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;
570,17 → 572,18
assign dmac_int = 1'b0;
`endif
 
wire ctri_sel, ctri_stall;
reg ctri_ack;
wire [31:0] ctri_data;
wire ctri_sel;
reg ctri_ack;
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
595,11 → 598,14
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,5 → 267,6
//
//
// `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.