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

Subversion Repositories zipcpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 131 to Rev 132
    Reverse comparison

Rev 131 → Rev 132

/zipcpu/trunk/rtl/core/zipcpu.v
137,7 → 137,7
parameter RESET_ADDRESS=32'h0100000, ADDRESS_WIDTH=24,
LGICACHE=6;
`ifdef OPT_MULTIPLY
parameter IMPLEMENT_MPY = 1;
parameter IMPLEMENT_MPY = `OPT_MULTIPLY;
`else
parameter IMPLEMENT_MPY = 0;
`endif
284,7 → 284,7
wire [13:0] opFl;
reg [5:0] r_opF;
wire [7:0] opF;
wire op_ce, op_phase;
wire op_ce, op_phase, op_pipe;
// Some pipeline control wires
`ifdef OPT_PIPELINED
reg opA_alu, opA_mem;
304,7 → 304,7
//
//
reg [(AW-1):0] alu_pc;
reg alu_pc_valid;
reg alu_pc_valid, mem_pc_valid;
wire alu_phase;
wire alu_ce, alu_stall;
wire [31:0] alu_result;
608,9 → 608,9
`endif
 
`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
// two valid adjacent instructions
// Both must be memory instructions
622,7 → 622,10
// calculated in the instruction decoder.
always @(posedge i_clk)
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
 
//
633,6 → 636,55
assign w_opA = regset[dcdA];
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;
generate
if (AW < 32)
662,7 → 714,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_cpu_info, w_opA[22:14], (dcdA[4])?w_uflags:w_iflags };
else
r_opA <= w_opA;
`ifdef OPT_PIPELINED
688,7 → 740,8
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_cpu_info, w_opB[22:14], // w_opB[31:14],
(dcdB[4])?w_uflags:w_iflags}
: w_opB)));
 
always @(posedge i_clk)
816,10 → 869,8
always @(posedge i_clk)
if (i_rst)
r_op_lock <= 1'b0;
else if ((op_ce)&&(dcd_lock))
r_op_lock <= 1'b1;
else if ((op_ce)||(clear_pipeline))
r_op_lock <= 1'b0;
else if (op_ce)
r_op_lock <= (dcd_lock)&&(~clear_pipeline);
assign op_lock = r_op_lock;
 
end else begin
942,11 → 993,14
// 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))
||(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
962,8 → 1016,10
// following each other constitutes a
// fairly unusualy code structure.)
//
((~dcd_zI)&&(opR == dcdB)&&(opR_wr))
// &&(opR != { op_gie, `CPU_PC_REG } )
((~dcd_zI)&&(
((opR == dcdB)&&(opR_wr))
||(((opvalid_mem)||(mem_rdbusy))
&&(op_pipe))))
// Stall following any instruction that will
// set the flags, if we're going to need the
// flags (CC) register for opB.
1075,14 → 1131,17
else if ((i_halt)&&(i_dbg_we))
alu_reg <= i_dbg_reg;
 
reg [31:0] dbg_val;
//
// DEBUG Register write access starts here
//
reg dbgv;
always @(posedge i_clk)
dbg_val <= i_dbg_data;
initial dbgv = 1'b0;
always @(posedge i_clk)
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)
if ((alu_ce)||(mem_ce))
alu_gie <= op_gie;
always @(posedge i_clk)
1101,14 → 1160,18
assign alu_illegal = (alu_illegal_op)||(r_alu_illegal);
`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 mem_pc_valid = 1'b0;
always @(posedge i_clk)
alu_pc_valid <= ((alu_ce)
||((master_ce)&&(opvalid_mem)&&(~clear_pipeline)&&(~mem_stalled)));
if (i_rst)
alu_pc_valid <= 1'b0;
else
alu_pc_valid <= (alu_ce);
always @(posedge i_clk)
if (i_rst)
mem_pc_valid <= 1'b0;
else
mem_pc_valid <= (mem_ce);
 
wire bus_lock;
`ifdef OPT_PIPELINED
1115,16 → 1178,16
generate
if (IMPLEMENT_LOCK != 0)
begin
reg r_bus_lock;
initial r_bus_lock = 1'b0;
reg [1:0] r_bus_lock;
initial r_bus_lock = 2'b00;
always @(posedge i_clk)
if (i_rst)
r_bus_lock <= 1'b0;
r_bus_lock <= 2'b00;
else if ((op_ce)&&(op_lock))
r_bus_lock <= 1'b1;
else if (~opvalid_mem)
r_bus_lock <= 1'b0;
assign bus_lock = r_bus_lock;
r_bus_lock <= 2'b11;
else if ((|r_bus_lock)&&((~opvalid_mem)||(~op_ce)))
r_bus_lock <= r_bus_lock + 2'b11;
assign bus_lock = |r_bus_lock;
end else begin
assign bus_lock = 1'b0;
end endgenerate
1168,8 → 1231,16
o_wb_we, o_wb_addr, o_wb_data,
i_wb_ack, i_wb_stall, i_wb_err);
 
 
 
