浏览代码

JANK

master
peteraa 6 年前
父节点
当前提交
80e27b313c
共有 19 个文件被更改,包括 419 次插入66 次删除
  1. 二进制
      Images/ChiselConditional.png
  2. 二进制
      Images/ScalaCond1.png
  3. +7
    -2
      build.sbt
  4. +5
    -0
      convert.sh
  5. +2
    -0
      hdl.org
  6. +0
    -2
      introduction.org
  7. 二进制
      pngs/0
  8. +5
    -1
      project/Dependencies.scala
  9. +1
    -1
      project/build.properties
  10. +3
    -2
      src/main/scala/Vector.scala
  11. +0
    -0
      src/main/scala/fileUtils.scala
  12. +1
    -0
      src/main/scala/main.scala
  13. +0
    -42
      src/test/scala/Example.scala
  14. +39
    -0
      src/test/scala/Examples/basic.scala
  15. +51
    -0
      src/test/scala/SVGSpec.scala
  16. +143
    -0
      src/test/scala/TestUtils.scala
  17. +19
    -16
      src/test/scala/VectorSpec.scala
  18. +0
    -0
      src/test/scala/svgRender.scala
  19. +143
    -0
      svgOutput/0.svg

二进制
Images/ChiselConditional.png 查看文件

之前 之后
宽度: 446  |  高度: 306  |  大小: 9.9KB

二进制
Images/ScalaCond1.png 查看文件

之前 之后
宽度: 585  |  高度: 322  |  大小: 12KB

+ 7
- 2
build.sbt 查看文件

@@ -24,11 +24,11 @@ def javacOptionsVersion(scalaVersion: String): Seq[String] = {
}
}

name := "chisel-module-template"
name := "chisel intro"

version := "3.1.0"

scalaVersion := "2.12.4"
scalaVersion := "2.12.8"

crossScalaVersions := Seq("2.11.12", "2.12.4")

@@ -66,3 +66,8 @@ addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.fu


testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-eS")

run := Defaults.runTask(fullClasspath in Runtime, mainClass in run in Compile, runner in run).evaluated

cancelable in Global := true
fork := true

+ 5
- 0
convert.sh 查看文件

