Skip to content

Commit 78cdcb1

Browse files
author
Oron Port
committed
Fix ToED stage with RT domain loops that modify a register
1 parent 03dd024 commit 78cdcb1

File tree

2 files changed

+98
-9
lines changed

2 files changed

+98
-9
lines changed

compiler/stages/src/main/scala/dfhdl/compiler/stages/ToED.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ case object ToED extends Stage:
7171
cb.guardRef.get match
7272
case dfVal: DFVal => cb :: dfVal.collectRelMembers(false)
7373
case _ => List(cb)
74+
case lb: DFLoop.DFForBlock =>
75+
lb :: lb.iteratorRef.get.collectRelMembers(false)
76+
case lb: DFLoop.DFWhileBlock =>
77+
lb :: lb.guardRef.get.collectRelMembers(false)
7478
case textOut: TextOut =>
7579
textOut :: textOut.collectRelMembers
7680
case _ => None

compiler/stages/src/test/scala/StagesSpec/ToEDSpec.scala

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,8 @@ class ToEDSpec extends StageSpec(stageCreatesUnrefAnons = true):
497497
y := x
498498

499499
class IDTop extends EDDesign:
500-
val x = SInt(16) <> IN
501-
val y = SInt(16) <> OUT
500+
val x = SInt(16) <> IN
501+
val y = SInt(16) <> OUT
502502
val dmn1 = new RTDomain:
503503
val id = ID()
504504
id.x <> x
@@ -558,8 +558,8 @@ class ToEDSpec extends StageSpec(stageCreatesUnrefAnons = true):
558558

559559
test("RT domain with basic combinational if-else") {
560560
class IDTop extends EDDesign:
561-
val x = SInt(16) <> IN
562-
val y = SInt(16) <> OUT
561+
val x = SInt(16) <> IN
562+
val y = SInt(16) <> OUT
563563
val dmn1 = new RTDomain:
564564
if (x < 0) y := 0
565565
else y := x
@@ -609,9 +609,9 @@ class ToEDSpec extends StageSpec(stageCreatesUnrefAnons = true):
609609
val rstCfg = RstCfg(RstCfg.Mode.Sync, RstCfg.Active.High)
610610
val cfg = RTDomainCfg(clkCfg, rstCfg)
611611
class ID extends RTDesign(cfg):
612-
val x = SInt(16) <> IN
613-
val y = SInt(16) <> OUT.REG init 0
614-
val r = SInt(16) <> VAR.REG init 0
612+
val x = SInt(16) <> IN
613+
val y = SInt(16) <> OUT.REG init 0
614+
val r = SInt(16) <> VAR.REG init 0
615615
val foo = new RelatedDomain:
616616
y.din := r
617617
r.din := 1
@@ -803,8 +803,8 @@ class ToEDSpec extends StageSpec(stageCreatesUnrefAnons = true):
803803

804804
test("RT design with ED domain") {
805805
class Foo extends RTDesign:
806-
val clk = Clk <> VAR
807-
val rst = Rst <> VAR
806+
val clk = Clk <> VAR
807+
val rst = Rst <> VAR
808808
val internal = new EDDomain:
809809
process(all):
810810
clk.actual := 0
@@ -878,4 +878,89 @@ class ToEDSpec extends StageSpec(stageCreatesUnrefAnons = true):
878878
|end Foo""".stripMargin
879879
)
880880
}
881+
882+
test("For loop with a register") {
883+
class Foo(
884+
val PORT_WIDTH: Int <> CONST = 5
885+
) extends RTDesign:
886+
val r = Bits(PORT_WIDTH) <> OUT.REG init all(0)
887+
for (i <- 0 until PORT_WIDTH)
888+
r(i).din := 1
889+
for (i <- 0 until PORT_WIDTH)
890+
if (r(PORT_WIDTH - 1 - i))
891+
r(i).din := 0
892+
end Foo
893+
894+
val top = (new Foo()).toED
895+
assertCodeString(
896+
top,
897+
"""|case class Clk_default() extends Clk
898+
|case class Rst_default() extends Rst
899+
|
900+
|class Foo(val PORT_WIDTH: Int <> CONST = 5) extends EDDesign:
901+
| val clk = Clk_default <> IN
902+
| val rst = Rst_default <> IN
903+
| val r = Bits(PORT_WIDTH) <> OUT
904+
| process(clk):
905+
| if (clk.actual.rising)
906+
| if (rst.actual == 1) r :== b"0".repeat(PORT_WIDTH)
907+
| else
908+
| for (i <- 0 until PORT_WIDTH)
909+
| r(i) :== 1
910+
| end for
911+
| for (i <- 0 until PORT_WIDTH)
912+
| if (r((PORT_WIDTH - 1) - i)) r(i) :== 0
913+
| end for
914+
| end if
915+
| end if
916+
|end Foo""".stripMargin
917+
)
918+
}
919+
920+
test("For loop with a register and combinational loop") {
921+
class Foo(
922+
val PORT_WIDTH: Int <> CONST = 5
923+
) extends RTDesign:
924+
val r = Bits(PORT_WIDTH) <> OUT.REG init all(0)
925+
val w = Bits(PORT_WIDTH) <> OUT
926+
for (i <- 0 until PORT_WIDTH)
927+
r(i).din := 1
928+
for (i <- 0 until PORT_WIDTH)
929+
if (r(PORT_WIDTH - 1 - i))
930+
r(i).din := 0
931+
for (i <- 0 until PORT_WIDTH)
932+
w(i) := r(i)
933+
end Foo
934+
935+
val top = (new Foo()).toED
936+
assertCodeString(
937+
top,
938+
"""|case class Clk_default() extends Clk
939+
|case class Rst_default() extends Rst
940+
|
941+
|class Foo(val PORT_WIDTH: Int <> CONST = 5) extends EDDesign:
942+
| val clk = Clk_default <> IN
943+
| val rst = Rst_default <> IN
944+
| val r = Bits(PORT_WIDTH) <> OUT
945+
| val w = Bits(PORT_WIDTH) <> OUT
946+
| val r_din = Bits(PORT_WIDTH) <> VAR
947+
| process(all):
948+
| r_din := r
949+
| for (i <- 0 until PORT_WIDTH)
950+
| r_din(i) := 1
951+
| end for
952+
| for (i <- 0 until PORT_WIDTH)
953+
| if (r((PORT_WIDTH - 1) - i)) r_din(i) := 0
954+
| end for
955+
| for (i <- 0 until PORT_WIDTH)
956+
| w(i) := r(i)
957+
| end for
958+
| process(clk):
959+
| if (clk.actual.rising)
960+
| if (rst.actual == 1) r :== b"0".repeat(PORT_WIDTH)
961+
| else r :== r_din
962+
| end if
963+
|end Foo""".stripMargin
964+
)
965+
}
881966
end ToEDSpec

0 commit comments

Comments
 (0)