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

Subversion Repositories xulalx25soc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 50 to Rev 51
    Reverse comparison

Rev 50 → Rev 51

/xulalx25soc/trunk/rtl/cpu/pfcache.v
74,6 → 74,7
reg [(CW-1):0] rdaddr;
reg [(AW-1):CW] tagval;
wire [(AW-1):PW] lasttag;
reg illegal_valid;
reg [(AW-1):PW] illegal_cache;
 
initial o_i = 32'h76_00_00_00; // A NOOP instruction
95,7 → 96,7
// has been filled, but our prior attempt to do so has lead
// to a race condition, so we keep this logic simple.
if (((r_v)&&(i_stall_n))||(i_clear_cache)||(i_new_pc))
lastpc <= tags[i_pc[(CW-1):PW]];
tagval <= tags[i_pc[(CW-1):PW]];
else
tagval <= tags[lastpc[(CW-1):PW]];
 
155,7 → 156,9
o_wb_stb <= 1'b0;
end else if (o_wb_cyc)
begin
if ((o_wb_stb)&&(~i_wb_stall))
if (i_wb_err)
o_wb_stb <= 1'b0;
else if ((o_wb_stb)&&(~i_wb_stall))
begin
if (o_wb_addr[(PW-1):0] == {(PW){1'b1}})
o_wb_stb <= 1'b0;
166,8 → 169,7
if (i_wb_ack)
begin
rdaddr <= rdaddr + 1;
if (rdaddr[(PW-1):0] == {(PW){1'b1}})
tags[o_wb_addr[(CW-1):PW]] <= o_wb_addr[(AW-1):CW];
tags[o_wb_addr[(CW-1):PW]] <= o_wb_addr[(AW-1):CW];
end
 
if (((i_wb_ack)&&(rdaddr[(PW-1):0]=={(PW){1'b1}}))||(i_wb_err))
179,7 → 181,7
end else if ((~r_v)&&(delay==0)
&&((tagval != lastpc[(AW-1):CW])
||(~vmask[lastpc[(CW-1):PW]]))
&&(~o_illegal))
&&((~illegal_valid)||(lastpc[(AW-1):PW] != illegal_cache)))
begin
o_wb_cyc <= 1'b1;
o_wb_stb <= 1'b1;
204,7 → 206,6
vmask[lastpc[(CW-1):PW]] <= 1'b0;
end
 
reg illegal_valid;
initial illegal_cache = 0;
initial illegal_valid = 0;
always @(posedge i_clk)
214,7 → 215,7
illegal_valid <= 0;
end else if ((o_wb_cyc)&&(i_wb_err))
begin
illegal_cache <= lastpc[(AW-1):PW];
illegal_cache <= o_wb_addr[(AW-1):PW];
illegal_valid <= 1'b1;
end
 
224,7 → 225,6
o_illegal <= 1'b0;
else
o_illegal <= (illegal_valid)
&&(tagval == i_pc[(AW-1):CW])
&&(illegal_cache == i_pc[(AW-1):PW]);
 
endmodule
/xulalx25soc/trunk/rtl/cpu/idecode.v
89,7 → 89,7
 
 
wire [4:0] w_op;
wire w_ldi, w_mov, w_cmptst, w_ldixx, w_ALU;
wire w_ldi, w_mov, w_cmptst, w_ldixx, w_ALU, w_brev;
wire [4:0] w_dcdR, w_dcdB, w_dcdA;
wire w_dcdR_pc, w_dcdR_cc;
wire w_dcdA_pc, w_dcdA_cc;
123,6 → 123,7
assign w_op= iword[26:22];
assign w_mov = (w_op == 5'h0f);
assign w_ldi = (w_op[4:1] == 4'hb);
assign w_brev = (w_op == 5'hc);
assign w_cmptst = (w_op[4:1] == 4'h8);
assign w_ldixx = (w_op[4:1] == 4'h4);
assign w_ALU = (~w_op[4]);
189,7 → 190,7
// and writes to the PC/CC register(s).
assign w_wF = (w_cmptst)
||((w_cond[3])&&((w_dcdFP)||(w_dcdDV)
||((w_ALU)&&(~w_mov)&&(~w_ldixx)
||((w_ALU)&&(~w_mov)&&(~w_ldixx)&&(~w_brev)
&&(iword[30:28] != 3'h7))));
 
// Bottom 13 bits: no LUT's
416,6 → 417,7
o_pipe <= (r_valid)&&(i_pf_valid)&&(~i_instruction[31])
&&(w_dcdM)&&(o_M)&&(o_op[0] ==i_instruction[22])
&&(i_instruction[17:14] == o_dcdB[3:0])
&&(i_instruction[17:14] != o_dcdA[3:0])
&&(i_gie == o_gie)
&&((i_instruction[21:19]==o_cond[2:0])
||(o_cond[2:0] == 3'h0))
/xulalx25soc/trunk/rtl/cpu/zipsystem.v
591,7 → 591,7
icontrol #(8+(EXTERNAL_INTERRUPTS-9))
ctri(i_clk, cpu_reset, (ctri_sel),
sys_data, ctri_data,
alt_int_vector[(EXTERNAL_INTERRUPTS-1):0],
alt_int_vector[(EXTERNAL_INTERRUPTS-2):0],
ctri_int);
end endgenerate
 
/xulalx25soc/trunk/rtl/cpu/zipcpu.v
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)
942,11 → 995,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 → 1018,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 → 1133,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 → 1162,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
1168,8 → 1233,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 → 1260,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 → 1390,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 → 1398,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 → 1436,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;
1418,10 → 1493,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 → 1610,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 → 1620,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 → 1693,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 → 1709,9
`ifdef DEBUG_SCOPE
always @(posedge i_clk)
o_debug <= {
i_wb_err, pf_pc[2:0], flags,
/*
i_wb_err, pf_pc[2:0],
flags,
pf_valid, dcdvalid, opvalid, alu_valid, mem_valid,
op_ce, alu_ce, mem_ce,
//
1646,8 → 1723,8
// ||((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 → 1733,23
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-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.