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

Subversion Repositories xulalx25soc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /xulalx25soc/trunk/rtl
    from Rev 72 to Rev 73
    Reverse comparison

Rev 72 → Rev 73

/cpu/zipcpu.v
165,7 → 165,7
input i_dbg_we;
input [31:0] i_dbg_data;
// Debug interface -- outputs
output reg o_dbg_stall;
output wire o_dbg_stall;
output reg [31:0] o_dbg_reg;
output reg [3:0] o_dbg_cc;
output wire o_break;
204,7 → 204,7
// (BUS, TRAP,ILL,BREAKEN,STEP,GIE,SLEEP ), V, N, C, Z
reg [3:0] flags, iflags;
wire [13:0] w_uflags, w_iflags;
reg trap, break_en, step, gie, sleep;
reg trap, break_en, step, gie, sleep, r_halted;
`ifdef OPT_ILLEGAL_INSTRUCTION
reg ill_err_u, ill_err_i;
`else
284,7 → 284,7
wire [13:0] opFl;
reg [5:0] r_opF;
wire [7:0] opF;
wire op_ce, op_phase, op_pipe;
wire op_ce, op_phase, op_pipe, op_change_data_ce;
// Some pipeline control wires
`ifdef OPT_PIPELINED
reg opA_alu, opA_mem;
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;
345,7 → 346,11
&&(~mem_rdbusy)&&(~div_busy)&&(~fpu_busy)
&&(set_cond);
 
 
// ALU, DIV, or FPU CE ... equivalent to the OR of all three of these
wire adf_ce;
assign adf_ce = (master_ce)&&(~clear_pipeline)&&(opvalid)
&&(~opvalid_mem)&&(~mem_rdbusy)&&(~div_busy)
&&(~fpu_busy)&&(set_cond);
//
//
// PIPELINE STAGE #5 :: Write-back
353,7 → 358,7
//
wire wr_reg_ce, wr_flags_ce, wr_write_pc, wr_write_cc;
wire [4:0] wr_reg_id;
wire [31:0] wr_reg_vl;
wire [31:0] wr_gpreg_vl, wr_spreg_vl;
wire w_switch_to_interrupt, w_release_from_interrupt;
reg [(AW-1):0] upc, ipc;
 
375,11 → 380,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
426,9 → 428,16
||(dcdF_stall)
);
assign op_ce = ((dcdvalid)||(dcd_illegal))&&(~op_stall)&&(~clear_pipeline);
// BUT ... op_ce is too complex for many of the data operations. So
// let's make their circuit enable code simpler. In particular, if
// op_ doesn't need to be preserved, we can change it all we want
// ... right? The clear_pipeline code, for example, really only needs
// to determine whether opvalid is true.
assign op_change_data_ce = (~op_stall);
`else
assign op_stall = (opvalid)&&(~master_ce);
assign op_ce = ((dcdvalid)||(dcd_illegal));
assign op_ce = ((dcdvalid)||(dcd_illegal))&&(~clear_pipeline);
assign op_change_data_ce = 1'b1;
`endif
 
//
458,7 → 467,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 → 482,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 → 525,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 → 535,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 → 580,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 → 638,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;
707,10 → 724,10
`endif
 
always @(posedge i_clk)
if (op_ce) // &&(dcdvalid))
if (op_change_data_ce)
begin
if ((wr_reg_ce)&&(wr_reg_id == dcdA))
r_opA <= wr_reg_vl;
r_opA <= wr_gpreg_vl;
else if (dcdA_pc)
r_opA <= w_pcA_v;
else if (dcdA_cc)
723,9 → 740,9
// 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;
// r_opA <= wr_gpreg_vl;
if ((wr_reg_ce)&&(wr_reg_id == opA_id)&&(opA_rd))
r_opA <= wr_reg_vl;
r_opA <= wr_gpreg_vl;
`endif
end
 
738,7 → 755,7
endgenerate
 
assign w_opBnI = (~dcdB_rd) ? 32'h00
: (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_reg_vl
: (((wr_reg_ce)&&(wr_reg_id == dcdB)) ? wr_gpreg_vl
: ((dcdB_pc) ? w_pcB_v
: ((dcdB_cc) ? { w_cpu_info, w_opB[22:14], // w_opB[31:14],
(dcdB[4])?w_uflags:w_iflags}
745,11 → 762,11
: w_opB)));
 
always @(posedge i_clk)
if (op_ce) // &&(dcdvalid))
if (op_change_data_ce)
r_opB <= w_opBnI + dcdI;
`ifdef OPT_PIPELINED
else if ((wr_reg_ce)&&(opB_id == wr_reg_id)&&(opB_rd))
r_opB <= wr_reg_vl;
r_opB <= wr_gpreg_vl;
`endif
 
// The logic here has become more complex than it should be, no thanks
762,7 → 779,9
// below, arriving at what we finally want in the (now wire net)
// opF.
always @(posedge i_clk)
if (op_ce)
if (op_ce) // Cannot do op_change_data_ce here since opF depends
// upon being either correct for a valid op, or correct
// for the last valid op
begin // Set the flag condition codes, bit order is [3:0]=VNCZ
case(dcdF[2:0])
3'h0: r_opF <= 6'h00; // Always
824,7 → 843,7
opvalid_div <= (dcdDV)&&(w_opvalid);
opvalid_fpu <= (dcdFP)&&(w_opvalid);
`endif
end else if ((clear_pipeline)||(alu_ce)||(mem_ce)||(div_ce)||(fpu_ce))
end else if ((clear_pipeline)||(adf_ce)||(mem_ce))
begin
opvalid <= 1'b0;
opvalid_alu <= 1'b0;
867,7 → 886,7
 
