Skip to content

Commit

Permalink
ice-v-swirl fixes, traces, additional checks
Browse files Browse the repository at this point in the history
  • Loading branch information
sylefeb committed Nov 6, 2023
1 parent 3796492 commit 0b59ca2
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 35 deletions.
2 changes: 2 additions & 0 deletions frameworks/boards/verilator/verilator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ $MAKE -f Vtop.mk -j$(nproc)
cd ..
if [[ -z "${NO_PROGRAM}" ]]; then
rm -f output.txt
./obj_dir/Vtop | tee out.log
# ./obj_dir/Vtop > out.log 2>&1
else
echo "Skipping execution."
fi
1 change: 1 addition & 0 deletions frameworks/verilator/verilator_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ int data(int addr);
void data_write(int wenable,int addr,unsigned char byte);
void set_vga_resolution(int w,int h);
int get_random();
void output_char(int c);
9 changes: 9 additions & 0 deletions frameworks/verilator/verilator_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,12 @@ int get_random()
{
return rand() ^ (rand()<<8) ^ (rand()<<16) ^ (rand()<<24);
}

void output_char(int c)
{
FILE *f = fopen("output.txt","a");
if (f != NULL) {
fputc(c,f);
fclose(f);
}
}
52 changes: 33 additions & 19 deletions projects/ice-v/CPUs/ice-v-ram.si
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ interface icev_ram_user {
unit icev_ram(
icev_ram_user mem,
$$if ICEV_USERDATA then
input uint32 user_data
input uint32 user_data,
$$end
$$if TRACE then
input uint1 trace_on,
$$end
) {

Expand Down Expand Up @@ -186,8 +189,10 @@ $$end
// instruction fetch done?
instr_trigger = reqmem_done;
$$if TRACE then
if (instr_trigger) {
trace = 1;
if (trace_on) {
if (instr_trigger) {
trace = 1;
}
}
$$end
}
Expand All @@ -213,28 +218,35 @@ $$end
}
case 3: {
// ---- LS2/commit
// may wait on RAM
uint1 instr_done = ~reqmem_pending & ~exec.working;
// ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
// wait on RAM if request pending wait on working ALU
// commit result
xregsA.wenable = ~exec.no_rd & ~reqmem_pending & ~exec.working;
// ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
// wait on RAM if request pending wait on working ALU
$$if TRACE then
if (trace & ~reqmem_pending & ~exec.working) {
__write("instr:%h (@%h) ",instr,pc<<2);
last_cycle = cycle;
if (xregsA.wenable) {
__display(" x[%d]=%h",exec.write_rd,write_back);
} else {
__display("");
if (trace_on) {
if (trace & instr_done) {
__write("@%h %h ",pc<<2,instr);
last_cycle = cycle;
if (xregsA.wenable) {
__display("x[%d]=%h",exec.write_rd,write_back);
} else {
__display("");
}
trace = 0;
}
trace = 0;
}
$$end
$$if ICEV_VERILATOR_TRACE then
// this is used to track retired instr. and compare CPUs
if (instr_done) {
__verilog("$c32(\"cpu_retires(4,\",%,\",\",%,\",\",%,\",\",%,\");\");",
pc<<2,instr,Rtype(instr).rd,write_back);
}
$$end
// prepare instruction fetch
// instruction fetch in progress
do_fetch = ~reqmem_pending & ~reset;
// ^^^^^^^^^^^^^^
// wait on RAM from load/store
do_fetch = instr_done & ~reset;
mem.addr = do_fetch ? (exec.jump ? (exec.n >> 2) : pc_plus1)
: mem.addr; // <= preserve addr if RAM is busy
mem.req_valid = do_fetch;
Expand Down Expand Up @@ -264,8 +276,10 @@ $$end
xregsB.addr = xregsA.wenable ? exec.write_rd : Rtype(instr).rs2;

$$if TRACE then
if (mem.wenable) {
__display("store @%x = %x",mem.addr<<2,mem.wdata<<{mem.byte_offset,3b000});
if (trace_on) {
if (mem.wenable) {
__display("store @%x = %x",mem.addr<<2,mem.wdata<<{mem.byte_offset,3b000});
}
}
cycle = cycle + 1;
$$end
Expand Down
43 changes: 29 additions & 14 deletions projects/ice-v/CPUs/ice-v-swirl.si
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ $$if ICEV_STALL then
// optional feature to stall the CPU (e.g. while filling a cache)
input uint1 stall_cpu,
$$end
$$if TRACE_swirl then
input uint1 trace_on,
$$end
) {

// register file, uses two BRAMs to fetch two registers at once
Expand Down Expand Up @@ -152,14 +155,13 @@ $$if TRACE_swirl then
$$end
$$if not ICEV_STALL then
uint1 stall_cpu(0); // stall disabled, never used
$$else
uint1 refetching(0); // tracks if a refetch is in progress
$$end
uint1 refetching(0); // tracks if a refetch is in progress

always {

$$if DEBUG_swirl then
uint1 debug_on = 1; // (cycle > 88430 && cycle < 90000);
uint1 debug_on = (cycle > 40885000);
$$end

// tracks whether a register was written cycle before
Expand Down Expand Up @@ -201,7 +203,8 @@ $$if ICEV_BRANCH_PRED then
jinstr = instr[ 4, 3] == 3b110;
jal = instr[2,2] == 2b11;
branch = instr[2,2] == 2b00;
bpred = jinstr & (jal|branch);
bpred = jinstr & (jal|branch) & ~refetching;
// no bpred if refetching ^^^^ cache may ping-pong
addr_a = __signed({1b0,pc[0,$addrW-1$],2b0});
addr_imm = jal ? {{12{instr[31,1]}},instr[12,8],instr[20,1],instr[21,10],1b0}
: {{20{instr[31,1]}},instr[7,1],instr[25,6],instr[8,4],1b0};
Expand Down Expand Up @@ -369,11 +372,19 @@ $$end
if (exec.store & ~bubble & ~jumping) {
// ^^^^^^ if stage 4 jumps, cancel store
// build write mask depending on SB, SH, SW
// assumes aligned, e.g. SW => next_addr[0,2] == 2
// assumes aligned SW
dmem.wenable = ( { { 2{exec.op[0,2]==2b10} },
exec.op[0,1] | exec.op[1,1], 1b1
} ) << exec.n[0,2];
}
$$if SIMULATION then
// check for unaligned loads (unsupported)
if ((exec.load & ~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);
__finish();
}
$$end
// decoder outputs to trickle down the pipeline towards stage 4
no_rd = exec.no_rd | bubble;
// ^^^^ disables data hazard in stage 2 on a bubble
Expand Down Expand Up @@ -435,13 +446,15 @@ if (debug_on) {
}
$$end
$$if TRACE_swirl then
if (instr_done) {
__write("instr:%h (@%h) ",instr,pc<<2);
last_cycle = cycle;
if (xregsA.wenable1) {
__display(" x[%d]=%h",xregsA.addr1,xregsA.wdata1);
} else {
__display("");
if (trace_on) {
if (instr_done) {
__write("@%h %h ",pc<<2,instr);
last_cycle = cycle;
if (xregsA.wenable1) {
__display("x[%d]=%h",xregsA.addr1,xregsA.wdata1);
} else {
__display("");
}
}
}
$$end
Expand Down Expand Up @@ -506,8 +519,10 @@ if (debug_on) {
}
$$end
$$if TRACE_swirl then
if ((|dmem.wenable) & ~stall_cpu) {
__display("store @%x = %x",dmem.addr<<2,dmem.wdata);
if (trace_on) {
if ((|dmem.wenable) & ~stall_cpu) {
__display("store @%x = %x",dmem.addr<<2,dmem.wdata);
}
}
$$end
xb = exec.xb;
Expand Down
18 changes: 16 additions & 2 deletions projects/ice-v/SOCs/ice-v-soc-ram.si
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@

// Address space and boot configuration
// allow for 32MB RAM addressing + 1 bit periph
$$addrW = 24
// (addressing 32bits: 2^23 x 32bits, 8MB x 4 bytes)
$$addrW = 24 -- 23 bits for addresses, 1 bit for peripheral mapping
// bit for peripheral addresses
$$periph = addrW-1
// boot address in QQSPI
Expand Down Expand Up @@ -334,6 +335,9 @@ $$if SIMULATION then
spiscreen_clk = screen_clk; spiscreen_mosi = screen_mosi; // assign pins
spiscreen_dc = screen_dc; spiscreen_resn = screen_resn;
$$end
$$end
$$if TRACE then
cpu.trace_on = reset ? 0 : cpu.trace_on;
$$end

// ---- memory mapping to peripherals: writes
Expand All @@ -345,8 +349,18 @@ $$end
// leds for activity
leds = ramio.wdata[0,5];
$$if SIMULATION then
$$if not TRACE then
__write("%c",ramio.wdata[0,8]);
// __display("==> %d",ramio.wdata);
$$else
if (ramio.wdata[31,1]) {
if (cpu.trace_on) {
__finish();
} else {
cpu.trace_on = 1;
}
}
$$end
__verilog("$c32(\"output_char(\",%,\");\");",ramio.wdata[0,8]);
$$end
// send over uart
uo.data_in_ready = 1;
Expand Down

0 comments on commit 0b59ca2

Please sign in to comment.