@@ -0,0 +1,5 @@
#!/bin/bash
parallel inkscape -f {} -e pngs/{.} ::: svgOutput/*.svg

mv ./pngs/svgOutput/* ./pngs/
rm -rf ./pngs/svgOutput

+ 2
- 0
hdl.org 查看文件

@@ -0,0 +1,2 @@
* Hardware description languages

+ 0
- 2
introduction.org 查看文件

@@ -139,8 +139,6 @@
This is done by creating a test program where the test runner drives inputs and reads outputs from
the module using what is called a peek poke tester.

*** Creating a peek poke tester
#+begin_src scala
class TheTestRunner(c: MyIncrement) extends PeekPokeTester(c) {


二进制
pngs/0 查看文件

之前 之后
宽度: 794  |  高度: 1123  |  大小: 13KB

+ 5
- 1
project/Dependencies.scala 查看文件

@@ -35,6 +35,10 @@ object Dependencies {

"com.github.pathikrit" %% "better-files" % "3.7.0",

"org.atnos" %% "eff" % "5.2.0"
"org.atnos" %% "eff" % "5.2.0",


"org.scala-lang.modules" %% "scala-swing" % "2.1.1",
"org.apache.xmlgraphics" % "batik-swing" % "1.11"
))
}

+ 1
- 1
project/build.properties 查看文件

@@ -1 +1 @@
sbt.version = 1.1.0
sbt.version = 1.2.8

+ 3
- 2
src/main/scala/Vector.scala 查看文件

@@ -9,7 +9,8 @@ class Vector(val elements: Int) extends Module {
new Bundle {
val idx = Input(UInt(32.W))
val dataIn = Input(UInt(32.W))
val writeEnable = Input(Bool())
// val writeEnable = Input(Bool())
val readEnable = Input(Bool())

val dataOut = Output(UInt(32.W))
}
@@ -19,7 +20,7 @@ class Vector(val elements: Int) extends Module {
val internalVector = RegInit(VecInit(List.fill(elements)(0.U(32.W))))


when(writeEnable){
when(io.readEnable){
// TODO:
// When writeEnable is true the content of internalVector at the index specified
// by idx should be set to the value of io.dataIn


+ 0
- 0
src/main/scala/fileUtils.scala 查看文件


+ 1
- 0
src/main/scala/main.scala 查看文件

@@ -9,3 +9,4 @@ object main {
println(s)
}
}


+ 0
- 42
src/test/scala/Example.scala 查看文件

@@ -1,42 +0,0 @@







// class DPCsimulatorSpec extends FlatSpec with Matchers {

// case class DotProdCalculator(vectorLen: Int, timeStep: Int = 0, accumulator: Int = 0){
// def update(inputA: Int, inputB: Int): (Int, Boolean, DotProdCalculator) = {
// val product = inputA * inputB
// if(((timeStep + 1) % vectorLen) == 0)
// (accumulator + product, true, this.copy(timeStep = 0, accumulator = 0))
// else
// (accumulator + product, false, this.copy(timeStep = this.timeStep + 1, accumulator = accumulator + product))
// }
// }

// val myDPC = DotProdCalculator(4)
// val dpcStream = Stream.iterate((0, myDPC)){ case(ts, dpc) =>
// val a = scala.util.Random.nextInt(4)
// val b = scala.util.Random.nextInt(4)
// val (output, valid, nextDPC) = dpc.update(a, b)
// val validString = if(valid) "yes" else "no"
// println(s"at timestep $ts:")
// println(s"INPUTS:")
// println(s"inputA: $a, inputB: $b")
// println(s"OUTPUTS:")
// println(s"output: $output, valid: $validString\n\n")

// (ts + 1, nextDPC)
// }.take(20)


// behavior of "Dot product simulator"

// it should "Be shoehorned into a test" in {
// dpcStream.last
// }
// }


+ 39
- 0
src/test/scala/Examples/basic.scala 查看文件

@@ -94,3 +94,42 @@ class MyIncrementManyTest extends FlatSpec with Matchers {
} should be(true)
}
}



class ChiselConditional() extends Module {
val io = IO(
new Bundle {
val a = Input(UInt(32.W))
val b = Input(UInt(32.W))
val opSel = Input(Bool())

val out = Output(UInt(32.W))
}
)

when(io.opSel){
io.out := io.a + io.b
}.otherwise{
io.out := io.a - io.b
}
}



class ScalaConditional(opSel: Boolean) extends Module {
val io = IO(
new Bundle {
val a = Input(UInt(32.W))
val b = Input(UInt(32.W))

val out = Output(UInt(32.W))
}
)

if(opSel){
io.out := io.a + io.b
} else {
io.out := io.a - io.b
}
}

+ 51
- 0
src/test/scala/SVGSpec.scala 查看文件

@@ -0,0 +1,51 @@
package Ex0

import chisel3._
import chisel3.experimental._
import chisel3.iotesters.PeekPokeTester
import org.scalatest.{Matchers, FlatSpec}
import TestUtils._

import scala.collection.immutable.{ Vector => _ }

class SVGSpec extends FlatSpec with Matchers {
import AdderTests._

behavior of "Adder"

it should "Make some sweet pngs" in {
// FileUtils.getSvg("Adder")
wrapTester(
chisel3.iotesters.Driver(() => new Adder()) { c =>
new AdderTester(c)
} should be(true)
)
}

}

class Adder() extends Module {
val io = IO(
new Bundle {
val reg_a = Output(UInt(32.W))
}
)

val reg_a = RegInit(0.U(8.W))
reg_a := reg_a + 1.U

io.reg_a := reg_a
}

object AdderTests {
class AdderTester(c: Adder) extends PeekPokeTesterLogger(c) {
override def ioLoggers = List(c.io)

for(ii <- 0 until 10){
step(1)
}

writeLog
}
}

+ 143
- 0
src/test/scala/TestUtils.scala 查看文件

@@ -1,6 +1,7 @@
package Ex0

import chisel3._
import chisel3.experimental._
import chisel3.iotesters.PeekPokeTester
import org.scalatest.{Matchers, FlatSpec}

@@ -42,4 +43,146 @@ object TestUtils {
case e: Exception => throw e
}
}

abstract class PeekPokeTesterLogger[T <: MultiIOModule](dut: T) extends PeekPokeTester(dut){
def ioLoggers: List[chisel3.Bundle]
import scala.collection.mutable._
private val log = ArrayBuffer[LinkedHashMap[String, BigInt]]()
override def step(n: Int): Unit = {
ioLoggers.foreach{ ioLogger => log.append(peek(ioLogger)) }
super.step(n)
}
def getLog = log
def writeLog = {
import cats.effect.IO
import SVGRender._
val moduleName: String = dut.getClass.getSimpleName
createSvgs(moduleName, getLog.toList).unsafeRunSync()
}
}
}


import java.io.File
import java.nio.file.Path
import scala.collection.mutable.LinkedHashMap

import cats.effect.IO
import cats.implicits._
import fs2._
import fs2.io
import fs2.text

object FileUtils {

def say(word: Any)(implicit filename: sourcecode.File, line: sourcecode.Line): Unit = {
val fname = filename.value.split("/").last
println(Console.YELLOW + s"[${fname}: ${sourcecode.Line()}]" + Console.RESET + s" - $word")
}

def getListOfFiles(dir: String): List[File] =
(new File(dir)).listFiles.filter(_.isFile).toList

def getListOfFiles(dir: Path): List[File] =
dir.toFile().listFiles.filter(_.isFile).toList

def getListOfFolders(dir: String): List[File] =
(new File(dir)).listFiles.filter(_.isDirectory).toList

def getListOfFolders(dir: Path): List[File] =
dir.toFile().listFiles.filter(_.isDirectory).toList

def getListOfFilesRecursive(dir: String): List[File] = {
getListOfFiles(dir) ::: getListOfFolders(dir).flatMap(f =>
getListOfFilesRecursive(f.getPath)
)
}

import java.nio.file.Paths
import java.util.concurrent.Executors

def relativeFile(name: String) = {
new File(getClass.getClassLoader.getResource(name).getPath)
}

def getSvgDir: File =
new File(getClass.getClassLoader.getResource("svgs").getPath)

def getAllSvgs: List[File] =
getListOfFilesRecursive(getSvgDir.getPath).filter( f => f.getPath.endsWith(".svg") )


import scala.concurrent.ExecutionContext
val EC = ExecutionContext.fromExecutorService(Executors.newFixedThreadPool(10))
implicit val cs = IO.contextShift(EC)
import scala.concurrent.ExecutionContext


def writeSvg(source: String, cycle: Int): Pipe[IO,String,Unit] = {
import sys.process._
say("pwd".!)
// val svgDir = getSvgDir.toPath.toString + s"/${source}Output"
val svgDir = "pwd".!!.filter(_ >= ' ') + s"/svgOutput"
(new File(svgDir)).mkdir()
val svgDest = new File(svgDir + s"/$cycle.svg").toPath

svgStream => svgStream
.through(text.utf8Encode)
.through(fs2.io.file.writeAll(svgDest, EC))
}
def getSvg(moduleName: String): Stream[IO, String] = {
say(getAllSvgs)
say(moduleName)
val file = getAllSvgs.filter(_.toPath.toString.contains(moduleName)).head
io.file.readAll[IO](file.toPath(), EC, 4096)
.through(text.utf8Decode)
.through(text.lines)
}
}



import java.io.File
import java.nio.file.Path
import scala.collection.mutable.LinkedHashMap

import chisel3._
import chisel3.iotesters.PeekPokeTester
import chisel3.experimental.MultiIOModule


object SVGRender {

import FileUtils._

import fs2._
import cats.effect.IO
import scala.collection.mutable.LinkedHashMap

def editFields(line: String, chiselVals: LinkedHashMap[String,BigInt]): String =
line.split("(?=>)")
.flatMap(_.split("(?=<)"))
.map{ subString =>
if(subString.endsWith("_field")){
val name = subString.dropRight(6)
val chiselVal = chiselVals.lift(name.drop(1).toLowerCase).map(_.toString).getOrElse("UNKNOWN")
s"$name = $chiselVal"
}
else
subString
}.mkString + "\n"


def editSvg(fieldValues: LinkedHashMap[String,BigInt]): Pipe[IO, String, String] =
_.map(line => editFields(line, fieldValues))

def createSvgs(moduleName: String, snapshots: List[LinkedHashMap[String,BigInt]]): IO[Unit] = {
val svgSinks: List[Pipe[IO, String, Unit]] = snapshots.zipWithIndex.map{ case(lhm, idx) =>
editSvg(lhm) andThen FileUtils.writeSvg(moduleName, idx)
}

getSvg(moduleName).broadcastTo(svgSinks:_*).compile.drain
}
}

+ 19
- 16
src/test/scala/VectorSpec.scala 查看文件

@@ -1,6 +1,7 @@
package Ex0

import chisel3._
import chisel3.experimental._
import chisel3.iotesters.PeekPokeTester
import org.scalatest.{Matchers, FlatSpec}
import TestUtils._
@@ -15,6 +16,7 @@ class VectorSpec extends FlatSpec with Matchers {
behavior of "Vector"

it should "Not read data when read enable is false" in {
// FileUtils.getSvg("Adder")
wrapTester(
chisel3.iotesters.Driver(() => new Vector(elements)) { c =>
new ReadEnable(c)
@@ -22,25 +24,26 @@ class VectorSpec extends FlatSpec with Matchers {
)
}

it should "Update its registers when read enable is true" in {
wrapTester(
chisel3.iotesters.Driver(() => new Vector(elements)) { c =>
new UpdatesData(c)
} should be(true)
)
}
it should "Retain its data once read enable is set to false" in {
wrapTester(
chisel3.iotesters.Driver(() => new Vector(elements)) { c =>
new UpdatesData(c)
} should be(true)
)
}
// it should "Update its registers when read enable is true" in {
// wrapTester(
// chisel3.iotesters.Driver(() => new Vector(elements)) { c =>
// new UpdatesData(c)
// } should be(true)
// )
// }
// it should "Retain its data once read enable is set to false" in {
// wrapTester(
// chisel3.iotesters.Driver(() => new Vector(elements)) { c =>
// new RetainsData(c)
// } should be(true)
// )
// }
}

object VectorTests {

object VectorTests {
class ReadEnable(c: Vector) extends PeekPokeTester(c) {

poke(c.io.dataIn, 123)


+ 0
- 0
src/test/scala/svgRender.scala 查看文件


+ 143
- 0
svgOutput/0.svg 查看文件

@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (unknown)"
sodipodi:docname="svg_test3.svg">
<defs
id="defs2">
<inkscape:path-effect
is_visible="true"
id="path-effect1515"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect1494"
is_visible="true" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="489.50694"
inkscape:cy="789.09773"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1916"
inkscape:window-height="1149"
inkscape:window-x="2280"
inkscape:window-y="400"
inkscape:window-maximized="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect815"
width="42.228577"
height="35.546844"
x="33.408691"
y="25.988699" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 33.408691,25.988699 H 75.637268 V 61.535543 H 61.905124 L 54.52298,55.676912 47.140835,61.535543 H 33.408691 Z"
id="rect1510"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.79374999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 46.931991,88.529769 h 24.78925 L 85.927158,99.1131 100.13308,88.529769 h 24.78925 L 114.33899,117.39488 H 57.515325 Z"
id="rect1489"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.06500006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 57.997486,61.535545 V 88.529767"
id="path1492"
inkscape:connector-curvature="0"
inkscape:path-effect="#path-effect1494"
inkscape:original-d="m 57.997486,61.535545 c 2.65e-4,8.997809 2.65e-4,17.995884 0,26.994222"
transform="translate(7.9375,-0.1889881)" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.065;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 86.328056,117.12761 v 21.9161 H 153.67998 V 44.430296 H 75.370006"
id="path1500"
inkscape:connector-curvature="0" />
<flowRoot
xml:space="preserve"
id="Reg_A"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.0000002px;line-height:125%;font-family:Verdana;-inkscape-font-specification:'Verdana, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;"
transform="scale(0.26458333)"
inkscape:label="Reg_A_value"><flowRegion
id="flowRegion1504"
style="-inkscape-font-specification:'Verdana, Normal';font-family:Verdana;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:16.0000002px;text-anchor:start;text-align:start;writing-mode:lr;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;"><rect
id="rect1506"
width="138.39091"
height="21.213207"
x="139.40105"
y="122.97374"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16.0000002px;font-family:Verdana;-inkscape-font-specification:'Verdana, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr;text-anchor:start;" /></flowRegion><flowPara
id="flowPara1615">Reg_A = 0</flowPara></flowRoot> <path
transform="translate(49.420387,-0.1889881)"
inkscape:original-d="m 57.997486,61.535545 c 2.65e-4,8.997809 2.65e-4,17.995884 0,26.994222"
inkscape:path-effect="#path-effect1515"
inkscape:connector-curvature="0"
id="path1513"
d="M 57.997486,61.535545 V 88.529767"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.06500006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<flowRoot
xml:space="preserve"
id="flowRoot1517"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:37.33333206px;line-height:125%;font-family:Verdana;-inkscape-font-specification:'Verdana, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
transform="scale(0.26458333)"><flowRegion
id="flowRegion1519"><rect
id="rect1521"
width="92.5"
height="38.57143"
x="416.42856"
y="222.16254" /></flowRegion><flowPara
id="flowPara1523">1</flowPara></flowRoot> <flowRoot
xml:space="preserve"
id="flowRoot1525"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:37.33333206px;line-height:125%;font-family:Verdana;-inkscape-font-specification:'Verdana, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
transform="scale(0.26458333)"><flowRegion
id="flowRegion1527"><rect
id="rect1529"
width="117.14286"
height="74.64286"
x="416.07144"
y="219.66254" /></flowRegion><flowPara
id="flowPara1531"
style="-inkscape-font-specification:'Verdana, Normal';font-family:Verdana;font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;font-size:21.3333336px;text-anchor:start;text-align:start;writing-mode:lr;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal">1</flowPara></flowRoot> </g>
</svg>


正在加载...
取消
保存