initial r_op_lock = 1'b0;
always @(posedge i_clk)
if (i_rst)
if ((i_rst)||(clear_pipeline))
r_op_lock <= 1'b0;
else if (op_ce)
r_op_lock <= (dcd_lock)&&(~clear_pipeline);
908,7 → 927,7
end
 
always @(posedge i_clk)
if (op_ce)
if (op_change_data_ce)
begin
opn <= dcdOp; // Which ALU operation?
// opM <= dcdM; // Is this a memory operation?
930,7 → 949,7
always @(posedge i_clk)
if ((i_rst)||(clear_pipeline))
r_op_phase <= 1'b0;
else if (op_ce)
else if (op_change_data_ce)
r_op_phase <= dcd_phase;
assign op_phase = r_op_phase;
`else
951,7 → 970,7
// 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;
? wr_gpreg_vl : r_opA;
`else
assign opA = r_opA;
`endif
974,7 → 993,7
 
`ifdef OPT_PIPELINED
assign opB = ((wr_reg_ce)&&(wr_reg_id == opB_id)&&(opB_rd))
? wr_reg_vl: r_opB;
? wr_gpreg_vl: r_opB;
`else
assign opB = r_opB;
`endif
995,31 → 1014,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.
1118,7 → 1133,7
always @(posedge i_clk)
if (i_rst)
r_alu_phase <= 1'b0;
else if ((alu_ce)||(mem_ce)||(div_ce)||(fpu_ce))
else if ((adf_ce)||(mem_ce))
r_alu_phase <= op_phase;
assign alu_phase = r_alu_phase;
`else
1126,7 → 1141,7
`endif
 
always @(posedge i_clk)
if ((alu_ce)||(div_ce)||(fpu_ce))
if (adf_ce)
alu_reg <= opR;
else if ((i_halt)&&(i_dbg_we))
alu_reg <= i_dbg_reg;
1137,15 → 1152,16
reg dbgv;
initial dbgv = 1'b0;
always @(posedge i_clk)
dbgv <= (~i_rst)&&(~alu_ce)&&((i_halt)&&(i_dbg_we));
dbgv <= (~i_rst)&&(i_halt)&&(i_dbg_we)&&(r_halted);
reg [31:0] dbg_val;
always @(posedge i_clk)
dbg_val <= i_dbg_data;
always @(posedge i_clk)
if ((alu_ce)||(mem_ce))
if ((adf_ce)||(mem_ce))
alu_gie <= op_gie;
always @(posedge i_clk)
if ((alu_ce)||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
if ((adf_ce)
||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
&&(~mem_stalled)))
alu_pc <= op_pc;
 
