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 145 to Rev 160
    Reverse comparison

Rev 145 → Rev 160

/idecode.v
19,7 → 19,7
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
88,8 → 88,11
wire [(AW-1):0] o_dcd_branch_pc;
reg o_dcdI, o_dcdIz;
`ifdef OPT_PIPELINED
reg r_lock, r_pipe;
reg r_lock;
`endif
`ifdef OPT_PIPELINED_BUS_ACCESS
reg r_pipe;
`endif
 
 
wire [4:0] w_op;
443,7 → 446,7
// taking place, and it's only valid if the new word is not compressed.
//
reg r_valid;
`ifdef OPT_PIPELINED
`ifdef OPT_PIPELINED_BUS_ACCESS
initial r_pipe = 1'b0;
always @(posedge i_clk)
if (i_ce)
/pipemem.v
160,8 → 160,9
always @(posedge i_clk)
o_wreg <= fifo_oreg[rdaddr];
always @(posedge i_clk)
if (i_wb_ack)
o_result <= i_wb_data;
// if (i_wb_ack) isn't necessary, since o_valid won't be true
// then either.
o_result <= i_wb_data;
 
assign o_pipe_stalled = (cyc)
&&((i_wb_stall)||((~o_wb_stb_lcl)&&(~o_wb_stb_gbl)));
/div.v
12,7 → 12,7
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
44,6 → 44,10
output reg [(BW-1):0] o_quotient;
output wire [3:0] o_flags;
 
// r_busy is an internal busy register. It will clear one clock
// before we are valid, so it can't be o_busy ...
//
reg r_busy;
reg [(2*BW-2):0] r_divisor;
reg [(BW-1):0] r_dividend;
wire [(BW):0] diff; // , xdiff[(BW-1):0];
50,26 → 54,35
assign diff = r_dividend - r_divisor[(BW-1):0];
// assign xdiff= r_dividend - { 1'b0, r_divisor[(BW-1):1] };
 
reg r_sign, pre_sign, r_z, r_c;
reg [(LGBW):0] r_bit;
reg r_sign, pre_sign, r_z, r_c, last_bit;
reg [(LGBW-1):0] r_bit;
 
initial r_busy = 1'b0;
always @(posedge i_clk)
if (i_rst)
begin
r_busy <= 1'b0;
else if (i_wr)
r_busy <= 1'b1;
else if ((last_bit)||(o_err))
r_busy <= 1'b0;
 
