Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quad RV32 LargeBoomCore Config failed to boot core2/3 with wfi dead loop #684

Open
zqf1995 opened this issue Mar 17, 2024 · 0 comments
Open

Comments

@zqf1995
Copy link

zqf1995 commented Mar 17, 2024

Type of issue: bug report | feature request | question | other enhancement
bug report

Impact: no rtl change | rtl refactoring | new rtl | unknown
rtl refactoring

Development Phase: request | proposal
request
Other information

The Config is shown as following:

class RV32LargeBoomConfig extends Config(  
  new boom.common.WithRV32 ++  
  new boom.common.WithNLargeBooms(4) ++  
  new chipyard.config.AbstractConfig)

The expected behavior shall be core0 writes 1 to CLINT and wakes up core by core from wfi. What I really find is that core0 writes 1 to CLINT address=0x20000004 and then reads 0x00010000.
In more detail, below asm code shows the register a3 is reused during interrupt_loop. Once 0x10020 read a3 !=1, then correct interrupt is not correctly passed to CLINT.

00010000 <_start>:
   10000:	020005b7          	lui	a1,0x2000
   10004:	f1402573          	csrr	a0,mhartid
   10008:	00050463          	beqz	a0,10010 <_start+0x10>
   1000c:	0780006f          	j	10084 
   10010:	00458613          	addi	a2,a1,4 # 2000004 <_dtb+0x1feff44>
   10014:	00100693          	li	a3,1
 00010018 :
   10018:	00d62023          	sw	a3,0(a2)
   1001c:	00460613          	addi	a2,a2,4
   10020:	ffc62683          	lw	a3,-4(a2)
   10024:	fe069ae3          	bnez	a3,10018 
   10028:	06c0006f          	j	10094 

What I find is the IOMSHR in boom works unproperly. Following code shows how the IOMSHR work with word align.
Keep in mind that I set RV32, so beatOffBits=4, wordOffBits=2, wordBytes=4.

def beatOffset(addr: UInt) = addr.extract(beatOffBits-1, wordOffBits)
def wordFromBeat(addr: UInt, dat: UInt) = {
val shift = Cat(beatOffset(addr), 0.U((wordOffBits+log2Ceil(wordBytes)).W))
(dat >> shift)(wordBits-1, 0)
}

Then FIRRTL transfers verilog code like:

wire [127:0] _grant_word_T = io_mem_ack_bits_data >> {122'h0, req_addr[3:2], 4'h0}; // @[Misc.scala:201:34, mshrs.scala:407:10, :410:16, package.scala:155:13]

Suppose we want to read 0x20000004 and io_mem_ack_bits_data receives 127‘h0x00000001000000010000000100000001, however grant_word is right shifted 16bit(32bit should be correct) to be :127‘h0x00000000000100000001000000010000. See the lower 32bit 0x00010000 writes back to register a3 , causing an error.

Instead, MSHR verilog code is shown as following, which I think shall work properly.

wire [127:0]     data_word = io_lb_resp >> {121'h0, _rpq_io_deq_bits_addr[3:2], 5'h0};  // @[mshrs.scala:107:22, :128:19, :251:56, :253:26]

What is the current behavior?
Only core0 and core1 boot successfully. Core2 and Core3 keep wfi during the simulation
What is the expected behavior?
int interrupt_loop, a3 should be kept as one till all the cores leave wfi
Please tell us about your environment:

What is the use case for changing the behavior?
bootrom code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant