ucb-bar / chipyard

An Agile RISC-V SoC Design Framework with in-order cores, out-of-order cores, accelerators, and more
https://chipyard.readthedocs.io/en/stable/
BSD 3-Clause "New" or "Revised" License
1.67k stars 657 forks source link

Documented scratchpad Config is broken #365

Closed baltazarortiz closed 4 years ago

baltazarortiz commented 4 years ago

In the documentation, there is an example config for making the L1 cache into a scratchpad.

I copied the SmallRocketConfig and ScratchpadRocketConfig definitions into RocketConfigs.scala, then tried to build using verilator with make CONFIG=ScratchpadRocketConfig -j8. This gives the following error:

[info] Running example.Generator /home/baltazar/chipyard/sims/verilator/generated-src/example.TestHarness.ScratchpadRocketConfig example TestHarness example ScratchpadRocketConfig              
[info] [0.009] Elaborating design...                                                                                                                                                             
[error] (run-main-0) java.lang.reflect.InvocationTargetException                                                                                                                                 
[error] java.lang.reflect.InvocationTargetException                                                                                                                                              
[error]         at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)                                                                                      
[error]         at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)                                                               
[error]         at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)                                                       
[error]         at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)                                                                                                     
[error]         at freechips.rocketchip.util.HasGeneratorUtilities.$anonfun$elaborate$1(GeneratorUtils.scala:54)                                                                                 
[error]         at chisel3.core.Module$.do_apply(Module.scala:52)                                                                                                                                
[error]         at chisel3.Driver$.$anonfun$elaborate$1(Driver.scala:95)                                                                                                                         
[error]         at chisel3.internal.Builder$.$anonfun$build$2(Builder.scala:343)                                                                                                                 
[error]         at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)                                                                                                                
[error]         at chisel3.internal.Builder$.$anonfun$build$1(Builder.scala:341)                                                                                                                 
[error]         at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)                                                                                                                
[error]         at chisel3.internal.Builder$.build(Builder.scala:341)                                                                                                                            
[error]         at chisel3.Driver$.elaborate(Driver.scala:95)                                                                                                                                    
[error]         at freechips.rocketchip.util.HasGeneratorUtilities.elaborate(GeneratorUtils.scala:59)                                                                                            
[error] Caused by: java.lang.IllegalArgumentException: requirement failed: memory_bus_xbar.node (A nexus node with parent 'memory_bus_xbar/mbus/TestHarness' at  (MemoryBus.scala:56:32)) has 1 r
equired inputs and no possible outputs                                                                                                                                                           
[error]         at scala.Predef$.require(Predef.scala:277)                                                                                                                                       
[error]         at freechips.rocketchip.diplomacy.MixedNexusNode.resolveStar(Nodes.scala:514)                                                                                                    
[error]         at freechips.rocketchip.diplomacy.MixedNode.liftedTree1$1(Nodes.scala:275)
[error]         at freechips.rocketchip.diplomacy.MixedNode.x$29$lzycompute(Nodes.scala:260)
[error]         at freechips.rocketchip.diplomacy.MixedNode.x$29(Nodes.scala:259)
[error]         at freechips.rocketchip.diplomacy.MixedNode.iPortMapping$lzycompute(Nodes.scala:259)
[error]         at freechips.rocketchip.diplomacy.MixedNode.iPortMapping(Nodes.scala:259)
[error]         at freechips.rocketchip.diplomacy.MixedNode.iPortMapping(Nodes.scala:225)
[error]         at freechips.rocketchip.diplomacy.MixedNode.$anonfun$oDirectPorts$1(Nodes.scala:295)
[error]         at scala.collection.immutable.List.flatMap(List.scala:335)
[error]         at freechips.rocketchip.diplomacy.MixedNode.oDirectPorts$lzycompute(Nodes.scala:294)
[error]         at freechips.rocketchip.diplomacy.MixedNode.oDirectPorts(Nodes.scala:294)
[error]         at freechips.rocketchip.diplomacy.MixedNode.oPorts$lzycompute(Nodes.scala:315)
[error]         at freechips.rocketchip.diplomacy.MixedNode.oPorts(Nodes.scala:315)
[error] Nonzero exit code: 1
[error] (Compile / runMain) Nonzero exit code: 1

