Line 135... |
Line 135... |
`endif
|
`endif
|
);
|
);
|
parameter RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=24,
|
parameter RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=24,
|
LGICACHE=6;
|
LGICACHE=6;
|
`ifdef OPT_MULTIPLY
|
`ifdef OPT_MULTIPLY
|
parameter IMPLEMENT_MPY = 1;
|
parameter IMPLEMENT_MPY = `OPT_MULTIPLY;
|
`else
|
`else
|
parameter IMPLEMENT_MPY = 0;
|
parameter IMPLEMENT_MPY = 0;
|
`endif
|
`endif
|
`ifdef OPT_DIVIDE
|
`ifdef OPT_DIVIDE
|
parameter IMPLEMENT_DIVIDE = 1;
|
parameter IMPLEMENT_DIVIDE = 1;
|
Line 282... |
Line 282... |
wire [31:0] opA_nowait, opB_nowait, opA, opB;
|
wire [31:0] opA_nowait, opB_nowait, opA, opB;
|
reg opR_wr, opR_cc, opF_wr, op_gie;
|
reg opR_wr, opR_cc, opF_wr, op_gie;
|
wire [13:0] opFl;
|
wire [13:0] opFl;
|
reg [5:0] r_opF;
|
reg [5:0] r_opF;
|
wire [7:0] opF;
|
wire [7:0] opF;
|
wire op_ce, op_phase;
|
wire op_ce, op_phase, op_pipe;
|
// Some pipeline control wires
|
// Some pipeline control wires
|
`ifdef OPT_PIPELINED
|
`ifdef OPT_PIPELINED
|
reg opA_alu, opA_mem;
|
reg opA_alu, opA_mem;
|
reg opB_alu, opB_mem;
|
reg opB_alu, opB_mem;
|
`endif
|
`endif
|
Line 302... |
Line 302... |
// PIPELINE STAGE #4 :: ALU / Memory
|
// PIPELINE STAGE #4 :: ALU / Memory
|
// Variable declarations
|
// Variable declarations
|
//
|
//
|
//
|
//
|
reg [(AW-1):0] alu_pc;
|
reg [(AW-1):0] alu_pc;
|
reg alu_pc_valid;
|
reg alu_pc_valid, mem_pc_valid;
|
wire alu_phase;
|
wire alu_phase;
|
wire alu_ce, alu_stall;
|
wire alu_ce, alu_stall;
|
wire [31:0] alu_result;
|
wire [31:0] alu_result;
|
wire [3:0] alu_flags;
|
wire [3:0] alu_flags;
|
wire alu_valid, alu_busy;
|
wire alu_valid, alu_busy;
|
Line 606... |
Line 606... |
dcd_pipe);
|
dcd_pipe);
|
assign dcd_ljmp = 1'b0;
|
assign dcd_ljmp = 1'b0;
|
`endif
|
`endif
|
|
|
`ifdef OPT_PIPELINED_BUS_ACCESS
|
`ifdef OPT_PIPELINED_BUS_ACCESS
|
reg op_pipe;
|
reg r_op_pipe;
|
|
|
initial op_pipe = 1'b0;
|
initial r_op_pipe = 1'b0;
|
// To be a pipeable operation, there must be
|
// To be a pipeable operation, there must be
|
// two valid adjacent instructions
|
// two valid adjacent instructions
|
// Both must be memory instructions
|
// Both must be memory instructions
|
// Both must be writes, or both must be reads
|
// Both must be writes, or both must be reads
|
// Both operations must be to the same identical address,
|
// Both operations must be to the same identical address,
|
Line 620... |
Line 620... |
//
|
//
|
// However ... we need to know this before this clock, hence this is
|
// However ... we need to know this before this clock, hence this is
|
// calculated in the instruction decoder.
|
// calculated in the instruction decoder.
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (op_ce)
|
if (op_ce)
|
op_pipe <= dcd_pipe;
|
r_op_pipe <= dcd_pipe;
|
|
assign op_pipe = r_op_pipe;
|
|
`else
|
|
assign op_pipe = 1'b0;
|
`endif
|
`endif
|
|
|
//
|
//
|
//
|
//
|
// PIPELINE STAGE #3 :: Read Operands (Registers)
|
// PIPELINE STAGE #3 :: Read Operands (Registers)
|
//
|
//
|
//
|
//
|
assign w_opA = regset[dcdA];
|
assign w_opA = regset[dcdA];
|
assign w_opB = regset[dcdB];
|
assign w_opB = regset[dcdB];
|
|
|
|
wire [8:0] w_cpu_info;
|
|
assign w_cpu_info = {
|
|
`ifdef OPT_ILLEGAL_INSTRUCTION
|
|
1'b1,
|
|
`else
|
|
1'b0,
|
|
`endif
|
|
`ifdef OPT_MULTIPLY
|
|
1'b1,
|
|
`else
|
|
1'b0,
|
|
`endif
|
|
`ifdef OPT_DIVIDE
|
|
1'b1,
|
|
`else
|
|
1'b0,
|
|
`endif
|
|
`ifdef OPT_IMPLEMENT_FPU
|
|
1'b1,
|
|
`else
|
|
1'b0,
|
|
`endif
|
|
`ifdef OPT_PIPELINED
|
|
1'b1,
|
|
`else
|
|
1'b0,
|
|
`endif
|
|
`ifdef OPT_TRADITIONAL_CACHE
|
|
1'b1,
|
|
`else
|
|
1'b0,
|
|
`endif
|
|
`ifdef OPT_EARLY_BRANCHING
|
|
1'b1,
|
|
`else
|
|
1'b0,
|
|
`endif
|
|
`ifdef OPT_PIPELINED_BUS_ACCESS
|
|
1'b1,
|
|
`else
|
|
1'b0,
|
|
`endif
|
|
`ifdef OPT_VLIW
|
|
1'b1
|
|
`else
|
|
1'b0
|
|
`endif
|
|
};
|
|
|
wire [31:0] w_pcA_v;
|
wire [31:0] w_pcA_v;
|
generate
|
generate
|
if (AW < 32)
|
if (AW < 32)
|
assign w_pcA_v = {{(32-AW){1'b0}}, (dcdA[4] == dcd_gie)?dcd_pc:upc };
|
assign w_pcA_v = {{(32-AW){1'b0}}, (dcdA[4] == dcd_gie)?dcd_pc:upc };
|
else
|
else
|
Line 660... |
Line 712... |
if ((wr_reg_ce)&&(wr_reg_id == dcdA))
|
if ((wr_reg_ce)&&(wr_reg_id == dcdA))
|
r_opA <= wr_reg_vl;
|
r_opA <= wr_reg_vl;
|
else if (dcdA_pc)
|
else if (dcdA_pc)
|
r_opA <= w_pcA_v;
|
r_opA <= w_pcA_v;
|
else if (dcdA_cc)
|
else if (dcdA_cc)
|
r_opA <= { w_opA[31:14], (dcdA[4])?w_uflags:w_iflags };
|
r_opA <= { w_cpu_info, w_opA[22:14], (dcdA[4])?w_uflags:w_iflags };
|
else
|
else
|
r_opA <= w_opA;
|
r_opA <= w_opA;
|
`ifdef OPT_PIPELINED
|
`ifdef OPT_PIPELINED
|
end else
|
end else
|
begin // We were going to pick these up when they became valid,
|
begin // We were going to pick these up when they became valid,
|
Line 686... |
Line 738... |
endgenerate
|
endgenerate
|
|
|
assign w_opBnI = (~dcdB_rd) ? 32'h00
|
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_reg_vl
|
: ((dcdB_pc) ? w_pcB_v
|
: ((dcdB_pc) ? w_pcB_v
|
: ((dcdB_cc) ? { w_opB[31:14], (dcdB[4])?w_uflags:w_iflags}
|
: ((dcdB_cc) ? { w_cpu_info, w_opB[22:14], // w_opB[31:14],
|
|
(dcdB[4])?w_uflags:w_iflags}
|
: w_opB)));
|
: w_opB)));
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (op_ce) // &&(dcdvalid))
|
if (op_ce) // &&(dcdvalid))
|
r_opB <= w_opBnI + dcdI;
|
r_opB <= w_opBnI + dcdI;
|
Line 814... |
Line 867... |
|
|
initial r_op_lock = 1'b0;
|
initial r_op_lock = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
r_op_lock <= 1'b0;
|
r_op_lock <= 1'b0;
|
else if ((op_ce)&&(dcd_lock))
|
else if (op_ce)
|
r_op_lock <= 1'b1;
|
r_op_lock <= (dcd_lock)&&(~clear_pipeline);
|
else if ((op_ce)||(clear_pipeline))
|
|
r_op_lock <= 1'b0;
|
|
assign op_lock = r_op_lock;
|
assign op_lock = r_op_lock;
|
|
|
end else begin
|
end else begin
|
assign op_lock_stall = 1'b0;
|
assign op_lock_stall = 1'b0;
|
assign op_lock = 1'b0;
|
assign op_lock = 1'b0;
|
Line 940... |
Line 991... |
// If the op stage isn't valid, yet something
|
// If the op stage isn't valid, yet something
|
// is running, then it must have been valid.
|
// is running, then it must have been valid.
|
// We'll use the last values from that stage
|
// We'll use the last values from that stage
|
// (opR_wr, opF_wr, opR) in our logic below.
|
// (opR_wr, opF_wr, opR) in our logic below.
|
&&((opvalid)||(mem_rdbusy)
|
&&((opvalid)||(mem_rdbusy)
|
||(div_busy)||(fpu_busy))
|
||(div_busy)||(fpu_busy)||(alu_busy))
|
&&(
|
&&(
|
// Stall on memory ops writing to my register
|
// Stall on memory ops writing to my register
|
// (i.e. loads), or on any write to my
|
// (i.e. loads), or on any write to my
|
// register if I have an immediate offset
|
// 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:
|
// Note the exception for writing to the PC:
|
// if I write to the PC, the whole next
|
// if I write to the PC, the whole next
|
// instruction is invalid, not just the
|
// instruction is invalid, not just the
|
// operand. That'll get wiped in the
|
// operand. That'll get wiped in the
|
// next operation anyway, so don't stall
|
// next operation anyway, so don't stall
|
Line 960... |
Line 1014... |
// order to help keep our logic simple, and
|
// order to help keep our logic simple, and
|
// because multiple conditional branches
|
// because multiple conditional branches
|
// following each other constitutes a
|
// following each other constitutes a
|
// fairly unusualy code structure.)
|
// fairly unusualy code structure.)
|
//
|
//
|
((~dcd_zI)&&(opR == dcdB)&&(opR_wr))
|
((~dcd_zI)&&(
|
// &&(opR != { op_gie, `CPU_PC_REG } )
|
((opR == dcdB)&&(opR_wr))
|
|
||(((opvalid_mem)||(mem_rdbusy))
|
|
&&(op_pipe))))
|
// Stall following any instruction that will
|
// Stall following any instruction that will
|
// set the flags, if we're going to need the
|
// set the flags, if we're going to need the
|
// flags (CC) register for opB.
|
// flags (CC) register for opB.
|
||((opF_wr)&&(dcdB_cc))
|
||((opF_wr)&&(dcdB_cc))
|
// Stall on any ongoing memory operation that
|
// Stall on any ongoing memory operation that
|
Line 1073... |
Line 1129... |
if ((alu_ce)||(div_ce)||(fpu_ce))
|
if ((alu_ce)||(div_ce)||(fpu_ce))
|
alu_reg <= opR;
|
alu_reg <= opR;
|
else if ((i_halt)&&(i_dbg_we))
|
else if ((i_halt)&&(i_dbg_we))
|
alu_reg <= i_dbg_reg;
|
alu_reg <= i_dbg_reg;
|
|
|
reg [31:0] dbg_val;
|
//
|
|
// DEBUG Register write access starts here
|
|
//
|
reg dbgv;
|
reg dbgv;
|
always @(posedge i_clk)
|
|
dbg_val <= i_dbg_data;
|
|
initial dbgv = 1'b0;
|
initial dbgv = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
dbgv <= (~i_rst)&&(~alu_ce)&&((i_halt)&&(i_dbg_we));
|
dbgv <= (~i_rst)&&(~alu_ce)&&((i_halt)&&(i_dbg_we));
|
|
reg [31:0] dbg_val;
|
|
always @(posedge i_clk)
|
|
dbg_val <= i_dbg_data;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((alu_ce)||(mem_ce))
|
if ((alu_ce)||(mem_ce))
|
alu_gie <= op_gie;
|
alu_gie <= op_gie;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((alu_ce)||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
|
if ((alu_ce)||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)
|
Line 1099... |
Line 1158... |
else if ((alu_ce)||(mem_ce))
|
else if ((alu_ce)||(mem_ce))
|
r_alu_illegal <= op_illegal;
|
r_alu_illegal <= op_illegal;
|
assign alu_illegal = (alu_illegal_op)||(r_alu_illegal);
|
assign alu_illegal = (alu_illegal_op)||(r_alu_illegal);
|
`endif
|
`endif
|
|
|
// This _almost_ is equal to (alu_ce)||(mem_ce). The only
|
|
// problem is that mem_ce is gated by the set_cond, and
|
|
// the PC will be valid independent of the set condition. Hence, this
|
|
// equals (alu_ce)||(everything in mem_ce but the set condition)
|
|
initial alu_pc_valid = 1'b0;
|
initial 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);
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
alu_pc_valid <= ((alu_ce)
|
if (i_rst)
|
||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)&&(~mem_stalled)));
|
mem_pc_valid <= 1'b0;
|
|
else
|
|
mem_pc_valid <= (mem_ce);
|
|
|
wire bus_lock;
|
wire bus_lock;
|
`ifdef OPT_PIPELINED
|
`ifdef OPT_PIPELINED
|
generate
|
generate
|
if (IMPLEMENT_LOCK != 0)
|
if (IMPLEMENT_LOCK != 0)
|
begin
|
begin
|
reg r_bus_lock;
|
reg [1:0] r_bus_lock;
|
initial r_bus_lock = 1'b0;
|
initial r_bus_lock = 2'b00;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
r_bus_lock <= 1'b0;
|
r_bus_lock <= 2'b00;
|
else if ((op_ce)&&(op_lock))
|
else if ((op_ce)&&(op_lock))
|
r_bus_lock <= 1'b1;
|
r_bus_lock <= 2'b11;
|
else if (~opvalid_mem)
|
else if ((|r_bus_lock)&&((~opvalid_mem)||(~op_ce)))
|
r_bus_lock <= 1'b0;
|
r_bus_lock <= r_bus_lock + 2'b11;
|
assign bus_lock = r_bus_lock;
|
assign bus_lock = |r_bus_lock;
|
end else begin
|
end else begin
|
assign bus_lock = 1'b0;
|
assign bus_lock = 1'b0;
|
end endgenerate
|
end endgenerate
|
`else
|
`else
|
assign bus_lock = 1'b0;
|
assign bus_lock = 1'b0;
|
Line 1166... |
Line 1229... |
// Common wires, in and out, of the arbiter
|
// Common wires, in and out, of the arbiter
|
o_wb_gbl_cyc, o_wb_lcl_cyc, o_wb_gbl_stb, o_wb_lcl_stb,
|
o_wb_gbl_cyc, o_wb_lcl_cyc, o_wb_gbl_stb, o_wb_lcl_stb,
|
o_wb_we, o_wb_addr, o_wb_data,
|
o_wb_we, o_wb_addr, o_wb_data,
|
i_wb_ack, i_wb_stall, i_wb_err);
|
i_wb_ack, i_wb_stall, i_wb_err);
|
|
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
|
//
|
//
|
//
|
//
|
//
|
// PIPELINE STAGE #5 :: Write-back results
|
// PIPELINE STAGE #5 :: Write-back results
|
//
|
//
|
//
|
//
|
Line 1185... |
Line 1256... |
// Note that the flags needed to be checked before issuing the
|
// Note that the flags needed to be checked before issuing the
|
// bus instruction, so they don't need to be checked here.
|
// bus instruction, so they don't need to be checked here.
|
// Further, alu_wr includes (set_cond), so we don't need to
|
// Further, alu_wr includes (set_cond), so we don't need to
|
// check for that here either.
|
// check for that here either.
|
`ifdef OPT_ILLEGAL_INSTRUCTION
|
`ifdef OPT_ILLEGAL_INSTRUCTION
|
assign wr_reg_ce = (~alu_illegal)&&
|
assign wr_reg_ce = (dbgv)||(~alu_illegal)&&
|
(((alu_wr)&&(~clear_pipeline)
|
(((alu_wr)&&(~clear_pipeline)
|
&&((alu_valid)||(div_valid)||(fpu_valid)))
|
&&((alu_valid)||(div_valid)||(fpu_valid)))
|
||(mem_valid));
|
||(mem_valid));
|
`else
|
`else
|
assign wr_reg_ce = ((alu_wr)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
|
assign wr_reg_ce = (dbgv)||((alu_wr)&&(~clear_pipeline))||(mem_valid)||(div_valid)||(fpu_valid);
|
`endif
|
`endif
|
// Which register shall be written?
|
// Which register shall be written?
|
// COULD SIMPLIFY THIS: by adding three bits to these registers,
|
// COULD SIMPLIFY THIS: by adding three bits to these registers,
|
// One or PC, one for CC, and one for GIE match
|
// 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
|
// Note that the alu_reg is the register to write on a divide or
|
Line 1315... |
Line 1386... |
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((i_rst)||(w_switch_to_interrupt))
|
if ((i_rst)||(w_switch_to_interrupt))
|
step <= 1'b0;
|
step <= 1'b0;
|
else if ((wr_reg_ce)&&(~alu_gie)&&(wr_reg_id[4])&&(wr_write_cc))
|
else if ((wr_reg_ce)&&(~alu_gie)&&(wr_reg_id[4])&&(wr_write_cc))
|
step <= wr_reg_vl[`CPU_STEP_BIT];
|
step <= wr_reg_vl[`CPU_STEP_BIT];
|
else if ((alu_pc_valid)&&(step)&&(gie))
|
else if (((alu_pc_valid)||(mem_pc_valid))&&(step)&&(gie))
|
step <= 1'b0;
|
step <= 1'b0;
|
|
|
// The GIE register. Only interrupts can disable the interrupt register
|
// The GIE register. Only interrupts can disable the interrupt register
|
assign w_switch_to_interrupt = (gie)&&(
|
assign w_switch_to_interrupt = (gie)&&(
|
// On interrupt (obviously)
|
// On interrupt (obviously)
|
((i_interrupt)&&(~alu_phase)&&(~bus_lock))
|
((i_interrupt)&&(~alu_phase)&&(~bus_lock))
|
// If we are stepping the CPU
|
// If we are stepping the CPU
|
||((alu_pc_valid)&&(step)&&(~alu_phase)&&(~bus_lock))
|
||(((alu_pc_valid)||(mem_pc_valid))&&(step)&&(~alu_phase)&&(~bus_lock))
|
// If we encounter a break instruction, if the break
|
// If we encounter a break instruction, if the break
|
// enable isn't set.
|
// enable isn't set.
|
||((master_ce)&&(~mem_rdbusy)&&(~div_busy)&&(~fpu_busy)
|
||((master_ce)&&(~mem_rdbusy)&&(~div_busy)&&(~fpu_busy)
|
&&(op_break)&&(~break_en))
|
&&(op_break)&&(~break_en))
|
`ifdef OPT_ILLEGAL_INSTRUCTION
|
`ifdef OPT_ILLEGAL_INSTRUCTION
|
Line 1361... |
Line 1432... |
|
|
initial trap = 1'b0;
|
initial trap = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
trap <= 1'b0;
|
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_reg_vl[`CPU_GIE_BIT])
|
&&(wr_write_cc)) // &&(wr_reg_id[4]) implied
|
&&(wr_write_cc)) // &&(wr_reg_id[4]) implied
|
trap <= 1'b1;
|
trap <= 1'b1;
|
else if (w_release_from_interrupt)
|
else if ((wr_reg_ce)&&(wr_write_cc)&&(wr_reg_id[4]))
|
trap <= 1'b0;
|
trap <= wr_reg_vl[`CPU_TRAP_BIT];
|
|
|
`ifdef OPT_ILLEGAL_INSTRUCTION
|
`ifdef OPT_ILLEGAL_INSTRUCTION
|
initial ill_err_i = 1'b0;
|
initial ill_err_i = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
ill_err_i <= 1'b0;
|
ill_err_i <= 1'b0;
|
// The debug interface can clear this bit
|
// Only the debug interface can clear this bit
|
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
|
else if ((dbgv)&&(wr_reg_id == {1'b0, `CPU_CC_REG})
|
&&(~wr_reg_vl[`CPU_ILL_BIT]))
|
&&(~wr_reg_vl[`CPU_ILL_BIT]))
|
ill_err_i <= 1'b0;
|
ill_err_i <= 1'b0;
|
else if ((alu_pc_valid)&&(alu_illegal)&&(~alu_gie))
|
else if ((alu_pc_valid)&&(alu_illegal)&&(~alu_gie))
|
ill_err_i <= 1'b1;
|
ill_err_i <= 1'b1;
|
Line 1416... |
Line 1489... |
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
ubus_err_flag <= 1'b0;
|
ubus_err_flag <= 1'b0;
|
else if (w_release_from_interrupt)
|
else if (w_release_from_interrupt)
|
ubus_err_flag <= 1'b0;
|
ubus_err_flag <= 1'b0;
|
// else if ((i_halt)&&(i_dbg_we)&&(~i_dbg_reg[4])
|
|
// &&(i_dbg_reg == {1'b1, `CPU_CC_REG})
|
|
// &&(~i_dbg_data[`CPU_BUSERR_BIT]))
|
|
// ubus_err_flag <= 1'b0;
|
|
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce)
|
else if (((~alu_gie)||(dbgv))&&(wr_reg_ce)
|
&&(~wr_reg_vl[`CPU_BUSERR_BIT])
|
&&(~wr_reg_vl[`CPU_BUSERR_BIT])
|
&&(wr_reg_id[4])&&(wr_write_cc))
|
&&(wr_reg_id[4])&&(wr_write_cc))
|
ubus_err_flag <= 1'b0;
|
ubus_err_flag <= 1'b0;
|
else if ((bus_err)&&(alu_gie))
|
else if ((bus_err)&&(alu_gie))
|
Line 1537... |
Line 1606... |
// it? Do we clear both? What if a gie instruction tries to clear
|
// it? Do we clear both? What if a gie instruction tries to clear
|
// a non-gie instruction?
|
// a non-gie instruction?
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc))
|
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc))
|
upc <= wr_reg_vl[(AW-1):0];
|
upc <= wr_reg_vl[(AW-1):0];
|
else if ((alu_gie)&&(alu_pc_valid)&&(~clear_pipeline))
|
else if ((alu_gie)&&
|
|
(((alu_pc_valid)&&(~clear_pipeline))
|
|
||(mem_pc_valid)))
|
upc <= alu_pc;
|
upc <= alu_pc;
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
ipc <= RESET_ADDRESS;
|
ipc <= RESET_ADDRESS;
|
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_pc))
|
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_pc))
|
ipc <= wr_reg_vl[(AW-1):0];
|
ipc <= wr_reg_vl[(AW-1):0];
|
else if ((~alu_gie)&&(alu_pc_valid)&&(~clear_pipeline))
|
else if ((~alu_gie)&&
|
|
(((alu_pc_valid)&&(~clear_pipeline))
|
|
||(mem_pc_valid)))
|
ipc <= alu_pc;
|
ipc <= alu_pc;
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_rst)
|
if (i_rst)
|
pf_pc <= RESET_ADDRESS;
|
pf_pc <= RESET_ADDRESS;
|
Line 1616... |
Line 1689... |
o_dbg_cc <= { o_break, bus_err, gie, sleep };
|
o_dbg_cc <= { o_break, bus_err, gie, sleep };
|
|
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
o_dbg_stall <= (i_halt)&&(
|
o_dbg_stall <= (i_halt)&&(
|
(pf_cyc)||(mem_cyc_gbl)||(mem_cyc_lcl)||(mem_busy)
|
(pf_cyc)||(mem_cyc_gbl)||(mem_cyc_lcl)||(mem_busy)
|
||((~opvalid)&&(~i_rst))
|
||((~opvalid)&&(~i_rst)&&(~dcd_illegal))
|
||((~dcdvalid)&&(~i_rst)));
|
||((~dcdvalid)&&(~i_rst)&&(~pf_illegal)));
|
|
|
//
|
//
|
//
|
//
|
// Produce accounting outputs: Account for any CPU stalls, so we can
|
// Produce accounting outputs: Account for any CPU stalls, so we can
|
// later evaluate how well we are doing.
|
// later evaluate how well we are doing.
|
Line 1632... |
Line 1705... |
assign o_i_count = (alu_pc_valid)&&(~clear_pipeline);
|
assign o_i_count = (alu_pc_valid)&&(~clear_pipeline);
|
|
|
`ifdef DEBUG_SCOPE
|
`ifdef DEBUG_SCOPE
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
o_debug <= {
|
o_debug <= {
|
i_wb_err, pf_pc[2:0], flags,
|
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,
|
op_ce, alu_ce, mem_ce,
|
//
|
//
|
master_ce, opvalid_alu, opvalid_mem,
|
master_ce, opvalid_alu, opvalid_mem,
|
//
|
//
|
Line 1644... |
Line 1718... |
mem_we,
|
mem_we,
|
// ((opvalid_alu)&&(alu_stall))
|
// ((opvalid_alu)&&(alu_stall))
|
// ||((opvalid_mem)&&(~op_pipe)&&(mem_busy))
|
// ||((opvalid_mem)&&(~op_pipe)&&(mem_busy))
|
// ||((opvalid_mem)&&( op_pipe)&&(mem_pipe_stalled)));
|
// ||((opvalid_mem)&&( op_pipe)&&(mem_pipe_stalled)));
|
// opA[23:20], opA[3:0],
|
// opA[23:20], opA[3:0],
|
gie, sleep,
|
gie, sleep, wr_reg_ce, wr_reg_vl[4:0]
|
wr_reg_ce, wr_reg_vl[4:0]
|
|
/*
|
/*
|
i_rst, master_ce, (new_pc),
|
i_rst, master_ce, (new_pc),
|
((dcd_early_branch)&&(dcdvalid)),
|
((dcd_early_branch)&&(dcdvalid)),
|
pf_valid, pf_illegal,
|
pf_valid, pf_illegal,
|
op_ce, dcd_ce, dcdvalid, dcd_stalled,
|
op_ce, dcd_ce, dcdvalid, dcd_stalled,
|
pf_cyc, pf_stb, pf_we, pf_ack, pf_stall, pf_err,
|
pf_cyc, pf_stb, pf_we, pf_ack, pf_stall, pf_err,
|
pf_pc[7:0], pf_addr[7:0]
|
pf_pc[7:0], pf_addr[7:0]
|
*/
|
*/
|
|
/*
|
|
i_wb_err, gie, alu_illegal,
|
|
(new_pc)||((dcd_early_branch)&&(~clear_pipeline)),
|
|
mem_busy,
|
|
(mem_busy)?{ (o_wb_gbl_stb|o_wb_lcl_stb), o_wb_we,
|
|
o_wb_addr[8:0] }
|
|
: { instruction[31:21] },
|
|
pf_valid, (pf_valid) ? alu_pc[14:0]
|
|
:{ pf_cyc, pf_stb, pf_pc[12:0] }
|
|
*/
|
|
/*
|
|
i_wb_err, gie, new_pc, dcd_early_branch, // 4
|
|
pf_valid, pf_cyc, pf_stb, instruction_pc[0], // 4
|
|
instruction[30:27], // 4
|
|
dcd_gie, mem_busy, o_wb_gbl_cyc, o_wb_gbl_stb, // 4
|
|
dcdvalid,
|
|
((dcd_early_branch)&&(~clear_pipeline)) // 15
|
|
? dcd_branch_pc[14:0]:pf_pc[14:0]
|
|
*/
|
};
|
};
|
`endif
|
`endif
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|