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/core
    from Rev 140 to Rev 145
    Reverse comparison

Rev 140 → Rev 145

/zipcpu.v
304,7 → 304,8
//
//
reg [(AW-1):0] alu_pc;
reg alu_pc_valid, mem_pc_valid;
reg r_alu_pc_valid, mem_pc_valid;
wire alu_pc_valid;
wire alu_phase;
wire alu_ce, alu_stall;
wire [31:0] alu_result;
375,11 → 376,8
//
// PIPELINE STAGE #2 :: Instruction Decode
// Calculate stall conditions
`ifdef OPT_PIPELINED
assign dcd_ce = ((~dcdvalid)||(~dcd_stalled))&&(~clear_pipeline);
`else
assign dcd_ce = 1'b1;
`endif
 
`ifdef OPT_PIPELINED
assign dcd_stalled = (dcdvalid)&&(op_stall);
`else
428,7 → 426,7
assign op_ce = ((dcdvalid)||(dcd_illegal))&&(~op_stall)&&(~clear_pipeline);
`else
assign op_stall = (opvalid)&&(~master_ce);
assign op_ce = ((dcdvalid)||(dcd_illegal));
assign op_ce = ((dcdvalid)||(dcd_illegal))&&(~clear_pipeline);
`endif
 
//
458,7 → 456,7
`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)||(op_illegal))&&(~alu_stall)&&(~clear_pipeline);
`endif
//
 
473,7 → 471,13
// 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);
//
// However, in hind sight this logic didn't work. What happens when
// something gets in the pipeline and then (due to interrupt or some
// such) needs to be voided? Thus we avoid simplification and keep
// what worked here.
assign mem_ce = (master_ce)&&(opvalid_mem)&&(~mem_stalled)
&&(~clear_pipeline);
`endif
`ifdef OPT_PIPELINED_BUS_ACCESS
assign mem_stalled = (~master_ce)||(alu_busy)||((opvalid_mem)&&(
510,9 → 514,9
`ifdef OPT_SINGLE_FETCH
wire pf_ce;
 
assign pf_ce = (~pf_valid)&&(~dcdvalid)&&(~opvalid)&&(~alu_valid);
assign pf_ce = (~pf_valid)&&(~dcdvalid)&&(~opvalid)&&(~alu_busy)&&(~mem_busy)&&(~alu_pc_valid)&&(~mem_pc_valid);
prefetch #(ADDRESS_WIDTH)
pf(i_clk, i_rst, (pf_ce), (~dcd_stalled), pf_pc, gie,
pf(i_clk, (i_rst), (pf_ce), (~dcd_stalled), pf_pc, gie,
instruction, instruction_pc, instruction_gie,
pf_valid, pf_illegal,
pf_cyc, pf_stb, pf_we, pf_addr, pf_data,
520,7 → 524,7
 
initial r_dcdvalid = 1'b0;
always @(posedge i_clk)
if (i_rst)
if ((i_rst)||(clear_pipeline))
r_dcdvalid <= 1'b0;
else if (dcd_ce)
r_dcdvalid <= (pf_valid);
565,7 → 569,7
if ((i_rst)||(clear_pipeline))
r_dcdvalid <= 1'b0;
else if (dcd_ce)
r_dcdvalid <= (pf_valid)&&(~clear_pipeline)&&(~dcd_ljmp)&&((~r_dcdvalid)||(~dcd_early_branch));
r_dcdvalid <= (pf_valid)&&(~dcd_ljmp)&&((~r_dcdvalid)||(~dcd_early_branch));
else if (op_ce)
r_dcdvalid <= 1'b0;
assign dcdvalid = r_dcdvalid;
623,6 → 627,8
always @(posedge i_clk)
if (op_ce)
r_op_pipe <= dcd_pipe;
else if (mem_ce) // Clear us any time an op_ is clocked in
r_op_pipe <= 1'b0;
assign op_pipe = r_op_pipe;
`else
assign op_pipe = 1'b0;
995,31 → 1001,27
&&((opvalid)||(mem_rdbusy)
||(div_busy)||(fpu_busy)||(alu_busy))
&&(
// Stall on memory ops writing to my register
// (i.e. loads), or on any write to my
// register if I have an immediate offset
// Actually, this is worse. I can't tell
// whether or not my register is going to
// be written to, so
// Note the exception for writing to the PC:
// if I write to the PC, the whole next
// 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.)
//
// Okay, what happens if the result register
// from instruction 1 becomes the input for
// instruction two, *and* there's an immediate
// offset in instruction two? In that case, we
// need an extra clock between the two
// instructions to calculate the base plus
// offset.
//
// What if instruction 1 (or before) is in a
// memory pipeline? We may no longer know what
// the register was! We will then need to
// blindly wait. We'll temper this only waiting
// if we're not piping this new instruction.
// If we were piping, the pipe logic in the
// decode circuit has told us that the hazard
// is clear, so we're okay then.
//
((~dcd_zI)&&(
((opR == dcdB)&&(opR_wr))
||(((opvalid_mem)||(mem_rdbusy))
&&(op_pipe))))
||((mem_rdbusy)&&(~dcd_pipe))
))
// Stall following any instruction that will
// set the flags, if we're going to need the
// flags (CC) register for opB.
1160,13 → 1162,16
assign alu_illegal = (alu_illegal_op)||(r_alu_illegal);
`endif
 
initial alu_pc_valid = 1'b0;
initial r_alu_pc_valid = 1'b0;
initial mem_pc_valid = 1'b0;
always @(posedge i_clk)
if (i_rst)
alu_pc_valid <= 1'b0;
else
alu_pc_valid <= (alu_ce);
r_alu_pc_valid <= 1'b0;
else if (alu_ce) // Includes && (~alu_clear_pipeline)
r_alu_pc_valid <= 1'b1;
else if ((~alu_busy)||(clear_pipeline))
r_alu_pc_valid <= 1'b0;
assign alu_pc_valid = (r_alu_pc_valid)&&(~alu_busy);
always @(posedge i_clk)
if (i_rst)
mem_pc_valid <= 1'b0;
1638,7 → 1643,9
else if ((new_pc)||((~dcd_stalled)&&(pf_valid)))
pf_pc <= pf_pc + {{(AW-1){1'b0}},1'b1};
`else
else if ((alu_pc_valid)&&(~clear_pipeline))
else if ((alu_gie==gie)&&(
((alu_pc_valid)&&(~clear_pipeline))
||(mem_pc_valid)))
pf_pc <= alu_pc;
`endif
 

powered by: WebSVN 2.1.0

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