Building Your First Process
In this tutorial, you’ll build a more complex process that receives data, processes it, and sends results. This demonstrates the core concepts of Weaver processes.
What You’ll Learn
- How to receive data on channels
- Processing data in a loop
- Combining multiple operations
Step 1: Create a Collatz Process
Let’s create a process that receives numbers and emits the entire Collatz sequence for that number.
[!WARNING] There are still quite a few bugs to work through in synthesis, this will generate a lot of errors and produce incorrect results.
[!WARNING] Loom does not yet have a true type system or support for templates. There is only a very basic set of types with manual bitwidths at the moment:
chan,fixed,ufixed,bool.
func Collatz(chan In, Out) {
var fixed value = 1
while {
if value <= 1 {
value = In.recv()
} or if value > 1 && value % 2 == 0 {
value = value / 2
Out.send(value)
} or if value > 1 && value % 2 == 1 {
value = 3 * value + 1
Out.send(value)
}
}
}
Let’s examine each part:
func Collatz(chan In, Out)- defines the Collatz process with input In and output Out.var fixed value = 1- stores the current number, starting at 1.while { … }- runs forever.if value <= 1- get a new number fromIn.if value > 1 && even- divide by 2, send result toOut.if value > 1 && odd- multiply by 3 and add 1, send result toOut.
Step 2: Build and Test
Compile your process:
lm build
If successful, you should see no errors. The compiled Verilog will be in
build/rtl/Collatz.v. The process is now ready to be used in larger designs.
You can also list your modules:
lm mod show
This will show:
top:Collatz(chan,chan)
top:Counter(chan)
Step 3: Create a Complete System
[!WARNING] Process instantiation is not yet functional,
top()will be empty.
Let’s create a system that uses both a counter and our doubler. Update top.wv:
func Counter(chan Out) {
var fixed count = 0
while {
Out.send(count)
count = count + 1
if count == 255 {
count = 0
}
}
}
func Collatz(chan In, Out) {
var fixed value = 1
while {
if value <= 1 {
value = In.recv()
} or if value > 1 && value % 2 == 0 {
value = value / 2
Out.send(value)
} or if value > 1 && value % 2 == 1 {
value = 3 * value + 1
Out.send(value)
}
}
}
func top(chan Out) {
var chan C
Counter(C) and
Collatz(C, Out)
}
In the top function, we:
- Declare channels to connect processes
- Instantiate the
Counterprocess, connecting its output toC - Instantiate the
Collatzprocess, takingCas input and producingOut
The processes run in parallel, with data flowing from Counter to Collatz.
Step 4: Build the System
lm build
This compiles the entire system. You’ll find:
build/rtl/Counter.vbuild/rtl/Collatz.v
Step 5: List Your Modules
See all available modules:
lm mod show
This will show:
top:Counter(chan)
top:Collatz(chan,chan)
top:top(chan)
Step 6: Inspect the System
To generate a guarded petri-net image for all processes:
lm show
This will create:
build/dbg/Collatz.png
build/dbg/top.png
build/dbg/Counter.png
Or you can see a single process
lm show "top:Collatz(chan,chan)"
which will create
./Collatz.png
Key Concepts Learned
In.recv()receives and removes data from a channel- Processes can be composed by connecting their channels
- Multiple processes run in parallel in Weaver
What’s Next?
Now that you understand basic processes, learn about:
- More advanced channel communication patterns
- Using
orandxorfor conditional behavior - Working with custom types
Continue to Working with Channels to explore channel communication in depth.