URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/zipcpu
- from Rev 83 to Rev 82
- ↔ Reverse comparison
Rev 83 → Rev 82
/trunk/rtl/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 |