Skip to content

Commit 7091585

Browse files
authored
Merge pull request #266 from DFiantHDL/vivado_build
v0.11.2
2 parents ce9b400 + a9a2339 commit 7091585

File tree

15 files changed

+257
-64
lines changed

15 files changed

+257
-64
lines changed

build.sbt

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ inThisBuild(
1919
url("https://twitter.com/soronpo")
2020
)
2121
),
22-
sonatypeCredentialHost := "central.sonatype.com"
2322
)
2423
)
2524

@@ -52,26 +51,12 @@ lazy val internals = project
5251
libraryDependencies ++= commonDependencies
5352
)
5453

55-
def additionalSources(scalaVersion: String, base: File): Seq[File] = {
56-
CrossVersion.partialVersion(scalaVersion) match {
57-
case Some((3, minor)) if minor <= 4 =>
58-
Seq(base / "src" / "main" / "scala-3.4-")
59-
case Some((3, minor)) if minor >= 5 =>
60-
Seq(base / "src" / "main" / "scala-3.5+")
61-
case _ =>
62-
Seq.empty
63-
}
64-
}
6554
lazy val plugin = project
6655
.settings(
6756
name := s"$projectName-plugin",
6857
settings,
6958
crossTarget := target.value / s"scala-${scalaVersion.value}", // workaround for https://github.com/sbt/sbt/issues/5097
7059
crossVersion := CrossVersion.full,
71-
Compile / unmanagedSourceDirectories ++= {
72-
val base = baseDirectory.value
73-
additionalSources(scalaVersion.value, base)
74-
},
7560
libraryDependencies += "org.scala-lang" %% "scala3-compiler" % compilerVersion % "provided"
7661
).dependsOn(internals)
7762

compiler/ir/src/main/scala/dfhdl/compiler/ir/DFRef.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ object IntParamRef:
9696
(intParamRef, that) match
9797
case (thisRef: DFRef.TypeRef, thatRef: DFRef.TypeRef) =>
9898
thisRef.get.isSimilarTo(thatRef.get)
99-
case (thisInt: Int, thatInt: Int) => thisInt == thatInt
99+
case (thisInt: Int, thatInt: Int) => thisInt == thatInt
100100
case (thisRef: DFRef.TypeRef, thatInt: Int) =>
101101
thisRef.get.isSimilarTo(fakeConst(thatInt))
102102
case (thisInt: Int, thatRef: DFRef.TypeRef) =>
@@ -114,16 +114,16 @@ object IntParamRef:
114114
,
115115
json =>
116116
json match
117-
case ujson.Str(s) => read[DFRef.TypeRef](s)
118117
case ujson.Num(n) => n.toInt
118+
case ujson.Str(_) => read[DFRef.TypeRef](json)
119119
case _ => throw new IllegalArgumentException(s"Expected String or Int, got $json")
120120
)
121121
end IntParamRef
122122