1160,13 → 1176,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 (adf_ce) // Includes && (~alu_clear_pipeline)
r_alu_pc_valid <= 1'b1;
else if (((~alu_busy)&&(~div_busy)&&(~fpu_busy))||(clear_pipeline))
r_alu_pc_valid <= 1'b0;
assign alu_pc_valid = (r_alu_pc_valid)&&((~alu_busy)&&(~div_busy)&&(~fpu_busy));
always @(posedge i_clk)
if (i_rst)
mem_pc_valid <= 1'b0;
1258,12 → 1277,15
// 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 = (dbgv)||(~alu_illegal)&&
(((alu_wr)&&(~clear_pipeline)
&&((alu_valid)||(div_valid)||(fpu_valid)))
||(mem_valid));
assign wr_reg_ce = (dbgv)||(mem_valid)
||((~clear_pipeline)&&(~alu_illegal)
&&(((alu_wr)&&(alu_valid))
||(div_valid)||(fpu_valid)));
`else
assign wr_reg_ce = (dbgv)||((alu_wr)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
assign wr_reg_ce = (dbgv)||(mem_valid)
||((~clear_pipeline)
&&(((alu_wr)&&(alu_valid))
||(div_valid)||(fpu_valid)));
`endif
// Which register shall be written?
// COULD SIMPLIFY THIS: by adding three bits to these registers,
1270,19 → 1292,21
// One or PC, one for CC, and one for GIE match
// Note that the alu_reg is the register to write on a divide or
// FPU operation.
assign wr_reg_id = (alu_wr)?alu_reg:mem_wreg;
assign wr_reg_id = (alu_wr|div_valid|fpu_valid)?alu_reg:mem_wreg;
// Are we writing to the CC register?
assign wr_write_cc = (wr_reg_id[3:0] == `CPU_CC_REG);
// 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
assign wr_gpreg_vl = ((mem_valid) ? mem_result
:((div_valid|fpu_valid))
? ((div_valid) ? div_result:fpu_result)
:((dbgv) ? dbg_val : alu_result));
assign wr_spreg_vl = ((mem_valid) ? mem_result
:((dbgv) ? dbg_val : alu_result));
always @(posedge i_clk)
if (wr_reg_ce)
regset[wr_reg_id] <= wr_reg_vl;
regset[wr_reg_id] <= wr_gpreg_vl;
 
//
// Write back to the condition codes/flags register ...
1303,7 → 1327,7
always @(posedge i_clk)
// If explicitly writing the register itself
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_cc))
flags <= wr_reg_vl[3:0];
flags <= wr_gpreg_vl[3:0];
// Otherwise if we're setting the flags from an ALU operation
else if ((wr_flags_ce)&&(alu_gie))
flags <= (div_valid)?div_flags:((fpu_valid)?fpu_flags
1311,7 → 1335,7
 
always @(posedge i_clk)
if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_cc))
iflags <= wr_reg_vl[3:0];
iflags <= wr_gpreg_vl[3:0];
else if ((wr_flags_ce)&&(~alu_gie))
iflags <= (div_valid)?div_flags:((fpu_valid)?fpu_flags
: alu_flags);
1336,10 → 1360,11
if ((i_rst)||(i_halt))
break_en <= 1'b0;
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_cc))
break_en <= wr_reg_vl[`CPU_BREAK_BIT];
break_en <= wr_spreg_vl[`CPU_BREAK_BIT];
`ifdef OPT_ILLEGAL_INSTRUCTION
assign o_break = ((break_en)||(~op_gie))&&(op_break)
&&(~alu_valid)&&(~mem_valid)&&(~mem_busy)
&&(~alu_busy)
&&(~div_busy)&&(~fpu_busy)
&&(~clear_pipeline)
||((~alu_gie)&&(bus_err))
1349,6 → 1374,7
`else
assign o_break = (((break_en)||(~op_gie))&&(op_break)
&&(~alu_valid)&&(~mem_valid)&&(~mem_busy)
&&(~alu_busy)&&(~div_busy)&&(~fpu_busy)
&&(~clear_pipeline))
||((~alu_gie)&&(bus_err))
||((~alu_gie)&&(div_valid)&&(div_error))
1371,23 → 1397,23
// Well ... not quite. Switching to user mode and
// sleep mode shouold only be possible if the interrupt
// flag isn't set.
// Thus: if (i_interrupt)&&(wr_reg_vl[GIE])
// Thus: if (i_interrupt)&&(wr_spreg_vl[GIE])
// don't set the sleep bit
// otherwise however it would o.w. be set
sleep <= (wr_reg_vl[`CPU_SLEEP_BIT])
&&((~i_interrupt)||(~wr_reg_vl[`CPU_GIE_BIT]));
else if ((wr_reg_ce)&&(wr_write_cc)&&(wr_reg_vl[`CPU_GIE_BIT]))
sleep <= (wr_spreg_vl[`CPU_SLEEP_BIT])
&&((~i_interrupt)||(~wr_spreg_vl[`CPU_GIE_BIT]));
else if ((wr_reg_ce)&&(wr_write_cc)&&(wr_spreg_vl[`CPU_GIE_BIT]))
// In user mode, however, you can only set the sleep
// mode while remaining in user mode. You can't switch
// to sleep mode *and* supervisor mode at the same
// time, lest you halt the CPU.
sleep <= wr_reg_vl[`CPU_SLEEP_BIT];
sleep <= wr_spreg_vl[`CPU_SLEEP_BIT];
 
always @(posedge i_clk)
if ((i_rst)||(w_switch_to_interrupt))
step <= 1'b0;
else if ((wr_reg_ce)&&(~alu_gie)&&(wr_reg_id[4])&&(wr_write_cc))
step <= wr_reg_vl[`CPU_STEP_BIT];
step <= wr_spreg_vl[`CPU_STEP_BIT];
else if (((alu_pc_valid)||(mem_pc_valid))&&(step)&&(gie))
step <= 1'b0;
 
1414,12 → 1440,12
//
||(bus_err)
// If we write to the CC register
||((wr_reg_ce)&&(~wr_reg_vl[`CPU_GIE_BIT])
||((wr_reg_ce)&&(~wr_spreg_vl[`CPU_GIE_BIT])
&&(wr_reg_id[4])&&(wr_write_cc))
);
assign w_release_from_interrupt = (~gie)&&(~i_interrupt)
// Then if we write the CC register
&&(((wr_reg_ce)&&(wr_reg_vl[`CPU_GIE_BIT])
&&(((wr_reg_ce)&&(wr_spreg_vl[`CPU_GIE_BIT])
&&(~wr_reg_id[4])&&(wr_write_cc))
);
always @(posedge i_clk)
1436,11 → 1462,11
trap <= 1'b0;
else if (w_release_from_interrupt)
trap <= 1'b0;
else if ((alu_gie)&&(wr_reg_ce)&&(~wr_reg_vl[`CPU_GIE_BIT])
else if ((alu_gie)&&(wr_reg_ce)&&(~wr_spreg_vl[`CPU_GIE_BIT])
&&(wr_write_cc)) // &&(wr_reg_id[4]) implied
trap <= 1'b1;
else if ((wr_reg_ce)&&(wr_write_cc)&&(wr_reg_id[4]))
trap <= wr_reg_vl[`CPU_TRAP_BIT];
trap <= wr_spreg_vl[`CPU_TRAP_BIT];
 
`ifdef OPT_ILLEGAL_INSTRUCTION
initial ill_err_i = 1'b0;
1449,7 → 1475,7
ill_err_i <= 1'b0;
// Only the debug interface can clear this bit
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
&&(~wr_reg_vl[`CPU_ILL_BIT]))
&&(~wr_spreg_vl[`CPU_ILL_BIT]))
ill_err_i <= 1'b0;
else if ((alu_pc_valid)&&(alu_illegal)&&(~alu_gie))
ill_err_i <= 1'b1;
1463,7 → 1489,7
// If the supervisor writes to this register, clearing the
// bit, then clear it
else if (((~alu_gie)||(dbgv))
&&(wr_reg_ce)&&(~wr_reg_vl[`CPU_ILL_BIT])
&&(wr_reg_ce)&&(~wr_spreg_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))
1479,7 → 1505,7
if (i_rst)
ibus_err_flag <= 1'b0;
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
&&(~wr_reg_vl[`CPU_BUSERR_BIT]))
&&(~wr_spreg_vl[`CPU_BUSERR_BIT]))
ibus_err_flag <= 1'b0;
else if ((bus_err)&&(~alu_gie))
ibus_err_flag <= 1'b1;
1492,7 → 1518,7
else if (w_release_from_interrupt)
ubus_err_flag <= 1'b0;
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce)
&&(~wr_reg_vl[`CPU_BUSERR_BIT])
&&(~wr_spreg_vl[`CPU_BUSERR_BIT])
&&(wr_reg_id[4])&&(wr_write_cc))
ubus_err_flag <= 1'b0;
else if ((bus_err)&&(alu_gie))
1511,7 → 1537,7
if (i_rst)
r_idiv_err_flag <= 1'b0;
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
&&(~wr_reg_vl[`CPU_DIVERR_BIT]))
&&(~wr_spreg_vl[`CPU_DIVERR_BIT]))
r_idiv_err_flag <= 1'b0;
else if ((div_error)&&(div_valid)&&(~alu_gie))
r_idiv_err_flag <= 1'b1;
1524,7 → 1550,7
else if (w_release_from_interrupt)
r_udiv_err_flag <= 1'b0;
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce)
&&(~wr_reg_vl[`CPU_DIVERR_BIT])
&&(~wr_spreg_vl[`CPU_DIVERR_BIT])
&&(wr_reg_id[4])&&(wr_write_cc))
r_udiv_err_flag <= 1'b0;
else if ((div_error)&&(alu_gie)&&(div_valid))
1548,7 → 1574,7
if (i_rst)
r_ifpu_err_flag <= 1'b0;
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
&&(~wr_reg_vl[`CPU_FPUERR_BIT]))
&&(~wr_spreg_vl[`CPU_FPUERR_BIT]))
r_ifpu_err_flag <= 1'b0;
else if ((fpu_error)&&(fpu_valid)&&(~alu_gie))
r_ifpu_err_flag <= 1'b1;
1561,7 → 1587,7
else if (w_release_from_interrupt)
r_ufpu_err_flag <= 1'b0;
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce)
&&(~wr_reg_vl[`CPU_FPUERR_BIT])
&&(~wr_spreg_vl[`CPU_FPUERR_BIT])
&&(wr_reg_id[4])&&(wr_write_cc))
r_ufpu_err_flag <= 1'b0;
else if ((fpu_error)&&(alu_gie)&&(fpu_valid))
1607,7 → 1633,7
// a non-gie instruction?
always @(posedge i_clk)
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc))
upc <= wr_reg_vl[(AW-1):0];
upc <= wr_spreg_vl[(AW-1):0];
else if ((alu_gie)&&
(((alu_pc_valid)&&(~clear_pipeline))
||(mem_pc_valid)))
1617,7 → 1643,7
if (i_rst)
ipc <= RESET_ADDRESS;
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_pc))
ipc <= wr_reg_vl[(AW-1):0];
ipc <= wr_spreg_vl[(AW-1):0];
else if ((~alu_gie)&&
(((alu_pc_valid)&&(~clear_pipeline))
||(mem_pc_valid)))
1631,7 → 1657,7
else if (w_release_from_interrupt)
pf_pc <= upc;
else if ((wr_reg_ce)&&(wr_reg_id[4] == gie)&&(wr_write_pc))
pf_pc <= wr_reg_vl[(AW-1):0];
pf_pc <= wr_spreg_vl[(AW-1):0];
`ifdef OPT_PIPELINED
else if ((dcd_early_branch)&&(~clear_pipeline))
pf_pc <= dcd_branch_pc + 1;
1638,7 → 1664,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
 
1689,10 → 1717,12
o_dbg_cc <= { o_break, bus_err, gie, sleep };
 
always @(posedge i_clk)
o_dbg_stall <= (i_halt)&&(
r_halted <= (i_halt)&&(
(pf_cyc)||(mem_cyc_gbl)||(mem_cyc_lcl)||(mem_busy)
||(alu_busy)||(div_busy)||(fpu_busy)
||((~opvalid)&&(~i_rst)&&(~dcd_illegal))
||((~dcdvalid)&&(~i_rst)&&(~pf_illegal)));
assign o_dbg_stall = r_halted;
 
//
//
1707,20 → 1737,47
`ifdef DEBUG_SCOPE
always @(posedge i_clk)
o_debug <= {
/*
o_break, i_wb_err, pf_pc[1:0],
//
flags,
pf_valid, dcdvalid, opvalid, alu_valid, mem_valid,
//
pf_valid, dcdvalid, opvalid, alu_valid,
//
mem_valid,
op_ce, alu_ce, mem_ce,
//
master_ce, opvalid_alu, opvalid_mem,
master_ce,
opvalid_alu, opvalid_mem, alu_stall,
//
alu_stall, mem_busy, op_pipe, mem_pipe_stalled,
mem_busy, op_pipe,
`ifdef OPT_PIPELINED_BUS_ACCESS
mem_pipe_stalled,
`else
1'b0,
`endif
mem_we,
//
// ((opvalid_alu)&&(alu_stall))
// ||((opvalid_mem)&&(~op_pipe)&&(mem_busy))
// ||((opvalid_mem)&&( op_pipe)&&(mem_pipe_stalled)));
// opA[23:20], opA[3:0],
gie, sleep, wr_reg_ce, wr_reg_vl[4:0]
*/
 
o_break, i_wb_err, o_wb_gbl_cyc, o_wb_gbl_stb,
pf_valid, dcdvalid, opvalid, alu_valid,
mem_valid, dcd_ce, op_ce, alu_ce,
mem_ce,
//
(new_pc)||((dcd_early_branch)&&(~clear_pipeline)),
gie, sleep,
{ ((o_wb_gbl_cyc)&&(o_wb_gbl_stb)&&(o_wb_we))
? o_wb_data[15:0]
: ((o_wb_gbl_cyc)&&(~o_wb_we)&&(i_wb_ack))
? i_wb_data[15:0]
: o_wb_addr[15:0]
}
/*
i_rst, master_ce, (new_pc),
((dcd_early_branch)&&(dcdvalid)),

powered by: WebSVN 2.1.0

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