//
//
//
//
//
//
//
//
// PIPELINE STAGE #5 :: Write-back results
//
//
1187,12 → 1258,12
// 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)&&
assign wr_reg_ce = (dbgv)||(~alu_illegal)&&
(((alu_wr)&&(~clear_pipeline)
&&((alu_valid)||(div_valid)||(fpu_valid)))
||(mem_valid));
`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
// Which register shall be written?
// COULD SIMPLIFY THIS: by adding three bits to these registers,
1317,7 → 1388,7
step <= 1'b0;
else if ((wr_reg_ce)&&(~alu_gie)&&(wr_reg_id[4])&&(wr_write_cc))
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;
 
// The GIE register. Only interrupts can disable the interrupt register
1325,7 → 1396,7
// On interrupt (obviously)
((i_interrupt)&&(~alu_phase)&&(~bus_lock))
// 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
// enable isn't set.
||((master_ce)&&(~mem_rdbusy)&&(~div_busy)&&(~fpu_busy)
1363,11 → 1434,13
always @(posedge i_clk)
if (i_rst)
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])
&&(wr_write_cc)) // &&(wr_reg_id[4]) implied
trap <= 1'b1;
else if (w_release_from_interrupt)
trap <= 1'b0;
else if ((wr_reg_ce)&&(wr_write_cc)&&(wr_reg_id[4]))
trap <= wr_reg_vl[`CPU_TRAP_BIT];
 
`ifdef OPT_ILLEGAL_INSTRUCTION
initial ill_err_i = 1'b0;
1374,7 → 1447,7
always @(posedge i_clk)
if (i_rst)
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})
&&(~wr_reg_vl[`CPU_ILL_BIT]))
ill_err_i <= 1'b0;
1418,10 → 1491,6
ubus_err_flag <= 1'b0;
else if (w_release_from_interrupt)
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)
&&(~wr_reg_vl[`CPU_BUSERR_BIT])
&&(wr_reg_id[4])&&(wr_write_cc))
1539,7 → 1608,9
always @(posedge i_clk)
if ((wr_reg_ce)&&(wr_reg_id[4])&&(wr_write_pc))
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;
 
always @(posedge i_clk)
1547,7 → 1618,9
ipc <= RESET_ADDRESS;
else if ((wr_reg_ce)&&(~wr_reg_id[4])&&(wr_write_pc))
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;
 
always @(posedge i_clk)
1618,8 → 1691,8
always @(posedge i_clk)
o_dbg_stall <= (i_halt)&&(
(pf_cyc)||(mem_cyc_gbl)||(mem_cyc_lcl)||(mem_busy)
||((~opvalid)&&(~i_rst))
||((~dcdvalid)&&(~i_rst)));
||((~opvalid)&&(~i_rst)&&(~dcd_illegal))
||((~dcdvalid)&&(~i_rst)&&(~pf_illegal)));
 
//
//
1634,7 → 1707,8
`ifdef DEBUG_SCOPE
always @(posedge i_clk)
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,
op_ce, alu_ce, mem_ce,
//
1646,8 → 1720,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_reg_vl[4:0]
/*
i_rst, master_ce, (new_pc),
((dcd_early_branch)&&(dcdvalid)),
1656,6 → 1729,25
pf_cyc, pf_stb, pf_we, pf_ack, pf_stall, pf_err,
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

powered by: WebSVN 2.1.0

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