123123
extension (intCompanion: Int.type)
124124
def unapply(intParamRef: IntParamRef)(using MemberGetSet): Option[Int] =
125125
(intParamRef: @unchecked) match
126-
case int: Int => Some(int)
126+
case int: Int => Some(int)
127127
case DFRef(dfVal: DFVal) =>
128128
dfVal.getConstData.asInstanceOf[Option[Option[BigInt]]].flatten.map(_.toInt)
129129

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/main/scala/dfhdl/compiler/stages/vhdl/VHDLOwnerPrinter.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,10 @@ protected trait VHDLOwnerPrinter extends AbstractOwnerPrinter:
131131
val dfValDcls =
132132
designMembers.view
133133
.flatMap {
134+
case _ @IteratorDcl() => None
134135
case p: DFVal.Dcl if p.isVar => Some(p)
135136
case _: DesignParam => None
136-
case c @ DclConst() =>
137+
case c @ DclConst() =>
137138
c.dfType match
138139
case DFInt32 => None
139140
case _ => Some(c)
@@ -214,7 +215,7 @@ protected trait VHDLOwnerPrinter extends AbstractOwnerPrinter:
214215
val dcl = csDFMembers(dcls).emptyOr(v => s"\n${v.hindent}")
215216
val named = pb.meta.nameOpt.map(n => s"$n : ").getOrElse("")
216217
val senList = pb.sensitivity match
217-
case Sensitivity.All => " (all)"
218+
case Sensitivity.All => " (all)"
218219
case Sensitivity.List(refs) =>
219220
if (refs.isEmpty) "" else s" ${refs.map(_.refCodeString).mkStringBrackets}"
220221
s"${named}process$senList$dcl\nbegin\n${body.hindent}\nend process;"

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

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class PrintVHDLCodeSpec extends StageSpec:
2020
val id1_y = SInt(16) <> VAR
2121
val id2_x = SInt(16) <> VAR
2222
val id2_y = SInt(16) <> VAR
23-
val id1 = new ID:
23+
val id1 = new ID:
2424
this.x <> id1_x
2525
this.y <> id1_y
2626
val id2 = new ID:
@@ -1306,4 +1306,55 @@ class PrintVHDLCodeSpec extends StageSpec:
13061306
|end Foo_arch;""".stripMargin
13071307
)
13081308
}
1309+
test("for loop with a register printing") {
1310+
class Foo(
1311+
val PORT_WIDTH: Int <> CONST = 5
1312+
) extends RTDesign:
1313+
val r = Bits(PORT_WIDTH) <> OUT.REG init all(0)
1314+
for (i <- 0 until PORT_WIDTH)
1315+
r(i).din := 1
1316+
for (i <- 0 until PORT_WIDTH)
1317+
if (r(PORT_WIDTH - 1 - i))
1318+
r(i).din := 0
1319+
end Foo
1320+
val top = (new Foo).getCompiledCodeString
1321+
assertNoDiff(
1322+
top,
1323+
"""|library ieee;
1324+
|use ieee.std_logic_1164.all;
1325+
|use ieee.numeric_std.all;
1326+
|use work.dfhdl_pkg.all;
1327+
|use work.Foo_pkg.all;
1328+
|
1329+
|entity Foo is
1330+
|generic (
1331+
| PORT_WIDTH : integer := 5
1332+
|);
1333+
|port (
1334+
| clk : in std_logic;
1335+
| rst : in std_logic;
1336+
| r : out std_logic_vector(PORT_WIDTH - 1 downto 0)
1337+
|);
1338+
|end Foo;
1339+
|
1340+
|architecture Foo_arch of Foo is
1341+
|begin
1342+
| process (clk)
1343+
| begin
1344+
| if rising_edge(clk) then
1345+
| if rst = '1' then r <= repeat("0", PORT_WIDTH);
1346+
| else
1347+
| for i in 0 to PORT_WIDTH-1 loop
1348+
| r(i) <= '1';
1349+
| end loop;
1350+
| for i in 0 to PORT_WIDTH-1 loop
1351+
| if r((PORT_WIDTH - 1) - i) then r(i) <= '0';
1352+
| end if;
1353+
| end loop;
1354+
| end if;
1355+
| end if;
1356+
| end process;
1357+
|end Foo_arch;""".stripMargin
1358+
)
1359+
}
13091360
end PrintVHDLCodeSpec

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

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class PrintVerilogCodeSpec extends StageSpec:
2222
val id1_y = SInt(16) <> VAR
2323
val id2_x = SInt(16) <> VAR
2424
val id2_y = SInt(16) <> VAR
25-
val id1 = new ID:
25+
val id1 = new ID:
2626
this.x <> id1_x
2727
this.y <> id1_y
2828
this.y2 <> OPEN
@@ -1221,4 +1221,43 @@ class PrintVerilogCodeSpec extends StageSpec:
12211221
|endmodule""".stripMargin
12221222
)
12231223
}
1224+
test("for loop with a register printing") {
1225+
class Foo(
1226+
val PORT_WIDTH: Int <> CONST = 5
1227+
) extends RTDesign:
1228+
val r = Bits(PORT_WIDTH) <> OUT.REG init all(0)
1229+
for (i <- 0 until PORT_WIDTH)
1230+
r(i).din := 1
1231+
for (i <- 0 until PORT_WIDTH)
1232+
if (r(PORT_WIDTH - 1 - i))
1233+
r(i).din := 0
1234+
end Foo
1235+
val top = (new Foo).getCompiledCodeString
1236+
assertNoDiff(
1237+
top,
1238+
"""|`default_nettype none
1239+
|`timescale 1ns/1ps
1240+
|`include "Foo_defs.svh"
1241+
|
1242+
|module Foo#(parameter int PORT_WIDTH = 5)(
1243+
| input wire logic clk,
1244+
| input wire logic rst,
1245+
| output logic [PORT_WIDTH - 1:0] r
1246+
|);
1247+
| `include "dfhdl_defs.svh"
1248+
| always_ff @(posedge clk)
1249+
| begin
1250+
| if (rst == 1'b1) r <= {PORT_WIDTH{1'b0}};
1251+
| else begin
1252+
| for (int i = 0; i < PORT_WIDTH; i = i + 1) begin
1253+
| r[i] <= 1'b1;
1254+
| end
1255+
| for (int i = 0; i < PORT_WIDTH; i = i + 1) begin
1256+
| if (r[(PORT_WIDTH - 1) - i]) r[i] <= 1'b0;
1257+
| end
1258+
| end
1259+
| end
1260+
|endmodule""".stripMargin
1261+
)
1262+
}
12241263
end PrintVerilogCodeSpec

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