initial o_busy = 1'b0;
always @(posedge i_clk)
if (i_rst)
o_busy <= 1'b0;
end else if (i_wr)
begin
else if (i_wr)
o_busy <= 1'b1;
end else if ((o_busy)&&((r_bit == 6'h0)||(o_err)))
else if (((last_bit)||(o_err))&&(~r_sign))
o_busy <= 1'b0;
// else busy is zero and stays at zero
else if (~r_busy)
o_busy <= 1'b0;
 
always @(posedge i_clk)
if ((i_rst)||(i_wr))
o_valid <= 1'b0;
else if (o_busy)
else if (r_busy)
begin
if ((r_bit == 6'h0)||(o_err))
if ((last_bit)||(o_err))
o_valid <= (o_err)||(~r_sign);
end else if (r_sign)
begin
85,12 → 98,26
else if (o_busy)
o_err <= (r_divisor == 0);
 
initial last_bit = 1'b0;
always @(posedge i_clk)
if ((i_wr)||(pre_sign)||(i_rst))
last_bit <= 1'b0;
else if (r_busy)
last_bit <= (r_bit == {{(LGBW-1){1'b0}},1'b1});
 
always @(posedge i_clk)
// if (i_rst) r_busy <= 1'b0;
// else
if (i_wr)
begin
//
// Set our values upon an initial command. Here's
// where we come in and start.
//
// r_busy <= 1'b1;
//
o_quotient <= 0;
// r_bit <= { 1'b1, {(LGBW){1'b0}} };
r_bit <= { 1'b0, {(LGBW){1'b1}} };
r_bit <= {(LGBW){1'b1}};
r_divisor <= { i_denominator, {(BW-1){1'b0}} };
r_dividend <= i_numerator;
r_sign <= 1'b0;
98,22 → 125,49
r_z <= 1'b1;
end else if (pre_sign)
begin
// r_bit <= r_bit - 1;
r_sign <= ((r_divisor[(2*BW-2)])^(r_dividend[(BW-1)]));;
//
// Note that we only come in here, for one clock, if
// our initial value may have been signed. If we are
// doing an unsigned divide, we then skip this step.
//
r_sign <= ((r_divisor[(2*BW-2)])^(r_dividend[(BW-1)]));
// Negate our dividend if necessary so that it becomes
// a magnitude only value
if (r_dividend[BW-1])
r_dividend <= -r_dividend;
// Do the same with the divisor--rendering it into
// a magnitude only.
if (r_divisor[(2*BW-2)])
r_divisor[(2*BW-2):(BW-1)] <= -r_divisor[(2*BW-2):(BW-1)];
//
// We only do this stage for a single clock, so go on
// with the rest of the divide otherwise.
pre_sign <= 1'b0;
end else if (o_busy)
end else if (r_busy)
begin
r_bit <= r_bit + {(LGBW+1){1'b1}}; // r_bit = r_bit - 1;
// While the divide is taking place, we examine each bit
// in turn here.
//
r_bit <= r_bit + {(LGBW){1'b1}}; // r_bit = r_bit - 1;
r_divisor <= { 1'b0, r_divisor[(2*BW-2):1] };
if (|r_divisor[(2*BW-2):(BW)])
begin
end else if (diff[BW])
begin
//
// diff = r_dividend - r_divisor[(BW-1):0];
//
// If this value was negative, there wasn't
// enough value in the dividend to support
// pulling off a bit. We'll move down a bit
// therefore and try again.
//
end else begin
//
// Put a '1' into our output accumulator.
// Subtract the divisor from the dividend,
// and then move on to the next bit
//
r_dividend <= diff[(BW-1):0];
o_quotient[r_bit[(LGBW-1):0]] <= 1'b1;
r_z <= 1'b0;
127,7 → 181,7
// Set Carry on an exact divide
wire w_n;
always @(posedge i_clk)
r_c <= (o_busy)&&((diff == 0)||(r_dividend == 0));
r_c <= (r_busy)&&((diff == 0)||(r_dividend == 0));
assign w_n = o_quotient[(BW-1)];
 
assign o_flags = { 1'b0, w_n, r_c, r_z };
/zipcpu.v
71,7 → 71,7
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
//
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
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;
292,6 → 292,9
`endif
`ifdef OPT_ILLEGAL_INSTRUCTION
reg op_illegal;
`else
wire op_illegal;
assign op_illegal = 1'b0;
`endif
reg op_break;
wire op_lock;
346,6 → 349,12
&&(~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, adf_ce_unconditional;
assign adf_ce_unconditional = (master_ce)&&(~clear_pipeline)&&(opvalid)
&&(~opvalid_mem)&&(~mem_rdbusy)&&(~div_busy)
&&(~fpu_busy);
assign adf_ce = (adf_ce_unconditional)&&(set_cond);
 
//
//
354,7 → 363,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;
 
424,9 → 433,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))&&(~clear_pipeline);
assign op_change_data_ce = 1'b1;
`endif
 
//
450,8 → 466,7
||((opvalid)&&(op_lock)&&(op_lock_stall))
||((opvalid)&&(op_break))
||(div_busy)||(fpu_busy);
assign alu_ce = (master_ce)&&((opvalid_alu)||(op_illegal))
&&(~alu_stall)
assign alu_ce = (master_ce)&&(opvalid_alu)&&(~alu_stall)
&&(~clear_pipeline);
`else
assign alu_stall = ((~master_ce)&&(opvalid_alu))
713,10 → 728,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)
729,9 → 744,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
 
744,7 → 759,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}
751,11 → 766,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
768,7 → 783,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
830,7 → 847,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_unconditional)||(mem_ce))
begin
opvalid <= 1'b0;
opvalid_alu <= 1'b0;
873,7 → 890,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);
914,7 → 931,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?
936,7 → 953,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
957,7 → 974,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
980,7 → 997,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
1120,7 → 1137,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_unconditional)||(mem_ce))
r_alu_phase <= op_phase;
assign alu_phase = r_alu_phase;
`else
1128,7 → 1145,7
`endif
 
always @(posedge i_clk)
if ((alu_ce)||(div_ce)||(fpu_ce))
if (adf_ce_unconditional)
alu_reg <= opR;
else if ((i_halt)&&(i_dbg_we))
alu_reg <= i_dbg_reg;
1139,15 → 1156,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_unconditional)||(mem_ce))
alu_gie <= op_gie;
always @(posedge i_clk)
if ((alu_ce)||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
if ((adf_ce_unconditional)
||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
&&(~mem_stalled)))
alu_pc <= op_pc;
 
1167,11 → 1185,11
always @(posedge i_clk)
if (i_rst)
r_alu_pc_valid <= 1'b0;
else if (alu_ce) // Includes && (~alu_clear_pipeline)
else if (adf_ce_unconditional)//Includes&&(~alu_clear_pipeline)
r_alu_pc_valid <= 1'b1;
else if ((~alu_busy)||(clear_pipeline))
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);
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;
1263,12 → 1281,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,
1275,19 → 1296,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 ...
1308,7 → 1331,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
1316,7 → 1339,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);
1341,10 → 1364,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))
1354,6 → 1378,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))
1376,23 → 1401,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;
 
1419,12 → 1444,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)
1441,11 → 1466,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;
1454,7 → 1479,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;
1468,7 → 1493,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))
1484,7 → 1509,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;
1497,7 → 1522,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))
1516,7 → 1541,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;
1529,7 → 1554,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))
1553,7 → 1578,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;
1566,7 → 1591,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))
1612,7 → 1637,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)))
1622,7 → 1647,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)))
1636,7 → 1661,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;
1696,10 → 1721,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;
 
//
//
1727,7 → 1754,7
// ||((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]
gie, sleep, wr_reg_ce, wr_gpreg_vl[4: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.