Skip to content

Commit

Permalink
fix to cache mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
sylefeb committed Nov 7, 2023
1 parent 0b59ca2 commit 8dbd1a4
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 47 deletions.
4 changes: 2 additions & 2 deletions frameworks/boards/verilator/verilator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ cd ..
if [[ -z "${NO_PROGRAM}" ]]; then
rm -f output.txt
./obj_dir/Vtop | tee out.log
# ./obj_dir/Vtop > out.log 2>&1
# ./obj_dir/Vtop | tee out.log
./obj_dir/Vtop > out.log 2>&1
else
echo "Skipping execution."
fi
9 changes: 5 additions & 4 deletions projects/ice-v/CPUs/ice-v-swirl.si
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ $$end
always {

$$if DEBUG_swirl then
uint1 debug_on = (cycle > 40885000);
uint1 debug_on = 0; // (cycle > 40333206) && (cycle < 40339206);
$$end

// tracks whether a register was written cycle before
Expand Down Expand Up @@ -379,9 +379,9 @@ $$end
}
$$if SIMULATION then
// check for unaligned loads (unsupported)
if ((exec.load & ~bubble & ~jumping)
if ((exec.load|exec.store) & ~bubble & ~jumping
& (exec.op[0,2]==2b10) & (exec.n[0,2] != 2b00)) {
__display("[cycle %d] ERROR @%h %h, unaligned lw from @%h",cycle,pc<<2,instr,exec.n);
__display("[cycle %d] ERROR @%h %h, unaligned access (%b) @%h",cycle,pc<<2,instr,exec.store,exec.n);
__finish();
}
$$end
Expand Down Expand Up @@ -519,7 +519,8 @@ if (debug_on) {
}
$$end
$$if TRACE_swirl then
if (trace_on) {
//uint32 full = dmem.addr<<2;
if (trace_on /*|| full[8,16] == 16h14cd*/) {
if ((|dmem.wenable) & ~stall_cpu) {
__display("store @%x = %x",dmem.addr<<2,dmem.wdata);
}
Expand Down
116 changes: 75 additions & 41 deletions projects/ice-v/SOCs/swirl-cache.si
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,25 @@ interface bram_provider
input addr,
}

$$cache_line_width = 8
$$cache_line_size_words = 1<<cache_line_width
$$cache_line_size_bytes = 1<<(cache_line_width+2)
$$num_cache_lines = 1<<(14-cache_line_width)
$$num_cache_lines_w = (14-cache_line_width)
$$cache_addr_w = ramW-cache_line_width
// SPRAM can store 12384 x 32bits for one cache, 14 bits address
// ram address is split as:
//
// [ cache addr | line id | line addr ]
// <--- cache_addr_w ---> <- num_cache_lines_w -> <----- cache_line_w ----->
// <--------------------------------- ramW -------------------------------->
// ^<-------------------- 14 bits ------------------->
// |
// cache_addr_start
//
$$cache_line_w = 8 -- has to be < 14
$$cache_line_size = 1 << cache_line_w
$$num_cache_lines_w = (14 - cache_line_w)
$$num_cache_lines = 1 << num_cache_lines_w
$$cache_addr_w = ramW - 14
$$cache_addr_start = 14

$$print('<<cache configuration>> ' .. num_cache_lines
$$ .. ' cache lines of ' .. cache_line_size_words .. ' int32')
$$ .. ' cache lines of ' .. cache_line_size .. ' int32')

// --------------------------------------------------
// cache unit
Expand All @@ -93,7 +103,8 @@ unit cache(
// cache for mem1 is spram2,spram3 (2x 16 bits)
//
// each cache stores 16K x int32
// thus 2^(14 - cache_line_width) lines of 2^cache_line_width int32
// thus 2^(14 - cache_line_w) lines of 2^cache_line_w int32
//
$$for n=0,3 do
$$if SIMULATION then
simulation_spram spram$n$;
Expand All @@ -108,18 +119,18 @@ $$ init_value = '1' .. init_value
$$end
$$init_value = (cache_addr_w+1) .. 'b0' .. init_value

// cache mapping
// cache mapping, stores for each line the upper address part, and a dirty bit
bram uint$cache_addr_w+1$ cache0_lines[$num_cache_lines$] = {pad($init_value$)};
bram uint$cache_addr_w+1$ cache1_lines[$num_cache_lines$] = {pad($init_value$)};
// ^ dirty bit

$$for c=0,1 do
// determines whether requested addr match the corresponding cache line
uint$num_cache_lines_w$ line$c$_id <: mem$c$.addr[$cache_line_width$,$num_cache_lines_w$];
uint1 cache$c$_hit <:: qaddr$c$[$cache_line_width$,$cache_addr_w$]
uint$num_cache_lines_w$ line$c$_id <: mem$c$.addr[$cache_line_w$,$num_cache_lines_w$];
uint1 cache$c$_hit <:: qaddr$c$[$cache_addr_start$,$cache_addr_w$]
== :cache$c$_lines.rdata[0,$cache_addr_w$];
uint1 cache$c$_canwrite <:: (:line$c$_id == qline$c$_id)
&& :mem$c$.addr[$cache_line_width$,$cache_addr_w$]
&& :mem$c$.addr[$cache_addr_start$,$cache_addr_w$]
== :cache$c$_lines.rdata[0,$cache_addr_w$];
// registers for memory interface inputs
uint$num_cache_lines_w$ qline$c$_id(0);
Expand Down Expand Up @@ -149,7 +160,18 @@ $$end
uint1 keep_wait(0);
uint1 write_fault(0);

$$if SIMULATION then
uint1 debug_on(0);
$$end

always_before {
$$if SIMULATION then
if (mem0.addr[$ramW$,1] || mem1.addr[$ramW$,1]) {
__display("ERROR cache accessed on peripheral address");
__finish();
}
debug_on = 0; // (cycle > 40333206) && (cycle < 40339206);
$$end
/*
__display("[%d] >> cache status in: @%x|@%x q: @%x|@%x miss: %b|%b ln: %x|%x",
cycle,mem0.addr<<2,mem1.addr<<2,
Expand All @@ -172,10 +194,10 @@ $$end
// default lookup
mem0.rdata = {spram1.data_out,spram0.data_out};
mem1.rdata = {spram3.data_out,spram2.data_out};
spram0.addr = {line0_id,mem0.addr[0,$cache_line_width$]};
spram1.addr = {line0_id,mem0.addr[0,$cache_line_width$]};
spram2.addr = {line1_id,mem1.addr[0,$cache_line_width$]};
spram3.addr = {line1_id,mem1.addr[0,$cache_line_width$]};
spram0.addr = {line0_id,mem0.addr[0,$cache_line_w$]};
spram1.addr = {line0_id,mem0.addr[0,$cache_line_w$]};
spram2.addr = {line1_id,mem1.addr[0,$cache_line_w$]};
spram3.addr = {line1_id,mem1.addr[0,$cache_line_w$]};
spram0.wmask = {{2{mem0.wenable[1,1]}},{2{mem0.wenable[0,1]}}};
spram1.wmask = {{2{mem0.wenable[3,1]}},{2{mem0.wenable[2,1]}}};
spram0.wenable = (|mem0.wenable) & cache0_canwrite;
Expand Down Expand Up @@ -219,7 +241,9 @@ $$end
if (update_lines_todo) {
// there is a pending cache miss
$$if SIMULATION then
__display("[%d] => cache miss %b|%b %x|%x",cycle,~cache0_hit,~cache1_hit,qaddr0<<2,qaddr1<<2);
if (debug_on) {
__display("[%d] => cache miss %b|%b %x|%x",cycle,~cache0_hit,~cache1_hit,qaddr0<<2,qaddr1<<2);
}
$$end
// if line is dirty, store back
// vvvvv start by cache0, then cache1
Expand All @@ -228,15 +252,17 @@ $$end
if (line_dirty) {
// store back line as it was written to
uint$ramW$ storeAddr =
~cache0_hit ? {cache0_lines.rdata,$cache_line_width$b0}
: {cache1_lines.rdata,$cache_line_width$b0};
uint$cache_line_width+2+1$ n = 0;
~cache0_hit ? {cache0_lines.rdata[0,$cache_addr_w$],qline0_id,$cache_line_w$b0}
: {cache1_lines.rdata[0,$cache_addr_w$],qline1_id,$cache_line_w$b0};
uint$cache_line_w+2+1$ n = 0;
$$if SIMULATION then
__display("[%d] => [cache %b] writing at @%x from line %d",cycle,cache0_hit,storeAddr,~cache0_hit ? qline0_id : qline1_id);
if (debug_on) {
__display("[%d] => [cache %b] writing at @%x from line %d",cycle,cache0_hit,storeAddr<<2,~cache0_hit ? qline0_id : qline1_id);
}
$$end
// write start addr
ram.addr = {storeAddr,2b00};
while (~n[$cache_line_width+2$,1]) {
while (~n[$cache_line_w+2$,1]) {
// maintain write status
ram.in_ready = 1;
ram.wenable = 1;
Expand All @@ -248,51 +274,59 @@ $$end
: {spram3.data_out,spram2.data_out} >> {n[0,2],3b0};
// next?
if (reg_ram_wstream) {
$$if SIMULATION then
//uint32 full = ram.addr + n;
//if (full[8,16] == 16h14cd || debug_on) {
// __display("store @%x = %x (cache %b, line %d, cycle %d)",full,ram.wdata,cache0_hit,~cache0_hit ? qline0_id : qline1_id,cycle);
//}
// __write("%x,",ram.wdata);
$$end
// next
n = n + 1;
}
// read in cache 0
spram0.addr = {qline0_id,n[2,$cache_line_width$]};
spram1.addr = {qline0_id,n[2,$cache_line_width$]};
spram0.addr = {qline0_id,n[2,$cache_line_w$]};
spram1.addr = {qline0_id,n[2,$cache_line_w$]};
// read in cache 1
spram2.addr = {qline1_id,n[2,$cache_line_width$]};
spram3.addr = {qline1_id,n[2,$cache_line_width$]};
spram2.addr = {qline1_id,n[2,$cache_line_w$]};
spram3.addr = {qline1_id,n[2,$cache_line_w$]};
}
// __display(" ");
++: // this one cycle pause is needed before starting to read, otherwise
// data_next from the write remains visible to the read (latencies)
}
// fetch new line
uint$ramW$ fetchAddr =
~cache0_hit ? {qaddr0[$cache_line_width$,$cache_addr_w$],
$cache_line_width$b0}
: {qaddr1[$cache_line_width$,$cache_addr_w$],
$cache_line_width$b0};
uint$cache_line_width+2+1$ n = 0;
~cache0_hit ? {qaddr0[$cache_line_w$,$ramW-cache_addr_w$],
$cache_line_w$b0}
: {qaddr1[$cache_line_w$,$ramW-cache_addr_w$],
$cache_line_w$b0};
uint$cache_line_w+2+1$ n = 0;
$$if SIMULATION then
__display("[%d] +> cache miss %b|%b %x|%x",cycle,~cache0_hit,~cache1_hit,qaddr0<<2,qaddr1<<2);
__display("[%d] => [cache %b] fetching from @%x in line %d",cycle,cache0_hit,fetchAddr<<2,~cache0_hit ? qline0_id : qline1_id);
// __display("[%d] +> cache miss %b|%b %x|%x",cycle,~cache0_hit,~cache1_hit,qaddr0<<2,qaddr1<<2);
if (debug_on) {
__display("[%d] => [cache %b] fetching from @%x in line %d",cycle,cache0_hit,fetchAddr<<2,~cache0_hit ? qline0_id : qline1_id);
}
$$end
ram.addr = {fetchAddr,2b00};
while (~n[$cache_line_width+2$,1]) {
while (~n[$cache_line_w+2$,1]) {
ram.in_ready = 1;
if (reg_ram_datanext) {
uint4 wmask = 2b11 << {n[0,1],1b0};
uint16 wdata = reg_ram_rdata << {n[0,1],3b0};
// __write("%x,", reg_ram_rdata);
// cache 0
spram0.addr = {qline0_id,n[2,$cache_line_width$]};
spram1.addr = {qline0_id,n[2,$cache_line_width$]};
spram0.addr = {qline0_id,n[2,$cache_line_w$]};
spram1.addr = {qline0_id,n[2,$cache_line_w$]};
spram0.data_in = wdata;
spram1.data_in = wdata;
spram0.wmask = wmask;
spram1.wmask = wmask;
spram0.wenable = ~cache0_hit & ~n[1,1];
spram1.wenable = ~cache0_hit & n[1,1];
// cache 1
spram2.addr = {qline1_id,n[2,$cache_line_width$]};
spram3.addr = {qline1_id,n[2,$cache_line_width$]};
spram2.addr = {qline1_id,n[2,$cache_line_w$]};
spram3.addr = {qline1_id,n[2,$cache_line_w$]};
spram2.data_in = wdata;
spram3.data_in = wdata;
spram2.wmask = wmask;
Expand All @@ -306,10 +340,10 @@ $$end
// __display(" ");
// update cache register
if (~cache0_hit) {
cache0_lines.wdata = {1b0,qaddr0[$cache_line_width$,$cache_addr_w$]};
cache0_lines.wdata = {1b0,qaddr0[$cache_addr_start$,$cache_addr_w$]};
cache0_lines.wenable = 1;
} else {
cache1_lines.wdata = {1b0,qaddr1[$cache_line_width$,$cache_addr_w$]};
cache1_lines.wdata = {1b0,qaddr1[$cache_addr_start$,$cache_addr_w$]};
cache1_lines.wenable = 1;
}
keep_wait = 1; // IMPORTANT: keeps wait high during bram transaction
Expand All @@ -321,7 +355,7 @@ $$end
write_cycle = 1; // keeps wait high while write to cache line occurs
// TODO: only if indeed writing?
$$if SIMULATION then
__display("[%d] cache done.",cycle);
// __display("[%d] cache done.",cycle);
$$end
} else {
// if no cache miss, maintain dirty flag
Expand Down

0 comments on commit 8dbd1a4

Please sign in to comment.