core/src/main/scala/dfhdl/core/DFDecimal.scala

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ object DFDecimal:
330330
): Either[String, (Boolean, Int, Int, BigInt)] =
331331
dec.replace(",", "").replace("_", "") match
332332
case intExp(numStr) => Right(fromIntDecString(numStr, signedForced))
333-
case _ =>
333+
case _ =>
334334
Left(s"Invalid decimal pattern found: $dec")
335335
end match
336336
end fromDecString
@@ -916,6 +916,27 @@ object DFXInt:
916916
def >>[P](shift: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, CONST | P] = trydf {
917917
DFVal.Func(DFInt32, FuncOp.>>, List(DFConstInt32(lhs), shift)).asValTP[DFInt32, P]
918918
}
919+
def +[P](rhs: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, P] = trydf {
920+
DFVal.Func(DFInt32, FuncOp.+, List(DFConstInt32(lhs), rhs)).asValTP[DFInt32, P]
921+
}
922+
def -[P](rhs: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, P] = trydf {
923+
DFVal.Func(DFInt32, FuncOp.-, List(DFConstInt32(lhs), rhs)).asValTP[DFInt32, P]
924+
}
925+
def *[P](rhs: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, P] = trydf {
926+
DFVal.Func(DFInt32, FuncOp.`*`, List(DFConstInt32(lhs), rhs)).asValTP[DFInt32, P]
927+
}
928+
def /[P](rhs: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, P] = trydf {
929+
DFVal.Func(DFInt32, FuncOp./, List(DFConstInt32(lhs), rhs)).asValTP[DFInt32, P]
930+
}
931+
def %[P](rhs: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, P] = trydf {
932+
DFVal.Func(DFInt32, FuncOp.%, List(DFConstInt32(lhs), rhs)).asValTP[DFInt32, P]
933+
}
934+
def max[P](rhs: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, P] = trydf {
935+
DFVal.Func(DFInt32, FuncOp.max, List(DFConstInt32(lhs), rhs)).asValTP[DFInt32, P]
936+
}
937+
def min[P](rhs: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, P] = trydf {
938+
DFVal.Func(DFInt32, FuncOp.min, List(DFConstInt32(lhs), rhs)).asValTP[DFInt32, P]
939+
}
919940
def **[P](shift: DFValTP[DFInt32, P])(using dfc: DFC): DFValTP[DFInt32, P] = trydf {
920941
DFVal.Func(DFInt32, FuncOp.**, List(DFConstInt32(lhs), shift)).asValTP[DFInt32, P]
921942
}

core/src/main/scala/dfhdl/core/DFRef.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import dfhdl.compiler.analysis.DclPort
44

55
import scala.annotation.targetName
66
extension [M <: ir.DFMember](member: M)
7-
private def injectGlobalCtx()(using DFC): Unit =
7+
private[dfhdl] def injectGlobalCtx()(using DFC): Unit =
88
import dfc.getSet
99
member match
1010
case dfVal: ir.DFVal.CanBeGlobal if dfVal.isGlobal =>

0 commit comments

Comments
 (0)