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 |
|