Skip to content

Commit

Permalink
Axi wrapper fixes (#1953)
Browse files Browse the repository at this point in the history
* fixed axi wrapper after default assignment changes

* improved bash script

* remove generated-axi-with-vec-add, the bash script will make this for you now

* reduce axi generator conditions

* make runt tests pass for calyx axi wrapper
  • Loading branch information
nathanielnrn committed Mar 6, 2024
1 parent ec266a0 commit ce57c8e
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 513 deletions.
38 changes: 20 additions & 18 deletions yxi/axi-calyx/axi-generator.expect
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ component m_read_channel(ARESETn: 1, RVALID: 1, RLAST: 1, RDATA: 32, RRESP: 2) -
}
wires {
RREADY = rready.out;
mem_ref.content_en = 1'd0;
group block_transfer {
rready.in = !(rready.out & RVALID) ? 1'd1;
rready.in = (rready.out & RVALID) ? 1'd0;
Expand All @@ -160,7 +159,8 @@ component m_read_channel(ARESETn: 1, RVALID: 1, RLAST: 1, RDATA: 32, RRESP: 2) -
mem_ref.addr0 = curr_addr_internal_mem.out;
mem_ref.write_data = read_data_reg.out;
mem_ref.write_en = 1'd1;
service_read_transfer[done] = mem_ref.write_done;
mem_ref.content_en = 1'd1;
service_read_transfer[done] = mem_ref.done;
}
group curr_addr_internal_mem_incr_group {
curr_addr_internal_mem_incr.left = curr_addr_internal_mem.out;
Expand Down Expand Up @@ -201,29 +201,31 @@ component m_write_channel(ARESETn: 1, WREADY: 1) -> (WVALID: 1, WLAST: 1, WDATA:
w_handshake_occurred = std_reg(1);
ref curr_addr_internal_mem = std_reg(3);
ref curr_addr_axi = std_reg(64);
curr_trsnfr_count = std_reg(8);
curr_transfer_count = std_reg(8);
ref max_transfers = std_reg(8);
n_finished_last_trnsfr = std_reg(1);
n_finished_last_transfer = std_reg(1);
bt_reg = std_reg(1);
curr_addr_internal_mem_incr = std_add(3);
curr_addr_axi_incr = std_add(64);
curr_trsnfr_count_incr = std_add(8);
curr_transfer_count_incr = std_add(8);
}
wires {
WVALID = wvalid.out;
mem_ref.write_en = 1'd0;
group service_write_transfer {
wvalid.in = (!(wvalid.out & WREADY) & !w_handshake_occurred.out) ? 1'd1;
wvalid.in = ((wvalid.out & WREADY) | w_handshake_occurred.out) ? 1'd0;
wvalid.write_en = 1'd1;
w_handshake_occurred.in = (wvalid.out & WREADY) ? 1'd1;
w_handshake_occurred.in = !(wvalid.out & WREADY) ? 1'd0;
w_handshake_occurred.write_en = !w_handshake_occurred.out ? 1'd1;
mem_ref.addr0 = curr_addr_internal_mem.out;
mem_ref.content_en = 1'd1;
WDATA = mem_ref.read_data;
WLAST = (max_transfers.out == curr_trsnfr_count.out) ? 1'd1;
WLAST = (max_transfers.out != curr_trsnfr_count.out) ? 1'd0;
n_finished_last_trnsfr.in = ((max_transfers.out == curr_trsnfr_count.out) & (wvalid.out & WREADY)) ? 1'd0;
n_finished_last_trnsfr.write_en = ((max_transfers.out == curr_trsnfr_count.out) & (wvalid.out & WREADY)) ? 1'd1;
WLAST = (max_transfers.out == curr_transfer_count.out) ? 1'd1;
WLAST = (max_transfers.out != curr_transfer_count.out) ? 1'd0;
n_finished_last_transfer.in = ((max_transfers.out == curr_transfer_count.out) & (wvalid.out & WREADY)) ? 1'd0;
n_finished_last_transfer.write_en = ((max_transfers.out == curr_transfer_count.out) & (wvalid.out & WREADY)) ? 1'd1;
bt_reg.in = (wvalid.out & WREADY) ? 1'd1;
bt_reg.in = !(wvalid.out & WREADY) ? 1'd0;
bt_reg.write_en = 1'd1;
Expand All @@ -243,25 +245,25 @@ component m_write_channel(ARESETn: 1, WREADY: 1) -> (WVALID: 1, WLAST: 1, WDATA:
curr_addr_axi.in = curr_addr_axi_incr.out;
curr_addr_axi_incr_group[done] = curr_addr_axi.done;
}
group curr_trsnfr_count_incr_group {
curr_trsnfr_count_incr.left = curr_trsnfr_count.out;
curr_trsnfr_count_incr.right = 8'd1;
curr_trsnfr_count.write_en = 1'd1;
curr_trsnfr_count.in = curr_trsnfr_count_incr.out;
curr_trsnfr_count_incr_group[done] = curr_trsnfr_count.done;
group curr_transfer_count_incr_group {
curr_transfer_count_incr.left = curr_transfer_count.out;
curr_transfer_count_incr.right = 8'd1;
curr_transfer_count.write_en = 1'd1;
curr_transfer_count.in = curr_transfer_count_incr.out;
curr_transfer_count_incr_group[done] = curr_transfer_count.done;
}
}
control {
seq {
invoke curr_addr_internal_mem(in=3'd0)();
invoke n_finished_last_trnsfr(in=1'd1)();
while n_finished_last_trnsfr.out {
invoke n_finished_last_transfer(in=1'd1)();
while n_finished_last_transfer.out {
seq {
invoke bt_reg(in=1'd0)();
service_write_transfer;
par {
curr_addr_internal_mem_incr_group;
curr_trsnfr_count_incr_group;
curr_transfer_count_incr_group;
curr_addr_axi_incr_group;
invoke w_handshake_occurred(in=1'd0)();
}
Expand Down
40 changes: 21 additions & 19 deletions yxi/axi-calyx/axi-generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,6 @@ def add_read_channel(prog, mem):
# Groups
with read_channel.continuous:
read_channel.this()["RREADY"] = rready.out
# Tie this low as we are only ever writing to seq_mem
mem_ref.content_en = 0

# Wait for handshake. Ensure that when this is done we are ready to write
# (i.e., read_data_reg.write_en = is_rdy.out)
Expand Down Expand Up @@ -268,7 +266,8 @@ def add_read_channel(prog, mem):
mem_ref.addr0 = curr_addr_internal_mem.out
mem_ref.write_data = read_data_reg.out
mem_ref.write_en = 1
service_read_transfer.done = mem_ref.write_done
mem_ref.content_en = 1
service_read_transfer.done = mem_ref.done

# creates group that increments curr_addr_internal_mem by 1. Creates adder and wires up correctly
curr_addr_internal_mem_incr = read_channel.incr(curr_addr_internal_mem, 1)
Expand Down Expand Up @@ -328,19 +327,21 @@ def add_write_channel(prog, mem):
# host indexing, must be 64 bits
curr_addr_axi = write_channel.reg("curr_addr_axi", 64, is_ref=True)

curr_trsnfr_count = write_channel.reg("curr_trsnfr_count", 8)
curr_transfer_count = write_channel.reg("curr_transfer_count", 8)
# Number of transfers we want to do in current txn
max_transfers = write_channel.reg("max_transfers", 8, is_ref=True)

# Register because w last is high with last transfer. Before this
# We were terminating immediately with last transfer and not servicing it.
n_finished_last_trnsfr = write_channel.reg("n_finished_last_trnsfr", 1)
n_finished_last_transfer = write_channel.reg("n_finished_last_transfer", 1)

bt_reg = write_channel.reg("bt_reg", 1)

# Groups
with write_channel.continuous:
write_channel.this()["WVALID"] = wvalid.out
#Needed due to default assignment bug #1930
mem_ref.write_en = 0

with write_channel.group("service_write_transfer") as service_write_transfer:
WREADY = write_channel.this()["WREADY"]
Expand All @@ -354,22 +355,23 @@ def add_write_channel(prog, mem):
# This is just wavlid.in_ guard from above
# TODO: confirm this is correct?
w_handshake_occurred.in_ = (wvalid.out & WREADY) @ 1
w_handshake_occurred.in_ = ~(wvalid.out & WREADY) @ 0
w_handshake_occurred.write_en = (~w_handshake_occurred.out) @ 1

# Set data output based on intermal memory output
mem_ref.addr0 = curr_addr_internal_mem.out
mem_ref.content_en = 1
write_channel.this()["WDATA"] = mem_ref.read_data

write_channel.this()["WLAST"] = (max_transfers.out == curr_trsnfr_count.out) @ 1
write_channel.this()["WLAST"] = (max_transfers.out != curr_trsnfr_count.out) @ 0
write_channel.this()["WLAST"] = (max_transfers.out == curr_transfer_count.out) @ 1
write_channel.this()["WLAST"] = (max_transfers.out != curr_transfer_count.out) @ 0

# set high when WLAST is high and a handshake occurs
n_finished_last_trnsfr.in_ = (
(max_transfers.out == curr_trsnfr_count.out) & (wvalid.out & WREADY)
n_finished_last_transfer.in_ = (
(max_transfers.out == curr_transfer_count.out) & (wvalid.out & WREADY)
) @ 0
n_finished_last_trnsfr.write_en = (
(max_transfers.out == curr_trsnfr_count.out) & (wvalid.out & WREADY)
n_finished_last_transfer.write_en = (
(max_transfers.out == curr_transfer_count.out) & (wvalid.out & WREADY)
) @ 1

# done after handshake
Expand All @@ -385,28 +387,28 @@ def add_write_channel(prog, mem):
# splicing for this.
# See https://cucapra.slack.com/archives/C05TRBNKY93/p1705587169286609?thread_ts=1705524171.974079&cid=C05TRBNKY93 # noqa: E501
curr_addr_axi_incr = write_channel.incr(curr_addr_axi, ceil(mem["width"] / 8))
curr_trsnfr_count_incr = write_channel.incr(curr_trsnfr_count, 1)
curr_transfer_count_incr = write_channel.incr(curr_transfer_count, 1)

# Control
init_curr_addr_internal_mem = invoke(curr_addr_internal_mem, in_in=0)
init_n_finished_last_trnsfr = invoke(n_finished_last_trnsfr, in_in=1)
while_n_finished_last_trnsfr_body = [
init_n_finished_last_transfer = invoke(n_finished_last_transfer, in_in=1)
while_n_finished_last_transfer_body = [
invoke(bt_reg, in_in=0),
service_write_transfer,
par(
curr_addr_internal_mem_incr,
curr_trsnfr_count_incr,
curr_transfer_count_incr,
curr_addr_axi_incr,
invoke(w_handshake_occurred, in_in=0),
),
]
while_n_finished_last_trnsfr = while_(
n_finished_last_trnsfr.out, while_n_finished_last_trnsfr_body
while_n_finished_last_transfer = while_(
n_finished_last_transfer.out, while_n_finished_last_transfer_body
)
write_channel.control += [
init_curr_addr_internal_mem,
init_n_finished_last_trnsfr,
while_n_finished_last_trnsfr,
init_n_finished_last_transfer,
while_n_finished_last_transfer,
]


Expand Down
7 changes: 6 additions & 1 deletion yxi/axi-calyx/cocotb/sim.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

# Intended to convert from calyx to synthesizable verilog, enable waveform tracing and run tests defined in Makefile
#expects an outputs/ dir one level up from here
fud e ../generated-axi-with-vec-add.futil --from calyx --to synth-verilog -o ../outputs/generated-axi-with-vec-add.v \
cd ../ \
&& python3 axi-generator.py > generated-axi.futil \
&& cp generated-axi.futil generated-axi-with-vec-add.futil \
&& cat fixed-vec-add.futil >> generated-axi-with-vec-add.futil \
&& cd cocotb \
&& fud e ../generated-axi-with-vec-add.futil --from calyx --to synth-verilog -o ../outputs/generated-axi-with-vec-add.v \
&& ../vcdump.py ../outputs/generated-axi-with-vec-add.v \
&& make WAVES=1 \
&& mv out.vcd generated-axi-with-vec-add.fst
17 changes: 12 additions & 5 deletions yxi/axi-calyx/fixed-vec-add.futil
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ component main() -> () {
bit_slice = std_bit_slice(4,0,2,3);
}
wires {
A0.write_en = 1'b0;
B0.write_en = 1'b0;

bit_slice.in = i0.out;
comb group cond0 {
Expand All @@ -29,27 +31,32 @@ component main() -> () {
}
//modified upd0 and upd1 to use seq_mem correctly
group upd0<"static"=2> {
A_read0_0.write_en = A0.read_done;
A_read0_0.write_en = A0.done;
A0.addr0 = bit_slice.out;
A0.read_en = 1'b1;
A0.content_en = 1'b1;
A_read0_0.in = 1'd1 ? A0.read_data;
upd0[done] = A_read0_0.done ? 1'd1;
}
//see comment for upd0
group upd1<"static"=2> {
B_read0_0.write_en = B0.read_done;
B_read0_0.write_en = B0.done;
B0.addr0 = bit_slice.out;
B0.read_en = 1'b1;
B0.content_en = 1'b1;
B_read0_0.in = 1'd1 ? B0.read_data;
upd1[done] = B_read0_0.done ? 1'd1;
}
group upd2<"static"=1> {
Sum0.addr0 = bit_slice.out;
Sum0.content_en = 1'd1;
Sum0.write_en = 1'd1;
B0.content_en = 1'b1;
B0.addr0 = bit_slice.out;
A0.addr0 = bit_slice.out;
A0.content_en = 1'b1;
add0.left = B_read0_0.out;
add0.right = A_read0_0.out;
Sum0.write_data = 1'd1 ? add0.out;
upd2[done] = Sum0.write_done ? 1'd1;
upd2[done] = Sum0.done ? 1'd1;
}
group upd3<"static"=1> {
i0.write_en = 1'd1;
Expand Down
Loading

0 comments on commit ce57c8e

Please sign in to comment.