凿子 AlreadyBoundException
Chisel AlreadyBoundException
我正在基于 Sodor 暂存存储器为 SoC 开发一个简单的片上存储器。因此,首先我将该设计的一个稍微修改过的版本转换为 chisel 3。现在,我收到了关于我无法理解的有界类型的异常。
[info] - should correctly write and read data *** FAILED ***
[info] chisel3.core.Binding$BindingException: Error: Cannot set as output .M_WR: Already bound to LitBinding()
[info] at chisel3.core.Binding$.bind(Binding.scala:100)
[info] at chisel3.core.Output$.apply(Data.scala:50)
[info] at chisel3.util.ReadyValidIO.<init>(Decoupled.scala:22)
[info] at chisel3.util.DecoupledIO.<init>(Decoupled.scala:72)
[info] at chisel3.util.Decoupled$.apply(Decoupled.scala:81)
[info] at mem.MemPortIO.<init>(memory.scala:40)
[info] at mem.OnChipMemory$$anon.<init>(memory.scala:49)
[info] at mem.OnChipMemory.<init>(memory.scala:47)
[info] at mem.memoryTester$$anonfun$$anonfun$apply$$anonfun$apply$mcV$sp.apply(memoryTest.scala:33)
[info] at mem.memoryTester$$anonfun$$anonfun$apply$$anonfun$apply$mcV$sp.apply(memoryTest.scala:33)
[info] at chisel3.core.Module$.do_apply(Module.scala:35)
[info] at chisel3.Driver$$anonfun$elaborate.apply(Driver.scala:194)
[info] at chisel3.Driver$$anonfun$elaborate.apply(Driver.scala:194)
[info] at chisel3.internal.Builder$$anonfun$build.apply(Builder.scala:206)
[info] at chisel3.internal.Builder$$anonfun$build.apply(Builder.scala:204)
[info] at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
[info] at chisel3.internal.Builder$.build(Builder.scala:204)
[info] at chisel3.Driver$.elaborate(Driver.scala:194)
[info] at chisel3.Driver$.execute(Driver.scala:229)
[info] at chisel3.iotesters.setupFirrtlTerpBackend$.apply(FirrtlTerpBackend.scala:110)
[info] at chisel3.iotesters.Driver$.execute(Driver.scala:47)
[info] at chisel3.iotesters.Driver$.apply(Driver.scala:210)
[info] at mem.memoryTester$$anonfun$$anonfun$apply.apply$mcV$sp(memoryTest.scala:33)
[info] at mem.memoryTester$$anonfun$$anonfun$apply.apply(memoryTest.scala:33)
[info] at mem.memoryTester$$anonfun$$anonfun$apply.apply(memoryTest.scala:33)
[info] at org.scalatest.Transformer$$anonfun$apply.apply$mcV$sp(Transformer.scala:22)
[info] at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
[info] at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info] at org.scalatest.Transformer.apply(Transformer.scala:22)
[info] at org.scalatest.Transformer.apply(Transformer.scala:20)
[info] at org.scalatest.FlatSpecLike$$anon.apply(FlatSpecLike.scala:1647)
[info] at org.scalatest.Suite$class.withFixture(Suite.scala:1122)
[info] at org.scalatest.FlatSpec.withFixture(FlatSpec.scala:1683)
[info] at org.scalatest.FlatSpecLike$class.invokeWithFixture(FlatSpecLike.scala:1644)
[info] at org.scalatest.FlatSpecLike$$anonfun$runTest.apply(FlatSpecLike.scala:1656)
[info] at org.scalatest.FlatSpecLike$$anonfun$runTest.apply(FlatSpecLike.scala:1656)
[info] at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
[info] at org.scalatest.FlatSpecLike$class.runTest(FlatSpecLike.scala:1656)
[info] at org.scalatest.FlatSpec.runTest(FlatSpec.scala:1683)
[info] at org.scalatest.FlatSpecLike$$anonfun$runTests.apply(FlatSpecLike.scala:1714)
[info] at org.scalatest.FlatSpecLike$$anonfun$runTests.apply(FlatSpecLike.scala:1714)
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes.apply(Engine.scala:413)
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes.apply(Engine.scala:401)
[info] at scala.collection.immutable.List.foreach(List.scala:381)
[info] at org.scalatest.SuperEngine.traverseSubNodes(Engine.scala:401)
[info] at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:390)
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes.apply(Engine.scala:427)
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes.apply(Engine.scala:401)
[info] at scala.collection.immutable.List.foreach(List.scala:381)
[info] at org.scalatest.SuperEngine.traverseSubNodes(Engine.scala:401)
[info] at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:396)
[info] at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:483)
[info] at org.scalatest.FlatSpecLike$class.runTests(FlatSpecLike.scala:1714)
[info] at org.scalatest.FlatSpec.runTests(FlatSpec.scala:1683)
[info] at org.scalatest.Suite$class.run(Suite.scala:1424)
[info] at org.scalatest.FlatSpec.org$scalatest$FlatSpecLike$$super$run(FlatSpec.scala:1683)
[info] at org.scalatest.FlatSpecLike$$anonfun$run.apply(FlatSpecLike.scala:1760)
[info] at org.scalatest.FlatSpecLike$$anonfun$run.apply(FlatSpecLike.scala:1760)
[info] at org.scalatest.SuperEngine.runImpl(Engine.scala:545)
[info] at org.scalatest.FlatSpecLike$class.run(FlatSpecLike.scala:1760)
[info] at org.scalatest.FlatSpec.run(FlatSpec.scala:1683)
[info] at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:466)
[info] at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:677)
[info] at sbt.TestRunner.runTest(TestFramework.scala:76)
[info] at sbt.TestRunner.run(TestFramework.scala:85)
[info] at sbt.TestFramework$$anon$$anonfun$$init$$$anonfun$apply.apply(TestFramework.scala:202)
[info] at sbt.TestFramework$$anon$$anonfun$$init$$$anonfun$apply.apply(TestFramework.scala:202)
[info] at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:185)
[info] at sbt.TestFramework$$anon$$anonfun$$init$.apply(TestFramework.scala:202)
[info] at sbt.TestFramework$$anon$$anonfun$$init$.apply(TestFramework.scala:202)
[info] at sbt.TestFunction.apply(TestFramework.scala:207)
[info] at sbt.Tests$$anonfun.apply(Tests.scala:216)
[info] at sbt.Tests$$anonfun.apply(Tests.scala:216)
[info] at sbt.std.Transform$$anon$$anonfun$apply.apply(System.scala:44)
[info] at sbt.std.Transform$$anon$$anonfun$apply.apply(System.scala:44)
[info] at sbt.std.Transform$$anon.work(System.scala:63)
[info] at sbt.Execute$$anonfun$submit$$anonfun$apply.apply(Execute.scala:228)
[info] at sbt.Execute$$anonfun$submit$$anonfun$apply.apply(Execute.scala:228)
[info] at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
[info] at sbt.Execute.work(Execute.scala:237)
[info] at sbt.Execute$$anonfun$submit.apply(Execute.scala:228)
[info] at sbt.Execute$$anonfun$submit.apply(Execute.scala:228)
[info] at sbt.ConcurrentRestrictions$$anon$$anonfun.apply(ConcurrentRestrictions.scala:159)
[info] at sbt.CompletionService$$anon.call(CompletionService.scala:28)
[info] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[info] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[info] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[info] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[info] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[info] at java.lang.Thread.run(Thread.java:745)
[info] ScalaCheck
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] ScalaTest
我不清楚导致问题的值。首先,我认为这是我在 Mem 和 IO 端口中使用的 Vec 的问题(因为我发现了一个类似异常的解释)。但是即使在我摆脱它们之后问题仍然存在。我什至尝试摆脱克隆功能。
现在,我对问题的原因一无所知。我发布了内存的源代码的主要部分(除了参数声明和一些简单的函数)以防它可能有用。
trait MemOpConstants
{
val MT_X = Bits(0, 3) // memory transfer type
val MT_B = Bits(1, 3)
val MT_H = Bits(2, 3)
val MT_W = Bits(3, 3)
val MT_D = Bits(4, 3)
val MT_BU = Bits(5, 3)
val MT_HU = Bits(6, 3)
val MT_WU = Bits(7, 3)
val M_X = Bits("b0", 1) // access type
val M_RD = Bits("b0", 1) // load
val M_WR = Bits("b1", 1) // store
}
class MemReq(data_width: Int)(implicit config: Configuration) extends Bundle with MemOpConstants
{
val addr = UInt(width = config.xprlen)
val data = Bits(width = data_width)
val fcn = Bits(width = M_X.getWidth) // memory function code
val typ = Bits(width = MT_X.getWidth) // memory access type
override def cloneType = { new MemReq(data_width).asInstanceOf[this.type] }
}
class MemResp(data_width: Int) extends Bundle
{
val data = Bits(width = data_width)
override def cloneType = { new MemResp(data_width).asInstanceOf[this.type] }
}
class MemPortIO(data_width: Int)(implicit config: Configuration) extends Bundle // constructor for IO interface of data memory
{
val req = Decoupled(new MemReq(data_width)) // ready valid pair
val resp = (new ValidIO(new MemResp(data_width))).flip // valid signal
override def cloneType = { new MemPortIO(data_width).asInstanceOf[this.type] }
}
class OnChipMemory(num_ports: Int = 2, num_bytes: Int = (1 << 15), seq_read: Boolean = false)(implicit config: Configuration) extends Module with MemOpConstants
{
val io = IO(new Bundle{
val port = Vec(num_ports, (new MemPortIO(data_width = config.xprlen)).flip)
})
val num_bytes_per_line = 4
val num_lines = num_bytes/num_bytes_per_line
val lsb_idx = log2Up(num_bytes_per_line) // index of lsb in address
val chipMem = Mem(Vec(4, UInt(width = 32)), num_lines) // memory
for (i <- 0 until num_ports)
{
io.port(i).resp.valid := Reg(next = io.port(i).req.valid)
io.port(i).req.ready := Bool(true) // for now
val req_valid = io.port(i).req.valid
val req_addr = io.port(i).req.bits.addr
val req_data = io.port(i).req.bits.data
val req_fn = io.port(i).req.bits.fcn
val req_typ = io.port(i).req.bits.typ
val byte_shift_amt = io.port(i).req.bits.addr(1,0)
val bit_shift_amt = Cat(byte_shift_amt, UInt(0,3))
//mem read
val r_data_idx = Reg(UInt())
val data_idx = req_addr >> UInt(lsb_idx)
val read_data = Bits()
val rdata = Bits()
if (seq_read)
{
read_data := chipMem(r_data_idx)
rdata := LoadDataGen((read_data >> Reg(next=bit_shift_amt)), Reg(next=req_typ))
}
else
{
read_data := chipMem(data_idx)
rdata := LoadDataGen((read_data >> bit_shift_amt), req_typ)
}
io.port(i).resp.bits.data := rdata
//mem write
when (req_valid && req_fn === M_WR)
{
val wdata = StoreDataGen(req_data, req_typ)
val wmask = ((StoreMask(req_typ) << bit_shift_amt)(31,0)).toBools
chipMem.write(data_idx, wdata, wmask)
}
.elsewhen (req_valid && req_fn === M_RD)
{
r_data_idx := data_idx
}
}
}
object StoreDataGen extends MemOpConstants
{
def apply(din: Bits, typ: Bits): Vec[UInt] =
{
val word = (typ.equals(MT_W)) || (typ.equals(MT_WU))
val half = (typ.equals(MT_H)) || (typ.equals(MT_HU))
val byte = (typ.equals(MT_B)) || (typ.equals(MT_BU))
val dout = Mux(Bool(byte), Vec(4, din( 7,0)),
Mux(Bool(half), Vec(din(15,8), din( 7,0), din(15,8), din( 7,0)),
Vec(din(31,25), din(24,16), din(15,8), din( 7,0))))
return dout
}
}
拥有更多带有行号的代码会有所帮助,但根据特征 MemOpConstants 的名称,我猜它包含一些 Chisel 文字。编译器抱怨它不能从 MemPortIO 中创建一个 IO 端口,因为它包含一个包含文字作为元素的 Bundle MemReq。
IO 端口只能包含纯的、未绑定的 Chisel 数据类型,而不是文字、Reg、Mem 或 Wire。
如果你想让这些常量在 IO 端口可用,你应该定义插槽 (UInts) 来接收它们,然后将这些插槽连接到实际的 constant/literal 值。不要将常量本身放在 IO 端口定义中。
您在 MemOpConstants 中的所有定义都是位类型的文字(常量)。它们具有值和宽度。这些值使它们成为文字(常量),不适合包含在 IO 端口定义中。
我正在基于 Sodor 暂存存储器为 SoC 开发一个简单的片上存储器。因此,首先我将该设计的一个稍微修改过的版本转换为 chisel 3。现在,我收到了关于我无法理解的有界类型的异常。
[info] - should correctly write and read data *** FAILED ***
[info] chisel3.core.Binding$BindingException: Error: Cannot set as output .M_WR: Already bound to LitBinding()
[info] at chisel3.core.Binding$.bind(Binding.scala:100)
[info] at chisel3.core.Output$.apply(Data.scala:50)
[info] at chisel3.util.ReadyValidIO.<init>(Decoupled.scala:22)
[info] at chisel3.util.DecoupledIO.<init>(Decoupled.scala:72)
[info] at chisel3.util.Decoupled$.apply(Decoupled.scala:81)
[info] at mem.MemPortIO.<init>(memory.scala:40)
[info] at mem.OnChipMemory$$anon.<init>(memory.scala:49)
[info] at mem.OnChipMemory.<init>(memory.scala:47)
[info] at mem.memoryTester$$anonfun$$anonfun$apply$$anonfun$apply$mcV$sp.apply(memoryTest.scala:33)
[info] at mem.memoryTester$$anonfun$$anonfun$apply$$anonfun$apply$mcV$sp.apply(memoryTest.scala:33)
[info] at chisel3.core.Module$.do_apply(Module.scala:35)
[info] at chisel3.Driver$$anonfun$elaborate.apply(Driver.scala:194)
[info] at chisel3.Driver$$anonfun$elaborate.apply(Driver.scala:194)
[info] at chisel3.internal.Builder$$anonfun$build.apply(Builder.scala:206)
[info] at chisel3.internal.Builder$$anonfun$build.apply(Builder.scala:204)
[info] at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
[info] at chisel3.internal.Builder$.build(Builder.scala:204)
[info] at chisel3.Driver$.elaborate(Driver.scala:194)
[info] at chisel3.Driver$.execute(Driver.scala:229)
[info] at chisel3.iotesters.setupFirrtlTerpBackend$.apply(FirrtlTerpBackend.scala:110)
[info] at chisel3.iotesters.Driver$.execute(Driver.scala:47)
[info] at chisel3.iotesters.Driver$.apply(Driver.scala:210)
[info] at mem.memoryTester$$anonfun$$anonfun$apply.apply$mcV$sp(memoryTest.scala:33)
[info] at mem.memoryTester$$anonfun$$anonfun$apply.apply(memoryTest.scala:33)
[info] at mem.memoryTester$$anonfun$$anonfun$apply.apply(memoryTest.scala:33)
[info] at org.scalatest.Transformer$$anonfun$apply.apply$mcV$sp(Transformer.scala:22)
[info] at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
[info] at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info] at org.scalatest.Transformer.apply(Transformer.scala:22)
[info] at org.scalatest.Transformer.apply(Transformer.scala:20)
[info] at org.scalatest.FlatSpecLike$$anon.apply(FlatSpecLike.scala:1647)
[info] at org.scalatest.Suite$class.withFixture(Suite.scala:1122)
[info] at org.scalatest.FlatSpec.withFixture(FlatSpec.scala:1683)
[info] at org.scalatest.FlatSpecLike$class.invokeWithFixture(FlatSpecLike.scala:1644)
[info] at org.scalatest.FlatSpecLike$$anonfun$runTest.apply(FlatSpecLike.scala:1656)
[info] at org.scalatest.FlatSpecLike$$anonfun$runTest.apply(FlatSpecLike.scala:1656)
[info] at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
[info] at org.scalatest.FlatSpecLike$class.runTest(FlatSpecLike.scala:1656)
[info] at org.scalatest.FlatSpec.runTest(FlatSpec.scala:1683)
[info] at org.scalatest.FlatSpecLike$$anonfun$runTests.apply(FlatSpecLike.scala:1714)
[info] at org.scalatest.FlatSpecLike$$anonfun$runTests.apply(FlatSpecLike.scala:1714)
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes.apply(Engine.scala:413)
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes.apply(Engine.scala:401)
[info] at scala.collection.immutable.List.foreach(List.scala:381)
[info] at org.scalatest.SuperEngine.traverseSubNodes(Engine.scala:401)
[info] at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:390)
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes.apply(Engine.scala:427)
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes.apply(Engine.scala:401)
[info] at scala.collection.immutable.List.foreach(List.scala:381)
[info] at org.scalatest.SuperEngine.traverseSubNodes(Engine.scala:401)
[info] at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:396)
[info] at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:483)
[info] at org.scalatest.FlatSpecLike$class.runTests(FlatSpecLike.scala:1714)
[info] at org.scalatest.FlatSpec.runTests(FlatSpec.scala:1683)
[info] at org.scalatest.Suite$class.run(Suite.scala:1424)
[info] at org.scalatest.FlatSpec.org$scalatest$FlatSpecLike$$super$run(FlatSpec.scala:1683)
[info] at org.scalatest.FlatSpecLike$$anonfun$run.apply(FlatSpecLike.scala:1760)
[info] at org.scalatest.FlatSpecLike$$anonfun$run.apply(FlatSpecLike.scala:1760)
[info] at org.scalatest.SuperEngine.runImpl(Engine.scala:545)
[info] at org.scalatest.FlatSpecLike$class.run(FlatSpecLike.scala:1760)
[info] at org.scalatest.FlatSpec.run(FlatSpec.scala:1683)
[info] at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:466)
[info] at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:677)
[info] at sbt.TestRunner.runTest(TestFramework.scala:76)
[info] at sbt.TestRunner.run(TestFramework.scala:85)
[info] at sbt.TestFramework$$anon$$anonfun$$init$$$anonfun$apply.apply(TestFramework.scala:202)
[info] at sbt.TestFramework$$anon$$anonfun$$init$$$anonfun$apply.apply(TestFramework.scala:202)
[info] at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:185)
[info] at sbt.TestFramework$$anon$$anonfun$$init$.apply(TestFramework.scala:202)
[info] at sbt.TestFramework$$anon$$anonfun$$init$.apply(TestFramework.scala:202)
[info] at sbt.TestFunction.apply(TestFramework.scala:207)
[info] at sbt.Tests$$anonfun.apply(Tests.scala:216)
[info] at sbt.Tests$$anonfun.apply(Tests.scala:216)
[info] at sbt.std.Transform$$anon$$anonfun$apply.apply(System.scala:44)
[info] at sbt.std.Transform$$anon$$anonfun$apply.apply(System.scala:44)
[info] at sbt.std.Transform$$anon.work(System.scala:63)
[info] at sbt.Execute$$anonfun$submit$$anonfun$apply.apply(Execute.scala:228)
[info] at sbt.Execute$$anonfun$submit$$anonfun$apply.apply(Execute.scala:228)
[info] at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
[info] at sbt.Execute.work(Execute.scala:237)
[info] at sbt.Execute$$anonfun$submit.apply(Execute.scala:228)
[info] at sbt.Execute$$anonfun$submit.apply(Execute.scala:228)
[info] at sbt.ConcurrentRestrictions$$anon$$anonfun.apply(ConcurrentRestrictions.scala:159)
[info] at sbt.CompletionService$$anon.call(CompletionService.scala:28)
[info] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[info] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[info] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[info] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[info] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[info] at java.lang.Thread.run(Thread.java:745)
[info] ScalaCheck
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] ScalaTest
我不清楚导致问题的值。首先,我认为这是我在 Mem 和 IO 端口中使用的 Vec 的问题(因为我发现了一个类似异常的解释)。但是即使在我摆脱它们之后问题仍然存在。我什至尝试摆脱克隆功能。
现在,我对问题的原因一无所知。我发布了内存的源代码的主要部分(除了参数声明和一些简单的函数)以防它可能有用。
trait MemOpConstants
{
val MT_X = Bits(0, 3) // memory transfer type
val MT_B = Bits(1, 3)
val MT_H = Bits(2, 3)
val MT_W = Bits(3, 3)
val MT_D = Bits(4, 3)
val MT_BU = Bits(5, 3)
val MT_HU = Bits(6, 3)
val MT_WU = Bits(7, 3)
val M_X = Bits("b0", 1) // access type
val M_RD = Bits("b0", 1) // load
val M_WR = Bits("b1", 1) // store
}
class MemReq(data_width: Int)(implicit config: Configuration) extends Bundle with MemOpConstants
{
val addr = UInt(width = config.xprlen)
val data = Bits(width = data_width)
val fcn = Bits(width = M_X.getWidth) // memory function code
val typ = Bits(width = MT_X.getWidth) // memory access type
override def cloneType = { new MemReq(data_width).asInstanceOf[this.type] }
}
class MemResp(data_width: Int) extends Bundle
{
val data = Bits(width = data_width)
override def cloneType = { new MemResp(data_width).asInstanceOf[this.type] }
}
class MemPortIO(data_width: Int)(implicit config: Configuration) extends Bundle // constructor for IO interface of data memory
{
val req = Decoupled(new MemReq(data_width)) // ready valid pair
val resp = (new ValidIO(new MemResp(data_width))).flip // valid signal
override def cloneType = { new MemPortIO(data_width).asInstanceOf[this.type] }
}
class OnChipMemory(num_ports: Int = 2, num_bytes: Int = (1 << 15), seq_read: Boolean = false)(implicit config: Configuration) extends Module with MemOpConstants
{
val io = IO(new Bundle{
val port = Vec(num_ports, (new MemPortIO(data_width = config.xprlen)).flip)
})
val num_bytes_per_line = 4
val num_lines = num_bytes/num_bytes_per_line
val lsb_idx = log2Up(num_bytes_per_line) // index of lsb in address
val chipMem = Mem(Vec(4, UInt(width = 32)), num_lines) // memory
for (i <- 0 until num_ports)
{
io.port(i).resp.valid := Reg(next = io.port(i).req.valid)
io.port(i).req.ready := Bool(true) // for now
val req_valid = io.port(i).req.valid
val req_addr = io.port(i).req.bits.addr
val req_data = io.port(i).req.bits.data
val req_fn = io.port(i).req.bits.fcn
val req_typ = io.port(i).req.bits.typ
val byte_shift_amt = io.port(i).req.bits.addr(1,0)
val bit_shift_amt = Cat(byte_shift_amt, UInt(0,3))
//mem read
val r_data_idx = Reg(UInt())
val data_idx = req_addr >> UInt(lsb_idx)
val read_data = Bits()
val rdata = Bits()
if (seq_read)
{
read_data := chipMem(r_data_idx)
rdata := LoadDataGen((read_data >> Reg(next=bit_shift_amt)), Reg(next=req_typ))
}
else
{
read_data := chipMem(data_idx)
rdata := LoadDataGen((read_data >> bit_shift_amt), req_typ)
}
io.port(i).resp.bits.data := rdata
//mem write
when (req_valid && req_fn === M_WR)
{
val wdata = StoreDataGen(req_data, req_typ)
val wmask = ((StoreMask(req_typ) << bit_shift_amt)(31,0)).toBools
chipMem.write(data_idx, wdata, wmask)
}
.elsewhen (req_valid && req_fn === M_RD)
{
r_data_idx := data_idx
}
}
}
object StoreDataGen extends MemOpConstants
{
def apply(din: Bits, typ: Bits): Vec[UInt] =
{
val word = (typ.equals(MT_W)) || (typ.equals(MT_WU))
val half = (typ.equals(MT_H)) || (typ.equals(MT_HU))
val byte = (typ.equals(MT_B)) || (typ.equals(MT_BU))
val dout = Mux(Bool(byte), Vec(4, din( 7,0)),
Mux(Bool(half), Vec(din(15,8), din( 7,0), din(15,8), din( 7,0)),
Vec(din(31,25), din(24,16), din(15,8), din( 7,0))))
return dout
}
}
拥有更多带有行号的代码会有所帮助,但根据特征 MemOpConstants 的名称,我猜它包含一些 Chisel 文字。编译器抱怨它不能从 MemPortIO 中创建一个 IO 端口,因为它包含一个包含文字作为元素的 Bundle MemReq。
IO 端口只能包含纯的、未绑定的 Chisel 数据类型,而不是文字、Reg、Mem 或 Wire。
如果你想让这些常量在 IO 端口可用,你应该定义插槽 (UInts) 来接收它们,然后将这些插槽连接到实际的 constant/literal 值。不要将常量本身放在 IO 端口定义中。
您在 MemOpConstants 中的所有定义都是位类型的文字(常量)。它们具有值和宽度。这些值使它们成为文字(常量),不适合包含在 IO 端口定义中。