Line 1... |
Line 1... |
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Filename: pfcache2.v
|
// Filename: pfcache.v
|
//
|
//
|
// Project: Zip CPU -- a small, lightweight, RISC CPU soft core
|
// Project: Zip CPU -- a small, lightweight, RISC CPU soft core
|
//
|
//
|
// Purpose: Keeping our CPU fed with instructions, at one per clock and
|
// Purpose: Keeping our CPU fed with instructions, at one per clock and
|
// with no stalls. An unusual feature of this cache is the
|
// with no stalls. An unusual feature of this cache is the
|
Line 71... |
Line 71... |
reg [((1<<(CW-PW))-1):0] vmask;
|
reg [((1<<(CW-PW))-1):0] vmask;
|
|
|
reg [(AW-1):0] lastpc;
|
reg [(AW-1):0] lastpc;
|
reg [(CW-1):0] rdaddr;
|
reg [(CW-1):0] rdaddr;
|
reg [(AW-1):CW] tagval;
|
reg [(AW-1):CW] tagval;
|
reg [(AW-1):PW] lasttag, illegal_cache;
|
wire [(AW-1):PW] lasttag;
|
|
reg [(AW-1):PW] illegal_cache;
|
|
|
initial o_i = 32'h76_00_00_00; // A NOOP instruction
|
initial o_i = 32'h76_00_00_00; // A NOOP instruction
|
initial o_pc = 0;
|
initial o_pc = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (~r_v)
|
if (~r_v)
|
Line 88... |
Line 89... |
o_pc <= i_pc;
|
o_pc <= i_pc;
|
end
|
end
|
|
|
initial tagval = 0;
|
initial tagval = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (i_stall_n)
|
if((o_wb_cyc)&&(rdaddr[(PW-1):0]=={(PW){1'b1}})
|
|
&&(i_wb_ack)&&(~i_wb_err))
|
|
// Our tag value changes any time we finish reading a
|
|
// new cache line
|
|
tagval <= o_wb_addr[(AW-1):CW];
|
|
else if ((i_stall_n)&&(~o_wb_cyc))
|
|
// Otherwise, as long as we're not reading new stuff,
|
|
// the tag line changes any time the pipeline steps
|
|
// forwards. Our purpose here is primarily just to
|
|
// catch sudden changes. The result is that walking
|
|
// from one cache line to the next will cost a clock.
|
tagval <= tags[i_pc[(CW-1):PW]];
|
tagval <= tags[i_pc[(CW-1):PW]];
|
|
|
// i_pc will only increment when everything else isn't stalled, thus
|
// i_pc will only increment when everything else isn't stalled, thus
|
// we can set it without worrying about that. Doing this enables
|
// we can set it without worrying about that. Doing this enables
|
// us to work in spite of stalls. For example, if the next address
|
// us to work in spite of stalls. For example, if the next address
|
Line 101... |
Line 112... |
initial lastpc = 0;
|
initial lastpc = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if (((r_v)&&(i_stall_n))||(i_clear_cache)||(i_new_pc))
|
if (((r_v)&&(i_stall_n))||(i_clear_cache)||(i_new_pc))
|
lastpc <= i_pc;
|
lastpc <= i_pc;
|
|
|
initial lasttag = 0;
|
assign lasttag = lastpc[(AW-1):PW];
|
always @(posedge i_clk)
|
// initial lasttag = 0;
|
lasttag <= i_pc[(AW-1):PW];
|
// always @(posedge i_clk)
|
|
// if (((r_v)&&(i_stall_n))||(i_clear_cache)||(i_new_pc))
|
|
// lasttag <= i_pc[(AW-1):PW];
|
|
|
wire r_v_from_pc, r_v_from_last;
|
wire r_v_from_pc, r_v_from_last;
|
assign r_v_from_pc = ((i_pc[(AW-1):PW] == lasttag)
|
assign r_v_from_pc = ((i_pc[(AW-1):PW] == lasttag)
|
&&(tagval == i_pc[(AW-1):CW])
|
&&(tagval == i_pc[(AW-1):CW])
|
&&(vmask[i_pc[(CW-1):PW]]));
|
&&(vmask[i_pc[(CW-1):PW]]));
|
assign r_v_from_last = ((lastpc[(AW-1):PW] == lasttag)
|
assign r_v_from_last = (
|
&&(tagval == lastpc[(AW-1):CW])
|
//(lastpc[(AW-1):PW] == lasttag)&&
|
|
(tagval == lastpc[(AW-1):CW])
|
&&(vmask[lastpc[(CW-1):PW]]));
|
&&(vmask[lastpc[(CW-1):PW]]));
|
|
|
reg [1:0] delay;
|
reg [1:0] delay;
|
|
|
initial delay = 2'h3;
|
initial delay = 2'h3;
|
Line 153... |
Line 167... |
else
|
else
|
o_wb_addr[(PW-1):0] <= o_wb_addr[(PW-1):0]+1;
|
o_wb_addr[(PW-1):0] <= o_wb_addr[(PW-1):0]+1;
|
end
|
end
|
|
|
if (i_wb_ack)
|
if (i_wb_ack)
|
rdaddr <= rdaddr + 1;
|
|
if ((rdaddr[(PW-1):0] == {(PW){1'b1}})||(i_wb_err))
|
|
begin
|
begin
|
o_wb_cyc <= 1'b0;
|
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
|
end
|
|
|
|
if (((i_wb_ack)&&(rdaddr[(PW-1):0]=={(PW){1'b1}}))||(i_wb_err))
|
|
o_wb_cyc <= 1'b0;
|
|
|
// else if (rdaddr[(PW-1):1] == {(PW-1){1'b1}})
|
// else if (rdaddr[(PW-1):1] == {(PW-1){1'b1}})
|
// tags[lastpc[(CW-1):PW]] <= lastpc[(AW-1):CW];
|
// tags[lastpc[(CW-1):PW]] <= lastpc[(AW-1):CW];
|
|
|
end else if ((~r_v)&&(delay==0)
|
end else if ((~r_v)&&(delay==0)
|
&&((tagval != lastpc[(AW-1):CW])
|
&&((tagval != lastpc[(AW-1):CW])
|