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 83 to Rev 82
    Reverse comparison

Rev 83 → Rev 82

/core/zipcpu.v
203,7 → 203,7
// Condition codes
// (BUS, TRAP,ILL,BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z
reg [3:0] flags, iflags;
wire [13:0] w_uflags, w_iflags;
wire [12:0] w_uflags, w_iflags;
reg trap, break_en, step, gie, sleep;
`ifdef OPT_ILLEGAL_INSTRUCTION
reg ill_err_u, ill_err_i;
242,7 → 242,7
// Variable declarations
//
//
reg opvalid, opvalid_mem, opvalid_alu;
reg opvalid, opvalid_mem, opvalid_alu, op_wr_pc;
reg opvalid_div, opvalid_fpu;
wire op_stall, dcd_ce, dcd_phase;
wire [3:0] dcdOp;
281,9 → 281,10
wire [31:0] w_opA, w_opB;
wire [31:0] opA_nowait, opB_nowait, opA, opB;
reg opR_wr, opR_cc, opF_wr, op_gie;
wire [13:0] opFl;
wire [12:0] opFl;
reg [5:0] r_opF;
wire [7:0] opF;
reg [2:0] opF_cp;
wire op_ce, op_phase;
// Some pipeline control wires
`ifdef OPT_PIPELINED
403,14 → 404,19
// stepping. This also includes our stalls for
// op_break and op_lock, so we don't need to
// include those as well here.
// This also includes whether or not the divide or
// floating point units are busy.
(alu_stall)
((opvalid)&&(alu_stall))
// Stall if the divide is busy, since we can't have
// two parallel stages writing back at the same time
||(div_busy)
// Same for the floating point unit
||(fpu_busy)
//
// ||((opvalid_alu)&&(mem_rdbusy)) // part of alu_stall
// Stall if we are going into memory with an operation
// that cannot be pipelined, and the memory is
// already busy
||(mem_stalled) // &&(opvalid_mem) part of mem_stalled
||((opvalid_mem)&&(mem_stalled))
// ||((opvalid_mem)&&(dcdvalid)&&(dcdM)&&(~dcd_pipe))
)
||(dcdvalid)&&(
// Stall if we need to wait for an operand A
661,7 → 667,7
else if (dcdA_pc)
r_opA <= w_pcA_v;
else if (dcdA_cc)
r_opA <= { w_opA[31:14], (dcdA[4])?w_uflags:w_iflags };
r_opA <= { w_opA[31:13], (dcdA[4])?w_uflags:w_iflags };
else
r_opA <= w_opA;
`ifdef OPT_PIPELINED
687,7 → 693,7
assign w_opBnI = (~dcdB_rd) ? 32'h00
: (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_reg_vl
: ((dcdB_pc) ? w_pcB_v
: ((dcdB_cc) ? { w_opB[31:14], (dcdB[4])?w_uflags:w_iflags}
: ((dcdB_cc) ? { w_opB[31:13], (dcdB[4])?w_uflags:w_iflags}
: w_opB)));
 
always @(posedge i_clk)
734,6 → 740,9
endcase
end // Bit order is { (flags_not_used), VNCZ mask, VNCZ value }
assign opF = { r_opF[3], r_opF[5], r_opF[1], r_opF[4:0] };
always @(posedge i_clk)
if (op_ce)
opF_cp[2:0] <= dcdF[2:0];
 
wire w_opvalid;
assign w_opvalid = (~clear_pipeline)&&(dcdvalid);
848,9 → 857,11
always @(posedge i_clk)
if (op_ce)
begin
opF_wr <= (dcdF_wr)&&((~dcdR_cc)||(~dcdR_wr))
&&(~dcd_early_branch)&&(~dcd_illegal);
opR_wr <= (dcdR_wr)&&(~dcd_early_branch)&&(~dcd_illegal);
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)
896,7 → 907,7
// 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))
assign opA = ((wr_reg_ce)&&(wr_reg_id == opA_id)&&(opA_rd))
? wr_reg_vl : r_opA;
`else
assign opA = r_opA;
903,16 → 914,9
`endif
 
`ifdef OPT_PIPELINED
// Stall if we have decoded an instruction that will read register A
// AND ... something that may write a register is running
// AND (series of conditions here ...)
// The operation might set flags, and we wish to read the
// CC register
// OR ... (No other conditions)
assign dcdA_stall = (dcdA_rd) // &&(dcdvalid) is checked for elsewhere
&&((opvalid)||(mem_rdbusy)
||(div_busy)||(fpu_busy))
&&((opF_wr)&&(dcdA_cc));
assign dcdA_stall = (dcdvalid)&&(dcdA_rd)&&(
((opvalid_alu)&&(opF_wr)&&(dcdA_cc))
);
`else
// There are no pipeline hazards, if we aren't pipelined
assign dcdA_stall = 1'b0;
926,21 → 930,7
`endif
 
`ifdef OPT_PIPELINED
// Stall if we have decoded an instruction that will read register B
// AND ... something that may write a (unknown) register is running
// AND (series of conditions here ...)
// The operation might set flags, and we wish to read the
// CC register
// OR the operation might set register B, and we still need
// a clock to add the offset to it
assign dcdB_stall = (dcdB_rd) // &&(dcdvalid) is checked for elsewhere
// If the op stage isn't valid, yet something
// is running, then it must have been valid.
// We'll use the last values from that stage
// (opR_wr, opF_wr, opR) in our logic below.
&&((opvalid)||(mem_rdbusy)
||(div_busy)||(fpu_busy))
&&(
assign dcdB_stall = (dcdvalid)&&(dcdB_rd)&&(
// Stall on memory ops writing to my register
// (i.e. loads), or on any write to my
// register if I have an immediate offset
949,22 → 939,15
// instruction is invalid, not just the
// operand. That'll get wiped in the
// next operation anyway, so don't stall
// here. This keeps a BC X, BNZ Y from
// stalling between the two branches.
// BC X, BRA Y is still clear, since BRA Y
// is an early branch instruction.
// (This exception is commented out in
// order to help keep our logic simple, and
// because multiple conditional branches
// following each other constitutes a
// fairly unusualy code structure.)
//
((~dcd_zI)&&(opR == dcdB)&&(opR_wr))
// &&(opR != { op_gie, `CPU_PC_REG } )
// Stall following any instruction that will
// set the flags, if we're going to need the
// flags (CC) register for opB.
||((opF_wr)&&(dcdB_cc))
// here.
((~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 -- captured above
// ||((mem_busy)&&(~mem_we)&&(mem_last_reg==dcdB)&&(~dcd_zI))
974,11 → 957,10
// hazard without the pipeline?
assign dcdB_stall = 1'b0;
`endif
assign dcdF_stall = ((~dcdF[3])
assign dcdF_stall = (dcdvalid)&&((~dcdF[3])
||((dcdA_rd)&&(dcdA_cc))
||((dcdB_rd)&&(dcdB_cc)))
&&(opvalid)&&(opR_cc);
// &&(dcdvalid) is checked for elsewhere
//
//
// PIPELINE STAGE #4 :: Apply Instruction
999,7 → 981,7
generate
if (IMPLEMENT_DIVIDE != 0)
begin
div thedivide(i_clk, (i_rst)||(clear_pipeline), div_ce, opn[0],
div thedivide(i_clk, i_rst, div_ce, opn[0],
opA, opB, div_busy, div_valid, div_error, div_result,
div_flags);
end else begin
1183,10 → 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)
&&((alu_valid)||(div_valid)||(fpu_valid)))
||(mem_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
1214,11 → 1193,11
// 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 = { uhalt_phase, ufpu_err_flag,
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 = { ihalt_phase, ifpu_err_flag,
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 };
1588,7 → 1567,7
o_dbg_reg <= {{(32-AW){1'b0}},(i_dbg_reg[4])?upc:ipc};
else if (i_dbg_reg[3:0] == `CPU_CC_REG)
begin
o_dbg_reg[13:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
o_dbg_reg[12:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
o_dbg_reg[`CPU_GIE_BIT] <= gie;
end
end
1600,7 → 1579,7
o_dbg_reg <= (i_dbg_reg[4])?upc:ipc;
else if (i_dbg_reg[3:0] == `CPU_CC_REG)
begin
o_dbg_reg[13:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
o_dbg_reg[12:0] <= (i_dbg_reg[4])?w_uflags:w_iflags;
o_dbg_reg[`CPU_GIE_BIT] <= gie;
end
end

powered by: WebSVN 2.1.0

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