Line 72... |
Line 72... |
|
|
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;
|
wire [(AW-1):PW] lasttag;
|
wire [(AW-1):PW] lasttag;
|
|
reg illegal_valid;
|
reg [(AW-1):PW] illegal_cache;
|
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)
|
Line 93... |
Line 94... |
always @(posedge i_clk)
|
always @(posedge i_clk)
|
// It may be possible to recover a clock once the cache line
|
// It may be possible to recover a clock once the cache line
|
// has been filled, but our prior attempt to do so has lead
|
// has been filled, but our prior attempt to do so has lead
|
// to a race condition, so we keep this logic simple.
|
// to a race condition, so we keep this logic simple.
|
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 <= tags[i_pc[(CW-1):PW]];
|
tagval <= tags[i_pc[(CW-1):PW]];
|
else
|
else
|
tagval <= tags[lastpc[(CW-1):PW]];
|
tagval <= tags[lastpc[(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
|
Line 153... |
Line 154... |
begin
|
begin
|
o_wb_cyc <= 1'b0;
|
o_wb_cyc <= 1'b0;
|
o_wb_stb <= 1'b0;
|
o_wb_stb <= 1'b0;
|
end else if (o_wb_cyc)
|
end else if (o_wb_cyc)
|
begin
|
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
|
begin
|
if (o_wb_addr[(PW-1):0] == {(PW){1'b1}})
|
if (o_wb_addr[(PW-1):0] == {(PW){1'b1}})
|
o_wb_stb <= 1'b0;
|
o_wb_stb <= 1'b0;
|
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)
|
begin
|
begin
|
rdaddr <= rdaddr + 1;
|
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))
|
if (((i_wb_ack)&&(rdaddr[(PW-1):0]=={(PW){1'b1}}))||(i_wb_err))
|
o_wb_cyc <= 1'b0;
|
o_wb_cyc <= 1'b0;
|
Line 177... |
Line 179... |
// 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])
|
||(~vmask[lastpc[(CW-1):PW]]))
|
||(~vmask[lastpc[(CW-1):PW]]))
|
&&(~o_illegal))
|
&&((~illegal_valid)||(lastpc[(AW-1):PW] != illegal_cache)))
|
begin
|
begin
|
o_wb_cyc <= 1'b1;
|
o_wb_cyc <= 1'b1;
|
o_wb_stb <= 1'b1;
|
o_wb_stb <= 1'b1;
|
o_wb_addr <= { lastpc[(AW-1):PW], {(PW){1'b0}} };
|
o_wb_addr <= { lastpc[(AW-1):PW], {(PW){1'b0}} };
|
rdaddr <= { lastpc[(CW-1):PW], {(PW){1'b0}} };
|
rdaddr <= { lastpc[(CW-1):PW], {(PW){1'b0}} };
|
Line 202... |
Line 204... |
vmask[rdaddr[(CW-1):PW]] <= 1'b1;
|
vmask[rdaddr[(CW-1):PW]] <= 1'b1;
|
if ((~r_v)&&(tagval != lastpc[(AW-1):CW])&&(delay == 0))
|
if ((~r_v)&&(tagval != lastpc[(AW-1):CW])&&(delay == 0))
|
vmask[lastpc[(CW-1):PW]] <= 1'b0;
|
vmask[lastpc[(CW-1):PW]] <= 1'b0;
|
end
|
end
|
|
|
reg illegal_valid;
|
|
initial illegal_cache = 0;
|
initial illegal_cache = 0;
|
initial illegal_valid = 0;
|
initial illegal_valid = 0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((i_rst)||(i_clear_cache))
|
if ((i_rst)||(i_clear_cache))
|
begin
|
begin
|
illegal_cache <= 0;
|
illegal_cache <= 0;
|
illegal_valid <= 0;
|
illegal_valid <= 0;
|
end else if ((o_wb_cyc)&&(i_wb_err))
|
end else if ((o_wb_cyc)&&(i_wb_err))
|
begin
|
begin
|
illegal_cache <= lastpc[(AW-1):PW];
|
illegal_cache <= o_wb_addr[(AW-1):PW];
|
illegal_valid <= 1'b1;
|
illegal_valid <= 1'b1;
|
end
|
end
|
|
|
initial o_illegal = 1'b0;
|
initial o_illegal = 1'b0;
|
always @(posedge i_clk)
|
always @(posedge i_clk)
|
if ((i_rst)||(i_clear_cache))
|
if ((i_rst)||(i_clear_cache))
|
o_illegal <= 1'b0;
|
o_illegal <= 1'b0;
|
else
|
else
|
o_illegal <= (illegal_valid)
|
o_illegal <= (illegal_valid)
|
&&(tagval == i_pc[(AW-1):CW])
|
|
&&(illegal_cache == i_pc[(AW-1):PW]);
|
&&(illegal_cache == i_pc[(AW-1):PW]);
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|