Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

Commit

Permalink
Merge branch 'master' into 1.6-release
Browse files Browse the repository at this point in the history
  • Loading branch information
jackkoenig committed Feb 16, 2023
2 parents 60bd03d + 94d425f commit 049e523
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 11 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/setup-oss-cad-suite/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Setup OSS CAD Suite

runs:
using: composite
steps:
- name: Install Tabby OSS Cad Suite
shell: bash
env:
VERSION: 2021-11-09
run: |
ARTIFACT=oss-cad-suite-linux-x64-$(echo $VERSION | tr -d '-')
wget -q -O - https://github.com/YosysHQ/oss-cad-suite-build/releases/download/${VERSION}/${ARTIFACT}.tgz | tar -zx
echo "$(pwd)/oss-cad-suite/bin" >> $GITHUB_PATH
12 changes: 4 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Tabby OSS Cad Suite (from YosysHQ)
uses: YosysHQ/setup-oss-cad-suite@v1
with:
osscadsuite-version: '2021-11-09'
- name: Install Tabby OSS Cad Suite
uses: ./.github/workflows/setup-oss-cad-suite
- name: Setup Scala
uses: olafurpg/setup-scala@v10
with:
Expand Down Expand Up @@ -75,10 +73,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Tabby OSS Cad Suite (from YosysHQ)
uses: YosysHQ/setup-oss-cad-suite@v1
with:
osscadsuite-version: '2021-11-09'
- name: Install Tabby OSS Cad Suite
uses: ./.github/workflows/setup-oss-cad-suite
- name: Setup Scala
uses: olafurpg/setup-scala@v10
with:
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.8.0
sbt.version=1.8.2
6 changes: 5 additions & 1 deletion src/main/scala/firrtl/ir/Serializer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,11 @@ object Serializer {
// WIR
case firrtl.CDefMemory(info, name, tpe, size, seq, readUnderWrite) =>
if (seq) b ++= "smem " else b ++= "cmem "
b ++= name; b ++= " : "; s(tpe); b ++= " ["; b ++= size.toString(); b += ']'; s(info)
b ++= name; b ++= " : "; s(tpe); b ++= " ["; b ++= size.toString(); b += ']'
if (readUnderWrite != ReadUnderWrite.Undefined) { // undefined is the default
b += ' '; b ++= readUnderWrite.toString
}
s(info)
case firrtl.CDefMPort(info, name, _, mem, exps, direction) =>
b ++= direction.serialize; b ++= " mport "; b ++= name; b ++= " = "; b ++= mem
b += '['; s(exps.head); b ++= "], "; s(exps(1)); s(info)
Expand Down
13 changes: 12 additions & 1 deletion src/main/scala/firrtl/passes/memlib/VerilogMemDelays.scala
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,18 @@ class MemDelayAndReadwriteTransformer(m: DefModule, passthroughSimpleSyncReadMem
val transformed = m match {
case mod: Module =>
findMemConns(mod.body)
mod.copy(body = Block(transform(mod.body) +: newConns.toSeq))
val bodyx = transform(mod.body)
// Fixup any mem connections being driven by other transformed memories
val newConsx = newConns.map {
case sx if kind(sx.loc) == MemKind =>
val (memRef, _) = Utils.splitRef(sx.loc)
if (passthroughMems(WrappedExpression(memRef)))
sx
else
sx.mapExpr(swapMemRefs)
case sx => sx
}
mod.copy(body = Block(bodyx +: newConsx.toSeq))
case mod => mod
}
}
Expand Down
29 changes: 29 additions & 0 deletions src/test/scala/firrtlTests/ParserSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,35 @@ class ParserSpec extends FirrtlFlatSpec {
firrtl.Parser.parse(input)
}
}

it should "parse smem read-under-write behavior" in {
val undefined = firrtl.Parser.parse(SMemTestCircuit.src(""))
assert(SMemTestCircuit.findRuw(undefined) == ReadUnderWrite.Undefined)

val undefined2 = firrtl.Parser.parse(SMemTestCircuit.src(" undefined"))
assert(SMemTestCircuit.findRuw(undefined2) == ReadUnderWrite.Undefined)

val old = firrtl.Parser.parse(SMemTestCircuit.src(" old"))
assert(SMemTestCircuit.findRuw(old) == ReadUnderWrite.Old)

val readNew = firrtl.Parser.parse(SMemTestCircuit.src(" new"))
assert(SMemTestCircuit.findRuw(readNew) == ReadUnderWrite.New)
}
}