I also tried using this config directly in Rocket, and get the same error.

I then tried taking the MMIOPortOnlyConfig and swapping in DefaultSmallConfig:

 class TestScratchpadConfig extends Config(                                      
    new WithNoSlavePort ++                                                        
    new WithNMemoryChannels(0) ++                                                 
    new WithNBanks(0) ++                                                          
    new WithIncoherentTiles ++                                                    
    new WithNoMemPort ++                                                          
    new WithScratchpadsOnly ++                                                    
    new DefaultSmallConfig                                                        
  )

This builds successfully, though it is a bit unclear to me what some of the Configs are doing here even after looking at the documentation, and specifically why enabling these fixes the previous error.

When I run the tests using this Config, some tests pass, and the rest result in exceptions (the same happens when using TinyConfig). I'm aware that the default scratchpad size is small enough that some tests don't pass, but previous issues mentioning this showed actual failures rather than exceptions.

...
  [ PASSED ] output/rv64ui-p-sraw.out    Completed after 53946 cycles
  [ PASSED ] output/rv64ui-p-srliw.out   Completed after 42426 cycles
  [ PASSED ] output/rv64ui-p-srlw.out    Completed after 53946 cycles
  [ PASSED ] output/rv64ui-p-subw.out    Completed after 51054 cycles
Makefile:40: recipe for target 'output/multiply.riscv.out' failed
make: *** [output/multiply.riscv.out] Error 1
Makefile:40: recipe for target 'output/median.riscv.out' failed
make: *** [output/median.riscv.out] Error 1
Makefile:40: recipe for target 'output/vvadd.riscv.out' failed 
make: *** [output/vvadd.riscv.out] Error 1
ERROR: ../fesvr/dtm.cc:360, Debug Abstract Command Error #3 (EXCEPTION)ERROR: ../fesvr/dtm.cc:361, Should die, but allowing simulation to continue and fail.Makefile:40: recipe for target 'outpu
t/dhrystone.riscv.out' failed
make: *** [output/dhrystone.riscv.out] Error 1
Makefile:40: recipe for target 'output/mt-matmul.riscv.out' failed
make: *** [output/mt-matmul.riscv.out] Error 1
ERROR: ../fesvr/dtm.cc:360, Debug Abstract Command Error #3 (EXCEPTION)ERROR: ../fesvr/dtm.cc:361, Should die, but allowing simulation to continue and fail.ERROR: ../fesvr/dtm.cc:360, Debug Abs
tract Command Error #3 (EXCEPTION)ERROR: ../fesvr/dtm.cc:361, Should die, but allowing simulation to continue and fail.ERROR: ../fesvr/dtm.cc:360, Debug Abstract Command Error #3 (EXCEPTION)ERR
OR: ../fesvr/dtm.cc:361, Should die, but allowing simulation to continue and fail.ERROR: ../fesvr/dtm.cc:360, Debug Abstract Command Error #3 (EXCEPTION)ERROR: ../fesvr/dtm.cc:361, Should die,
but allowing simulation to continue and fail.ERROR: ../fesvr/dtm.cc:360, Debug Abstract Command Error #3 (EXCEPTION)
...

Specific questions:

colinschmidt commented 4 years ago

I was able to get it to build with these configs:

class SmallRocketConfig extends Config(
  new WithTop ++                                           // use default top
  new WithBootROM ++                                       // use default bootrom
  new freechips.rocketchip.subsystem.WithNSmallCores(1) ++
  new freechips.rocketchip.system.BaseConfig)

class ScratchpadRocketConfig extends Config(
  new freechips.rocketchip.subsystem.WithNoMemPort ++      
  new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++
  new freechips.rocketchip.subsystem.WithNBanks(0) ++
  new freechips.rocketchip.subsystem.WithScratchpadsOnly ++
  new SmallRocketConfig)

Basically, removing the L2 cache and the mbus fully by setting the number of memory channels to 0 and the number of banks to 0. If this works for you we should update the documentation (you can submit a PR if you want).

baltazarortiz commented 4 years ago

This works for 64 and 32 bit cores (passes asm and bmark tests), thank you! I'll submit a PR.

With the same configuration, Rocket still gets the exceptions from above. I'll make a separate issue in the Rocket repo about that.