aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazidar2015-02-24 16:30:40 -0800
committerazidar2015-02-24 16:30:40 -0800
commitd0dddb37c056647e7fed4e9771650ef41f85bae3 (patch)
tree8a72fc312aa8a0338b331454ce66fb9c81b173c6
parent2353d640907a7b04477b06a5b3da6b7bbafc448d (diff)
Rewrote README to include installation instructions and stanza justification. Added response to feedback, locatd in notes/feedbackQA*. Use two different mains, one for testing and one for deployment (make build vs make build-deploy).
-rw-r--r--Makefile13
-rw-r--r--README.md52
-rw-r--r--TODO9
-rw-r--r--notes/feedbackQA.02.24.15.docbin0 -> 35328 bytes
-rw-r--r--notes/feedbackQA.02.24.15.txt84
-rw-r--r--src/main/stanza/firrtl-main.stanza2
-rw-r--r--src/main/stanza/firrtl-test-main.stanza33
-rw-r--r--src/main/stanza/passes.stanza10
-rw-r--r--test/passes/infer-types/primops.fir5
9 files changed, 169 insertions, 39 deletions
diff --git a/Makefile b/Makefile
index 0dbca93e..4259b7ec 100644
--- a/Makefile
+++ b/Makefile
@@ -6,16 +6,19 @@ firrtl_dir ?= $(root_dir)/src/main/stanza
all: build check
-install-stanza:
+install:
+ cd src/lib && unzip stanzam.zip
+ cd stanzam && sudo ./stanzam -platform os-x -install /usr/local/bin/stanzam
-build:
+build-deploy:
cd $(firrtl_dir) && stanzam -i firrtl-main.stanza -o $(root_dir)/utils/bin/firrtl
-# Runs single test
+build:
+ cd $(firrtl_dir) && stanzam -i firrtl-test-main.stanza -o $(root_dir)/utils/bin/firrtl
+
check:
cd $(test_dir)/passes && lit -v . --path=$(root_dir)/utils/bin/
clean:
- rm -f $(test_dir)/passes/*/*.out
- rm -f $(test_dir)/passes/*.out
+ rm -f $(test_dir)/*/*/*.out
rm -f $(test_dir)/*/*.out
diff --git a/README.md b/README.md
index ef050aae..8038a1f0 100644
--- a/README.md
+++ b/README.md
@@ -1,33 +1,39 @@
# firrtl
Flexible Internal Representation for RTL
-General TODO:
- Add instructions to install stanzam
- Run directory structure past Patrick
- Go over .gitignore
- Write makefile for installation
- Add instructions to compile firrtl
-
-Work TODO:
- Reimplement to-working-ir
- Write printer function
- Make compilation of txt file an argument, not hardcoded
-
-Secondary TODO:
- Need stanza version control - perhaps a sub-repo?
-
-Install lit:
- pip install lit
+Description:
+
+This repository contains the compiler for .firrtl files.
+It is currently being developed in stanza, with the end-goal to translate into scala for ease of other people to use.
+This decision was made for multiple reasons:
+ (1) previous development had already been done in stanza
+ (2) most of the passes are relatively language independent
+ (3) stanza is easier to develop in than scala bc less-strict type system
+ (4) as a favor, its useful to develop in stanza to give Patrick some language tips :)
+The hardest part to port will likely be the parser, but we hope to use an scala parser for the port.
+Installation instructions:
-Stanza Installation:
+-- Disclaimer: This project is going through development stages so there is no guarantee anything works.
+
+-- These installations are for a mac. Won't work for a Unix-based system.
+ `
+ ; Clone repository
git clone https://github.com/ucb-bar/firrtl
- cd src/lib
- unzip stanzam.zip
- cd stanzam
- sudo ./stanzam -platform os-x -install /usr/local/bin/stanzam
+
+ ; Stanza installation
+ make install
+ ; Install lit <- this assumes you have pip installed
+ pip install lit
+
+ ; Build firrtl
+ make build
+ ; Run tests
+ make check
+ ; Build & test
+ make
+ `
-
diff --git a/TODO b/TODO
index 722f395f..46d0f5bf 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,10 @@
+
TODO
-Make stanza a git repo
-Write installation instructions for stanza
-Need 2 different prints, one with IR-internal information, and another that matches correct FIRRTL
+ Make stanza a git repo
+ Write installation instructions for stanza
+ Need 2 different prints, one with IR-internal information, and another that matches correct FIRRTL
+ Figure out how types and widths propogate for all updated primops
+ node not parsed for stmts
Tests:
Error if declare anything other than module in circuit
diff --git a/notes/feedbackQA.02.24.15.doc b/notes/feedbackQA.02.24.15.doc
new file mode 100644
index 00000000..abb8272b
--- /dev/null
+++ b/notes/feedbackQA.02.24.15.doc
Binary files differ
diff --git a/notes/feedbackQA.02.24.15.txt b/notes/feedbackQA.02.24.15.txt
new file mode 100644
index 00000000..d9cfe21d
--- /dev/null
+++ b/notes/feedbackQA.02.24.15.txt
@@ -0,0 +1,84 @@
+LIST OF FEEDBACK, QUESTIONS, AND ANSWERS
+
+Q1. Bundles seem a bit odd -- I don't really like the idea this implicit direction thing.
+A1. We agree that using the same names for port and bundle directions is confusing, we will will change the direction names for bundle fields
+
+Q2. Why are there nodes? Can't these just be wires?
+A2. Nodes are names of intermediate results, while wires have complicated semantics because you can connect to a wire. The compiler deals with nodes in a simpler way, because it knows nothing can connect to it. This means the compiler will run faster, and we can provide a checking mechanism if users try to connect to a node when they shouldn’t.
+Example:
+ x + y := UInt(10) ; This should cause an error!
+ =>
+ node temp = x + y
+ temp := UInt(1) ; Since the compiler will generate a node temp, this will get cause
+
+Q3. There's some ambiguity in the spec as to how you refer to integers -- sometimes you mean a literal integer, and sometimes either Int or UInt.
+A3. Could you point to specific cases? Some confusion may be that the first two pages contain the ABSTRACT syntax definition, while later in the spec (Section 11) describes the concrete syntax.
+
+Q4. Why are there memories? Can't these just be vectors of registers? Or I guess registers of a vector type?
+A4. No, registers have their own semantics (.init fields), and have index expressions (.2). These are not valid for memories. You can have a register of vector type, but not a vector of registers – by making vector a type, its easier to write the compiler to correctly handle Vec[Vec] type.
+
+Q5. Are memories sequential or combinational? This seems to be a sticking point of all other HDLs...
+A5. Good point. We will add a new field to the Mem construct for specifying sequential or combinational. This will be dealt with in whichever backend is used.
+
+Q6. I don't understand the purpose of the "letrec" form, it seems like you've just got two entire copies of the language stuck together. Would it be possible to define the lowered form as something that looks closer to the regular form, so everyone doesn't have to implement all their transformations twice?
+Q7. Agreed, it is not that pretty. The reason for the apparent duplication of the language is to express two different representations of construction of a graph. The higher form separates declaring a structure, and connecting to it. Although this is easier to write/generate, it is much harder to write passes because identifying the inputs/outputs of structures is non-trivial.
+ However, the lowered form is a specialized usage of the letrec, where all structural elements and their inputs are declared at the same time. This is easier for writing passes, but harder to generate. Thus, we merged the two specifications using the letrec construct.
+ You won’t have to write two versions of each pass – passes should either operate at the higher or lower form. However, it would be useful to go through some potential passes and explain how generally we imagine they would be written.
+ To make all this less confusing, we can change the concrete syntax of all structural elements so they look less like expressions/statements.
+
+Q8. There seem to be some convenience features in FIRRTL that I don't think should be there -- specifically, things that might make this easier to write as human-written language that end up making FIRRTL less strict and therefor harder to write generators for:
+* Modules have an implicit reset port that can also be declared. This just seems like a recipe for disaster -- someone is going to not know this, and then declare a field called reset, which FIRRTL won't throw an error for but will instead just change the behavior of all the existing nodes in the circuit.
+A8. No it won’t – there will be a pass ensuring that reset is a 1-bit UInt.
+
+* Lots of the "Primitive Operations" can be constructed from others in trivial ways, which just adds more boilerplate code to anything that has to walk a FIRRTL graph. Specifically:
+ - concat
+ - bit
+ - add/sub (or add-mod/sub-mod)
+ - lt/leq/gt/geq, pad
+ - multiplex
+A8. These are included to allow backends to treat them differently, if needed. For example, if compiling to run on x86, we want to keep these ops around so it can generate more optimal code.
+
+* Can things like "bits" or "pad" take "?" as the width argument? That would be very useful for generators.
+A8. Can you provide an example for when you would want to extract an unknown number of bits?
+
+* I don't like the implicit growth, I'd argue that it should be explicit. Particularly if you support something like
+
+ add(pad(a, ?), pad(b, ?))
+
+ for saying "these widths may be different, just expand one to make them match" then you could still easily have your generator use the weaker version but allow generators that think they know their widths a bit better to get error messages from the compiler.
+
+A8. Assuming width growth is the common case, then the firttl code will have pad(a,?) everywhere, which is annoying. However, we did come up with an example where implicit growth silently hides an error:
+Example:
+module Counter :
+ input enable : UInt(1)
+ output out : UInt(3)
+ reg r : UInt
+ when enable :
+ r := r + 1
+ r.init := 0
+ out := r
+In this case, r will toggle between 0 and 1, when in reality we want it to fail because the size of the counter should ideally be 3 bits. Thus, we will play around with non-implicit growth and get back to you.
+
+Q9. It feels funny you have things like "ltu", but then not the same for
+"rsh".
+A9. We will get rid of the generics, and instead add all combinations (i.e. adduu, addus, addss, ltuu, ltus etc.)
+
+Q10. There's no way to do assertions. It'd be great to have both static
+and dynamic assertions.
+A10. What do you mean by static? Can you give me an example? We will add a dynamic assertion.
+
+Q11. How would one convert from a signed integer to an unsigned integer?
+A11. We will add this convert operation to the primop.
+
+Future questions to answer:
+Introduction – motivation, and intended usage
+Philosophical justifications for all constructs
+More introduction for types, e.g. what is a ground type?
+What is a statement? What is an expression? What is a memory? Difference between vector type and memory? What are accessors for?
+Why would I ever write an empty statement? Mainly for use by compiler/passes
+What is a structural element? Duplication?
+Subtracting two unsigned numbers… Should talk to a math guy to figure it out
+What are shift left and shift right operations? HW doesn’t have these concepts. Need justification.
+What is lowered form? What is it for?
+
+
diff --git a/src/main/stanza/firrtl-main.stanza b/src/main/stanza/firrtl-main.stanza
index 1f87b1da..4c7ecaab 100644
--- a/src/main/stanza/firrtl-main.stanza
+++ b/src/main/stanza/firrtl-main.stanza
@@ -9,7 +9,7 @@ include("ir-parser.stanza")
include("passes.stanza")
include("widthsolver.stanza")
-defpackage chmain :
+defpackage firrtl-main :
import core
import verse
import firrtl.parser
diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza
new file mode 100644
index 00000000..8904bd27
--- /dev/null
+++ b/src/main/stanza/firrtl-test-main.stanza
@@ -0,0 +1,33 @@
+include<"core/stringeater.stanza">
+include<"compiler/lexer.stanza">
+include<"compiler/parser.stanza">
+include<"compiler/rdparser2.stanza">
+include<"compiler/macro-utils.stanza">
+include("firrtl-ir.stanza")
+include("ir-utils.stanza")
+include("ir-parser.stanza")
+include("passes.stanza")
+include("widthsolver.stanza")
+
+defpackage firrtl-main :
+ import core
+ import verse
+ import firrtl.parser
+ import firrtl.passes
+ import stanza.lexer
+ import stanza.parser
+ import firrtl.ir-utils
+
+public var PRINT-TYPES : True|False = false
+
+defn main () :
+ val arg = commandline-arguments()
+ val args = split(arg,' ')
+ val lexed = lex-file(args[1])
+ val c = parse-firrtl(lexed)
+ ;println(c)
+ run-passes(c,to-list(args[2]))
+
+main()
+
+
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index f1c9b248..4a5634d0 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -4,6 +4,7 @@ defpackage firrtl.passes :
import firrtl.ir2
import firrtl.ir-utils
import widthsolver
+ import firrtl-main
;============== EXCEPTIONS =================================
defclass PassException <: Exception
@@ -62,11 +63,10 @@ defmethod print (o:OutputStream, k:Kind) :
(k:StructuralMemKind) : "smem:"
defmethod print (o:OutputStream, e:WRef) :
- match(type(e)) :
- (t:UnknownType) :
- print-all(o,[kind(e) name(e)])
- (t) :
- print-all(o,[kind(e) name(e) ":" type(e)])
+ if PRINT-TYPES :
+ print-all(o,[kind(e) name(e) ":" type(e)])
+ else :
+ print-all(o,[kind(e) name(e)])
defmethod print (o:OutputStream, e:WField) :
print-all(o,[exp(e) "." name(e)])
diff --git a/test/passes/infer-types/primops.fir b/test/passes/infer-types/primops.fir
index fa0f0c90..dc47d9c6 100644
--- a/test/passes/infer-types/primops.fir
+++ b/test/passes/infer-types/primops.fir
@@ -4,5 +4,6 @@
circuit top :
module top :
wire io : {input x : UInt, output y : UInt}
- io.x := add(io.x,io.y)
-;CHECK: n:io:{input x : UInt, output y : UInt}.x := add(n:io:{input x : UInt, output y : UInt}.x, n:io:{input x : UInt, output y : UInt}.y)
+ wire a : UInt
+ a := io.x
+