Skip to content

Commit

Permalink
PIFO, FIFO: command peek (#1657)
Browse files Browse the repository at this point in the history
  • Loading branch information
anshumanmohan authored Aug 15, 2023
1 parent 0bd028c commit 4a319fc
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 45 deletions.
16 changes: 16 additions & 0 deletions calyx-py/calyx/builder_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@ def insert_lt(comp: cb.ComponentBuilder, left, right, cellname, width):
return insert_comb_group(comp, left, right, lt_cell, f"{cellname}_group")


def insert_le(comp: cb.ComponentBuilder, left, right, cellname, width):
"""Inserts wiring into component {comp} to check if {left} <= {right}.
<cellname> = std_le(<width>);
...
comb group <cellname>_group {
<cellname>.left = <left>;
<cellname>.right = <right>;
}
Returns handles to the cell and the combinational group.
"""
le_cell = comp.le(cellname, width)
return insert_comb_group(comp, left, right, le_cell, f"{cellname}_group")


def insert_gt(comp: cb.ComponentBuilder, left, right, cellname, width):
"""Inserts wiring into component {comp} to check if {left} > {right}.
Expand Down
51 changes: 17 additions & 34 deletions calyx-py/calyx/queue_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ def insert_main(prog, queue):
incr_i = util.insert_incr(main, i, "incr_i") # i++
incr_j = util.insert_incr(main, j, "incr_j") # j++
err_eq_0 = util.insert_eq(main, err.out, 0, "err_eq_0", 1) # is `err` flag down?
cmd_eq_0 = util.insert_eq(main, cmd.out, 0, "cmd_eq_0", 32) # cmd == 0
cmd_neq_0 = util.insert_neq(
main, cmd.out, cb.const(32, 0), "cmd_neq_0", 32
) # cmd != 0
cmd_le_1 = util.insert_le(main, cmd.out, 1, "cmd_le_1", 32) # cmd <= 1

read_cmd = util.mem_read_seq_d1(main, commands, i.out, "read_cmd_phase1")
write_cmd_to_reg = util.mem_write_seq_d1_to_reg(
Expand All @@ -102,38 +99,24 @@ def insert_main(prog, queue):
[
read_cmd, # Read `commands[i]`
write_cmd_to_reg, # Write it to `cmd`
cb.par( # Now, in parallel, act based on the value of `cmd`
cb.if_(
# Is this a pop?
cmd_eq_0[0].out,
cmd_eq_0[1],
[ # A pop
cb.invoke( # First we call pop
queue,
in_cmd=cmd.out,
ref_ans=ans,
ref_err=err,
),
# AM: my goal is that,
# if err flag comes back raised,
# we do not perform this write or this incr_j
write_ans,
incr_j,
],
),
cb.if_( # Is this a push?
cmd_neq_0[0].out,
cmd_neq_0[1],
cb.invoke( # A push
queue,
in_cmd=cmd.out,
ref_ans=ans,
ref_err=err,
),
),
cb.invoke( # Call the queue with `cmd`
queue,
in_cmd=cmd.out,
ref_ans=ans,
ref_err=err,
),
cb.if_( # If it was a pop or a peek, write ans to the answer list
cmd_le_1[0].out,
cmd_le_1[1],
[ # AM: I'd like to have an additional check hereL
# if err flag comes back raised,
# we do not perform this write_ans or this incr_j
write_ans,
incr_j,
],
),
incr_i, # Increment the command index
cb.invoke( # If i = MAX_CMDS, raise error flag
cb.invoke( # If i = 15, raise error flag
raise_err_if_i_eq_max_cmds, in_i=i.out, ref_err=err
), # AM: hella hacky
],
Expand Down
2 changes: 1 addition & 1 deletion calyx-py/test/correctness/fifo.data
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"commands": {
"data": [
100,
0,
1,
101,
102,
0,
Expand Down
4 changes: 2 additions & 2 deletions calyx-py/test/correctness/fifo.expect
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
{
"ans_mem": [
100,
100,
101,
102,
103,
104,
105,
0,
0,
0,
0
],
"commands": [
100,
0,
1,
101,
102,
0,
Expand Down
2 changes: 1 addition & 1 deletion calyx-py/test/correctness/pifo.data
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
104,
201,
202,
1,
0,
0,
0,
0,
105,
106,
0
],
"format": {
Expand Down
4 changes: 2 additions & 2 deletions calyx-py/test/correctness/pifo.expect
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
101,
102,
201,
201,
103,
202,
104,
105,
0,
0,
0
],
"commands": [
Expand All @@ -20,12 +20,12 @@
104,
201,
202,
1,
0,
0,
0,
0,
105,
106,
0
]
}
89 changes: 84 additions & 5 deletions calyx-py/test/correctness/pifo.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def insert_pifo(prog, name):

pifo: cb.ComponentBuilder = prog.component(name)
cmd = pifo.input("cmd", 32)
# If this is 0, we pop. Otherwise, we push the value.
# If this is 0, we pop. If it is 1, we peek. Otherwise, we push the value.

# Create the two FIFOs and ready them for invocation.
fifo_0 = pifo.cell("myfifo_0", fifo.insert_fifo(prog, "fifo_0"))
Expand Down Expand Up @@ -108,7 +108,8 @@ def insert_pifo(prog, name):
len_eq_0 = util.insert_eq(pifo, len.out, 0, "len_eq_0", 32)
len_eq_10 = util.insert_eq(pifo, len.out, 10, "len_eq_10", 32)
cmd_eq_0 = util.insert_eq(pifo, cmd, 0, "cmd_eq_0", 32)
cmd_neq_0 = util.insert_neq(pifo, cmd, cb.const(32, 0), "cmd_neq_0", 32)
cmd_eq_1 = util.insert_eq(pifo, cmd, 1, "cmd_eq_1", 32)
cmd_gt_1 = util.insert_gt(pifo, cmd, 1, "cmd_gt_1", 32)
err_eq_0 = util.insert_eq(pifo, err.out, 0, "err_eq_0", 1)
err_neq_0 = util.insert_neq(pifo, err.out, cb.const(1, 0), "err_neq_0", 1)

Expand All @@ -123,7 +124,7 @@ def insert_pifo(prog, name):
# The main logic.
pifo.control += [
cb.par(
# Was it a pop or a push? We can do both cases in parallel.
# Was it a pop, peek, or a push? We can do all cases in parallel.
cb.if_(
# Did the user call pop?
cmd_eq_0[0].out,
Expand Down Expand Up @@ -202,10 +203,88 @@ def insert_pifo(prog, name):
],
),
),
cb.if_(
# Did the user call peek?
cmd_eq_1[0].out,
cmd_eq_1[1],
cb.if_(
# Yes, the user called peek. But is the queue empty?
len_eq_0[0].out,
len_eq_0[1],
[raise_err, zero_out_ans], # The queue is empty: underflow.
[ # The queue is not empty. Proceed.
# We must check if `hot` is 0 or 1.
lower_err,
cb.par( # We'll check both cases in parallel.
cb.if_(
# Check if `hot` is 0.
hot_eq_0[0].out,
hot_eq_0[1],
[ # `hot` is 0. We'll invoke `peek` on `fifo_0`.
cb.invoke( # First we call peek
fifo_0,
in_cmd=cb.const(32, 1),
ref_ans=ans, # Its answer is our answer.
ref_err=err,
),
# Our next step depends on whether `fifo_0`
# raised the error flag.
cb.if_(
err_neq_0[0].out,
err_neq_0[1],
[ # `fifo_0` raised an error.
# We'll try to peek from `fifo_1`.
# We'll pass it a lowered `err`.
lower_err,
cb.invoke(
fifo_1,
in_cmd=cb.const(32, 1),
ref_ans=ans,
# Its answer is our answer.
ref_err=err,
# Its error is our error,
# whether it raised one or not.
),
],
),
# Peeking does not affect `hot`.
# Peeking does not affect the length.
],
),
# If `hot` is 1, we proceed symmetrically.
cb.if_(
hot_eq_1[0].out,
hot_eq_1[1],
[
cb.invoke(
fifo_1,
in_cmd=cb.const(32, 1),
ref_ans=ans,
ref_err=err,
),
cb.if_(
err_neq_0[0].out,
err_neq_0[1],
[
lower_err,
cb.invoke(
fifo_0,
in_cmd=cb.const(32, 1),
ref_ans=ans,
ref_err=err,
),
],
),
],
),
),
],
),
),
cb.if_(
# Did the user call push?
cmd_neq_0[0].out,
cmd_neq_0[1],
cmd_gt_1[0].out,
cmd_gt_1[1],
cb.if_(
# Yes, the user called push. But is the queue full?
len_eq_10[0].out,
Expand Down

0 comments on commit 4a319fc

Please sign in to comment.