/** used to test parsing and serialization of smems */
object SMemTestCircuit {
def src(ruw: String): String =
s"""circuit Example :
| module Example :
| smem mem : UInt<8> [8] $ruw@[main.scala 10:25]
|""".stripMargin

def findRuw(c: Circuit): ReadUnderWrite.Value = {
val main = c.modules.head.asInstanceOf[ir.Module]
val mem = main.body.asInstanceOf[ir.Block].stmts.collectFirst { case m: CDefMemory => m }.get
mem.readUnderWrite
}
}

class ParserPropSpec extends FirrtlPropSpec {
Expand Down
15 changes: 15 additions & 0 deletions src/test/scala/firrtlTests/SerializerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,19 @@ class SerializerSpec extends AnyFlatSpec with Matchers {
val serialized = Serializer.serialize(when, 1)
serialized should be(" when cond :\n skip\n")
}

it should "serialize read-under-write behavior for smems correctly" in {
def parseSerializeParse(src: String): Circuit = Parser.parse(Parser.parse(src).serialize)
val undefined = parseSerializeParse(SMemTestCircuit.src(""))
assert(SMemTestCircuit.findRuw(undefined) == ReadUnderWrite.Undefined)

val undefined2 = parseSerializeParse(SMemTestCircuit.src(" undefined"))
assert(SMemTestCircuit.findRuw(undefined2) == ReadUnderWrite.Undefined)

val old = parseSerializeParse(SMemTestCircuit.src(" old"))
assert(SMemTestCircuit.findRuw(old) == ReadUnderWrite.Old)

val readNew = parseSerializeParse(SMemTestCircuit.src(" new"))
assert(SMemTestCircuit.findRuw(readNew) == ReadUnderWrite.New)
}
}
58 changes: 58 additions & 0 deletions src/test/scala/firrtlTests/VerilogMemDelaySpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,62 @@ class VerilogMemDelaySpec extends LeanTransformSpec(Seq(Dependency(VerilogMemDel
res should include("m.write.clk <= clock")
res should include("reg m_write_data_pipe_0 : UInt<8>, clock")
}

it should "VerilogMemDelays should replace expr in connections of previous mems" in {
val input =
"""
|circuit Test :
| module Test :
| input clock : Clock
| input sel : UInt<1>
| input en : UInt<1>
| output v1 : UInt<1>
| output v2 : UInt<1>
|
| mem m1 :
| data-type => UInt<1>
| depth => 2
| read-latency => 0
| write-latency => 1
| readwriter => rw1
| readwriter => rw2
| read-under-write => undefined
| mem m2 :
| data-type => UInt<1>
| depth => 2
| read-latency => 0
| write-latency => 1
| readwriter => rw1
| readwriter => rw2
| read-under-write => undefined
| v1 <= m1.rw2.rdata
| v2 <= m2.rw2.rdata
| m1.rw1.addr <= UInt<1>("h0")
| m2.rw1.addr <= UInt<1>("h0")
| m1.rw1.en <= UInt<1>("h1")
| m2.rw1.en <= UInt<1>("h1")
| m1.rw1.clk <= clock
| m2.rw1.clk <= clock
| m1.rw1.wmode <= en
| m2.rw1.wmode <= en
| m1.rw1.wdata <= UInt<1>("h1")
| m2.rw1.wdata <= UInt<1>("h0")
| m1.rw1.wmask <= en
| m2.rw1.wmask <= UInt<1>("h0")
| m1.rw2.addr <= m2.rw1.rdata
| m2.rw2.addr <= m2.rw1.rdata
| m1.rw2.en <= UInt<1>("h1")
| m2.rw2.en <= UInt<1>("h1")
| m1.rw2.clk <= clock
| m2.rw2.clk <= clock
| m1.rw2.wmode <= en
| m2.rw2.wmode <= en
| m1.rw2.wdata <= UInt<1>("h0")
| m2.rw2.wdata <= UInt<1>("h0")
| m1.rw2.wmask <= en
| m2.rw2.wmask <= UInt<1>("h0")
""".stripMargin

compileTwice(input)
}
}

0 comments on commit 049e523

Please sign in to comment.