Skip to content

Commit 94bd03a

Browse files
committed
fix: pc improperly clamped in ALU address computations (#286)
1 parent 3b7c556 commit 94bd03a

File tree

8 files changed

+32
-30
lines changed

8 files changed

+32
-30
lines changed

projects/ice-v/CPUs/ice-v-conveyor.si

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ $$end
143143
// flag register being written
144144
written_regs_ins = {31b0,has_rd & ~bubble} << Rtype(rom.rdata).rd;
145145
$$if DEBUG_conveyor then
146-
__display("[1] instr: %x @%x (bubble:%b refetch:%b alu:%b alu_was:%b)",instr,pc<<2,bubble,refetch,exec.working,alu_was_working);
146+
__display("[1] instr: %x @%x (bubble:%b refetch:%b alu:%b alu_was:%b)",instr,{pc,2b00},bubble,refetch,exec.working,alu_was_working);
147147
$$end
148148
// remember ALU was just busy
149149
alu_was_working vv= exec.working ? 3b100 : (alu_was_working>>1);
@@ -157,7 +157,7 @@ $$end
157157
// give instruction, pc and registers to decoder+ALU
158158
instr = bubble ? exec.instr : instr;
159159
$$if DEBUG_conveyor then
160-
__display("[2] instr: %x @%x (bubble:%b)",instr,pc<<2,bubble);
160+
__display("[2] instr: %x @%x (bubble:%b)",instr,{pc,2b00},bubble);
161161
$$end
162162
$$if SIMULATION then
163163
// for correct PC display, otherwise not required
@@ -176,7 +176,7 @@ $$end
176176
// start a bubble on refectch or ALU busy, resume when ALU stops being busy
177177
bubble = (bubble & ~alu_was_working[2,1]) | refetch | exec.working;
178178
$$if DEBUG_conveyor then
179-
__display("[3] instr: %x @%x (bubble:%b)",instr,pc<<2,bubble);
179+
__display("[3] instr: %x @%x (bubble:%b)",instr,{pc,2b00},bubble);
180180
$$end
181181
// memory address from which to load/store
182182
mem.addr = (exec.n >> 2);
@@ -222,10 +222,10 @@ $$end
222222
xregsA.wdata1 = load ? loaded : write_back;
223223
$$if DEBUG_conveyor then
224224
__display("[4] instr: %x @%x (bubble:%b refetch:%b), loaded:%x, alu_n:%x",
225-
instr,pc<<2,bubble,refetch,loaded,alu_n);
225+
instr,{pc,2b00},bubble,refetch,loaded,alu_n);
226226
if (~bubble & ~refetch) {
227227
__display("[4] ++++ %x (@%x) jump %b, wreg:[%d]=%x (%b)",
228-
instr,pc<<2,jump,Rtype(instr).rd,xregsA.wdata1,xregsA.wenable1);
228+
instr,{pc,2b00},jump,Rtype(instr).rd,xregsA.wdata1,xregsA.wenable1);
229229
}
230230
$$end
231231
$$if SIMULATION then
@@ -235,7 +235,7 @@ $$if ICEV_VERILATOR_TRACE then
235235
// this is used by SOCs/ice-v-cmp, to track retired instr. and compare CPUs
236236
if (instr_done) {
237237
__verilog("$c32(\"cpu_retires(2,\",%,\",\",%,\",\",%,\",\",%,\");\");",
238-
pc<<2,instr,xregsA.wenable1?Rtype(instr).rd:0,xregsA.wdata1);
238+
{pc,2b00},instr,xregsA.wenable1?Rtype(instr).rd:0,xregsA.wdata1);
239239
}
240240
$$end
241241
$$if TRACE_conveyor then
@@ -244,7 +244,7 @@ $$if TRACE_conveyor then
244244
}
245245
if (trace_on) {
246246
if (instr_done) {
247-
__write("@%h %h ",pc<<2,instr);
247+
__write("@%h %h ",{pc,2b00},instr);
248248
if (xregsA.wenable1) {
249249
__display("x[%d]=%h",Rtype(instr).rd,xregsA.wdata1);
250250
} else {
@@ -337,7 +337,7 @@ unit decode_and_ALU_conveyor(
337337
uint1 aluShift <: (IntImm | IntReg) & op[0,2] == 2b01; // shift requested
338338

339339
// ==== select next address adder first input
340-
int$addrW+3$ addr_a <: pcOrReg ? __signed({1b0,pc[0,$addrW-2$],2b0}) : xa;
340+
int$addrW+3$ addr_a <: pcOrReg ? __signed({1b0,pc,2b0}) : xa;
341341
// ==== select ALU second input
342342
int32 b <: regOrImm ? (xb) : imm_i;
343343

projects/ice-v/CPUs/ice-v-dual-fermata.si

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ $$if ICEV_MULDIV then
9999
$$end
100100

101101
// ==== select next address adder first input
102-
int$addrW+3$ addr_a <: pcOrReg ? __signed({1b0,pc[0,$addrW-1$],2b0}) : xa;
102+
int$addrW+3$ addr_a <: pcOrReg ? __signed({1b0,pc,2b0}) : xa;
103103
// ==== select ALU second input
104104
int32 b <: regOrImm ? (xb) : imm_i;
105105

projects/ice-v/CPUs/ice-v-dual.si

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ $$end
101101
$$end
102102

103103
// ==== select next address adder first input
104-
int$addrW+3$ addr_a = pcOrReg ? __signed({1b0,pc[0,$addrW-1$],2b0}) : xa;
104+
int$addrW+3$ addr_a = pcOrReg ? __signed({1b0,pc,2b0}) : xa;
105105
// ==== select ALU second input
106106
int32 b = regOrImm ? (xb) : imm_i;
107107

projects/ice-v/CPUs/ice-v-swirl.si

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ $$end
194194
{ // ==== stage 1 ==========================================================
195195
$$if DEBUG_swirl then
196196
if (debug_on) {
197-
__display("[1] cycle:%d reset:%b stall_cpu:%b refetch:%b refetch_addr:%x refetching:%b pc:%x",cycle,reset,stall_cpu,refetch,refetch_addr<<2,refetching,pc<<2);
197+
__display("[1] cycle:%d reset:%b stall_cpu:%b refetch:%b refetch_addr:%x refetching:%b pc:%x",cycle,reset,stall_cpu,refetch,refetch_addr<<2,refetching,{pc,2b00});
198198
__display("[1] cycle:%d imem.addr:%x imem.rdata:%x dmem.addr:%x dmem.rdata:%x",cycle,imem.addr<<2,imem.rdata,dmem.addr<<2,dmem.rdata);
199199
}
200200
$$end
@@ -228,9 +228,9 @@ $$if DEBUG_swirl then
228228
if (debug_on) {
229229
if (~stall_cpu | on_stall) {
230230
__display("[1] cycle:%d instr: %x @%x (bubble:%b reset:%b refetch:%b hold:%b stall_cpu:%b alu_busy:%b rs1 %d rs2 %d)",
231-
cycle,instr,pc<<2,bubble,reset,refetch,hold,stall_cpu,exec.working,xregsA.addr0,xregsB.addr0);
231+
cycle,instr,{pc,2b00},bubble,reset,refetch,hold,stall_cpu,exec.working,xregsA.addr0,xregsB.addr0);
232232
if (bpred) {
233-
__display("[1] pc @%x following branch to @%x",pc<<2,imem.addr<<2);
233+
__display("[1] pc @%x following branch to @%x",{pc,2b00},imem.addr<<2);
234234
}
235235
}
236236
}
@@ -308,7 +308,7 @@ $$end
308308
$$if DEBUG_swirl then
309309
if (debug_on) {
310310
if (~stall_cpu | on_stall) {
311-
__display("[2] instr: %x @%x (bubble:%b bpred:%b) rA(%d):%x rB(%d):%x",instr,pc<<2,bubble,bpred,Rtype(instr).rs1,xregsA.rdata0,Rtype(instr).rs2,xregsB.rdata0);
311+
__display("[2] instr: %x @%x (bubble:%b bpred:%b) rA(%d):%x rB(%d):%x",instr,{pc,2b00},bubble,bpred,Rtype(instr).rs1,xregsA.rdata0,Rtype(instr).rs2,xregsB.rdata0);
312312
}
313313
}
314314
$$end
@@ -379,7 +379,7 @@ $$end
379379
$$if DEBUG_swirl then
380380
if (debug_on) {
381381
if (~stall_cpu | on_stall) {
382-
__display("[3] instr: %x @%x (bubble:%b bpred:%b exec.r:%d)",instr,pc<<2,bubble,bpred,exec.r);
382+
__display("[3] instr: %x @%x (bubble:%b bpred:%b exec.r:%d)",instr,{pc,2b00},bubble,bpred,exec.r);
383383
}
384384
}
385385
$$end
@@ -407,7 +407,7 @@ $$end
407407
$$if DEBUG_swirl then
408408
if (debug_on) {
409409
if (~stall_cpu | on_stall) {
410-
__display("[4] instr: %x @%x (bubble:%b bpred:%b alu_r:%d)",instr,pc<<2,bubble,bpred,alu_r);
410+
__display("[4] instr: %x @%x (bubble:%b bpred:%b alu_r:%d)",instr,{pc,2b00},bubble,bpred,alu_r);
411411
}
412412
}
413413
$$end
@@ -440,7 +440,7 @@ $$if SIMULATION then
440440
// check for unaligned loads (unsupported)
441441
if ((load|store) & ~bubble & ~jumping
442442
& (op[0,2]==2b10) & (alu_n[0,2] != 2b00)) {
443-
__display("[cycle %d] ERROR @%h %h, unaligned access (%b) @%h",cycle,pc<<2,instr,store,alu_n);
443+
__display("[cycle %d] ERROR @%h %h, unaligned access (%b) @%h",cycle,{pc,2b00},instr,store,alu_n);
444444
__finish();
445445
}
446446
$$end
@@ -473,16 +473,16 @@ $$if ICEV_VERILATOR_TRACE then
473473
// this is used by SOCs/ice-v-cmp, to track retired instr. and compare CPUs
474474
if (instr_done) {
475475
__verilog("$c32(\"cpu_retires(3,\",%,\",\",%,\",\",%,\",\",%,\");\");",
476-
pc<<2,instr,xregsA.wenable1?Rtype(instr).rd:0,xregsA.wdata1);
476+
{pc,2b00},instr,xregsA.wenable1?Rtype(instr).rd:0,xregsA.wdata1);
477477
}
478478
$$end
479479
$$if DEBUG_swirl then
480480
if (debug_on) {
481481
if (~stall_cpu | on_stall) {
482-
__display("[5] instr: %x @%x (bubble:%b jump:%b bpred:%b load:%b alu_r:%d) nretired:%d",instr,pc<<2,bubble,jump,bpred,load,alu_r,nretired);
482+
__display("[5] instr: %x @%x (bubble:%b jump:%b bpred:%b load:%b alu_r:%d) nretired:%d",instr,{pc,2b00},bubble,jump,bpred,load,alu_r,nretired);
483483
if (instr_done) {
484484
__display("[5] ++++ %x (@%x) jump %b, wreg:[%d]=%x (%b) nretired:%d",
485-
instr,pc<<2,jump,Rtype(instr).rd,xregsA.wdata1,xregsA.wenable1,nretired);
485+
instr,{pc,2b00},jump,Rtype(instr).rd,xregsA.wdata1,xregsA.wenable1,nretired);
486486
}
487487
}
488488
if (xregsA.wenable1) {
@@ -498,7 +498,7 @@ $$end
498498
$$if TRACE_swirl then
499499
if (trace_on) {
500500
if (instr_done) {
501-
__write("@%h %h ",pc<<2,instr);
501+
__write("@%h %h ",{pc,2b00},instr);
502502
last_cycle = cycle;
503503
if (xregsA.wenable1) {
504504
__display("x[%d]=%h",xregsA.addr1,xregsA.wdata1);
@@ -537,7 +537,7 @@ $$if DEBUG_swirl then
537537
if (debug_on) {
538538
if (~stall_cpu | on_stall) {
539539
if (bpred & ~refetch) {
540-
__display("[5] pc @%x branch predicted towards @%x (jump %b)",pc<<2,alu_n,jump);
540+
__display("[5] pc @%x branch predicted towards @%x (jump %b)",{pc,2b00},alu_n,jump);
541541
}
542542
if (refetch) {
543543
__display("[5] REFETCH to @%x (stall_cpu %b jump %b bpred %b)",refetch_addr<<2,stall_cpu,jump,bpred);
@@ -584,11 +584,11 @@ $$end
584584
xregsB.addr1 = xregsA.addr1;
585585
$$if SIMULATION then
586586
if (xregsA_conflict_possible & xa_regR & ~stage2_bubble) {
587-
__display("[cycle %d] ERROR reading from a written register (A) @%h",cycle,pc<<2);
587+
__display("[cycle %d] ERROR reading from a written register (A) @%h",cycle,{pc,2b00});
588588
__finish();
589589
}
590590
if (xregsB_conflict_possible & xb_regR & ~stage2_bubble & has_rs2) {
591-
__display("[cycle %d] ERROR reading from a written register (B) @%h",cycle,pc<<2);
591+
__display("[cycle %d] ERROR reading from a written register (B) @%h",cycle,{pc,2b00});
592592
__finish();
593593
}
594594
$$end
@@ -664,7 +664,7 @@ $$if ICEV_MULDIV then
664664
div32 div<reginputs>;
665665
$$end
666666
// ==== select next address adder first input
667-
int$addrW+3$ addr_a <: pcOrReg ? __signed({1b0,pc[0,$addrW-1$],2b0}) : xa;
667+
int$addrW+3$ addr_a <: pcOrReg ? __signed({1b0,pc,2b0}) : xa;
668668
// ==== select ALU second input
669669
int32 b <: regOrImm ? (xb) : imm_i;
670670
// ==== allows to do subtraction and all comparisons with a single adder

projects/ice-v/CPUs/ice-v.si

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ unit execute(
5656
uint1 sub = IntReg & Rtype(instr).sign; // subtract
5757
uint1 aluShift = (IntImm | IntReg) & op[0,2] == 2b01; // shift requested
5858
// ==== select next address adder first input
59-
int32 addr_a = pcOrReg ? __signed({1b0,pc[0,$addrW-2$],2b0}) : xa;
59+
int32 addr_a = pcOrReg ? __signed({1b0,pc,2b0}) : xa;
6060
// ==== select ALU second input
6161
int32 b = regOrImm ? (xb) : imm_i;
6262
// ==== allows to do subtraction and all comparisons with a single adder
@@ -224,7 +224,7 @@ unit rv32i_cpu(bram_port mem) {
224224
$$if ICEV_VERILATOR_TRACE then
225225
// this is used by SOCs/ice-v-cmp, to track retired instr. and compare CPUs
226226
__verilog("$c32(\"cpu_retires(1,\",%,\",\",%,\",\",%,\",\",%,\");\");",
227-
pc<<2,instr,xregsA.wenable?exec.write_rd:0,write_back);
227+
{pc,2b00},instr,xregsA.wenable?exec.write_rd:0,write_back);
228228
$$end
229229
break;
230230
// instruction read from BRAM and write to register
@@ -241,7 +241,7 @@ $$end
241241
$$if ICEV_VERILATOR_TRACE then
242242
// this is used by SOCs/ice-v-cmp, to track retired instr. and compare CPUs
243243
__verilog("$c32(\"cpu_retires(1,\",%,\",\",%,\",\",%,\",\",%,\");\");",
244-
pc<<2,instr,xregsA.wenable?exec.write_rd:0,write_back);
244+
{pc,2b00},instr,xregsA.wenable?exec.write_rd:0,write_back);
245245
$$end
246246
break;
247247
// instruction read from BRAM and write to register

projects/ice-v/SOCs/ice-v-soc-cmp.si.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void cpu_retires(int id,unsigned int pc,unsigned int instr,
117117
unsigned int rd,unsigned int val)
118118
{
119119
if (instr == 0 && id == 1) {
120-
fprintf(stderr,"null instruction from cpu %d: halting",id);
120+
fprintf(stderr,"null instruction from cpu %d @%03x: halting",id,pc);
121121
for (int i=0;i<3;++i) {
122122
fprintf(stderr,"\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CPU %d >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",1+i);
123123
fprintf(stderr,"%s\n",cpu_stdout[i].c_str());

projects/ice-v/SOCs/pre_include_compiled.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ for str in string.gmatch(code, "([^ \r\n]+)") do
6464
end
6565
out:write(string.pack('B', 0 ))
6666
end
67+
written = addr
6768
end
6869
else
6970
h32 = str .. h32
@@ -93,7 +94,7 @@ code_size_bytes = numwords * 4
9394
print('code size: ' .. numwords .. ' 32bits words ('
9495
.. code_size_bytes .. ' bytes)')
9596
data_size_bytes = datanumwords * 4
96-
print('dara size: ' .. datanumwords .. ' 32bits words ('
97+
print('data size: ' .. datanumwords .. ' 32bits words ('
9798
.. data_size_bytes .. ' bytes)')
9899
meminit = meminit .. 'pad(0)}'
99100
datainit = datainit .. 'pad(0)}'

projects/ice-v/compile/cmp/config_c.ld

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ MEMORY
88
}
99

1010
SECTIONS {
11+
1112
/* The program code and other data goes into ROM, mapped in a first BRAM */
1213
.text :
1314
{

0 commit comments

Comments
 (0)